User File #11605836887834478

Upload All User Files

#11605836887834478 - SNES Soul Blazer script v1 (lsnes)

SB_RNG_Lair.lua
1140 downloads
Uploaded 12/27/2013 3:41 PM by FatRatKnight (see all 245)
Here's my lsnes script for Soul Blazer. It's currently set up for (U), though I have a commented line packed somewhere in there that would make it compatible with (J) instead. The lair listing code needs it, as it's the address for the pointer to the first object.
Top-left corner: Position of player
Right side: RNG, direction a certain enemy will go next
More right: List of lair information: Position, count, timer
Other odds and ends: Count of detected lairs, count of objects, RNG frame timer
This script gets false positives for lairs at times. I have tried to search through the object data some more to tighten the detection, but without success. The attempts are minimal, however, as there are no observed false negatives, and I usually can weed out the false positives while TASing.
Nothing real fancy, though. Haven't even put in the boxes that I feature in the Snes9x script. It serves well enough, though.
local R1u= memory.readbyte
local R2u= memory.readword
local R4u= memory.readdword

--*****************************************************************************
local function Roll(rTbl)
--*****************************************************************************
    local c= 0
    for i= 14, 0, -1 do
        local v= rTbl[i]+rTbl[i+1]+c
        c= math.floor(v/0x100)
        rTbl[i]= v%0x100
    end
    rTbl[15]= (rTbl[15]+1)%0x100
end

local R= {}
local Rlist= {0} -- Have a default to display without an error.

--*****************************************************************************
local function s(v)
--*****************************************************************************
    return string.format("%3d",v)
end

local Thresholds= {
[0]= {L= 1, M= 4},
     {L= 3, M= 8},
     {L= 5, M=12},
     {L= 7, M=16},
     {L= 9, M=20},
     {L=11, M=24},
     {L=51, M=100},
}
--*****************************************************************************
local function GetColor(v,zone)
--*****************************************************************************
    if zone > 7 then return 0x808080 end -- I'm confused.
    if v < Thresholds[zone].L then return 0x00FFFF end  -- Large. Awesome.
    if v < Thresholds[zone].M then return 0xFFFF00 end  -- Medium. Nice.
    return 0x808080 -- Small. Nuts.
end

local OldR= -1
--*****************************************************************************
local function UpdateRNG(count)
--*****************************************************************************
    local TestR= R4u(0x7E0302)
    if TestR == OldR then return end -- Assume we're good, don't process.
    OldR= TestR

    for i= 0,15 do R[i]= R1u(0x7E0302+i) end
    for i= 1, count do
        Roll(R)
        Rlist[i]= R[0]
    end
end

local DirTbl= {[0]="^","v",">","<"}
--*****************************************************************************
local function RNGHandler(x,top,count)
--*****************************************************************************
    UpdateRNG(count)
    for i= 1, count do
        local c= GetColor(Rlist[i]%100,R1u(0x7E03BA))
        gui.text(x   ,top + 15*(i-1), s(Rlist[i]), c)
        gui.text(x+24,top + 15*(i-1), DirTbl[Rlist[i]%4])
    end
end

--*****************************************************************************
local function LairList(x,top)
--*****************************************************************************
    local Panic= 0
    local Next= R2u(0x7E06A6) -- (U)
--    local Next= R2u(0x7E06A3) -- (J)
    local total= 0
    while Next ~= 0 do
        Panic= Panic+1
        if Panic > 255 then gui.text(x,top+total*15,"PANIC",0xFF2000); return end

        local Addr= 0x7E0000 + Next

--ID as lair?
        local count= R1u(Addr+0x2E)
        local Assoc= R2u(Addr+0x32)
        if (count ~= 0) and (Assoc == 0) then
            local color= 0x00FF00
            if R2u(Addr+0x16) >= 0x8000 then color= 0x7F7F7F end

            gui.text(x,top+total*15,string.format("%3X %3X %2d %3d",
                R2u(Addr),R2u(Addr+2),count,R2u(Addr+0x14)
                ),color
            )
            total= total+1
        end

        Next= R2u(Addr + 0x3E)
    end
    gui.text(x   ,top+total*15,string.format("%3d",total),0x00FFFF)
    gui.text(x+40,top+total*15,string.format("%3d",Panic),0xFFFF00)
end

local RNG_count,RNG_prev= 0, 0
--*****************************************************************************
local function BasicHUD(x,top,height)
--*****************************************************************************
    gui.text(0, 0,string.format("%4X",R2u(0x7E0800)),0xFFFF80,0x40000000)
    gui.text(0,15,string.format("%4X",R2u(0x7E0802)),0x80FFFF,0x40000000)

    local bottom= top+height

    gui.text(x,bottom-16,string.format("%4X",R2u(0x7E0312)))

--[[
    local RNG= R1u(0x7E0311)
    local RNG_diff= (RNG - RNG_prev) % 256
    RNG_count= RNG_count + RNG_diff
    RNG_prev= RNG
    gui.text(x,bottom-32,string.format("%5d:%2X",RNG_count,RNG_prev))
]]--

end


local OldPaint= on_paint or function() end

--*****************************************************************************
function on_paint(non_synth)
--*****************************************************************************
    OldPaint(non_synth) -- Decent way to chain scripts together.

    local x,height= gui.resolution()
    x= x+gui.delta_right_gap(152)  -- Place ourselves to the right of that gunk

    local y= gui.delta_top_gap(0) -- Incorperate spare space provided by the
    height= height+y+gui.delta_bottom_gap(0) -- chained scripts we have.
    local count= math.floor(height/15)

    RNGHandler(x,-y,count)
    LairList(x+40,-y)
    BasicHUD(x+40,-y,height)
end


--[[
Address 0x7E0800, object size=64
+0x00,2s X-pos
+0x02,2s Y-pos
+0x04,2s X-spd
+0x06,2s Y-spd
+0x08,2s Hitbox Left (subtract from X-pos)
+0x0A,2s Hitbox Top  (subtract from Y-pos)
+0x0C,2s Hitbox Right   (add to X-pos)
+0x0E,2s Hitbox Bottom  (add to Y-pos)
+0x10,
+0x12,
+0x14,2u Useful timer (such as lair spawn rate)
+0x16,2x Flags (0x8000 indicates offscreen)
+0x18,2x Some kind of ID number?
+0x1A,
+0x1C,
+0x1E,
+0x20,
+0x22,
+0x24,
+0x26,2s Invincibility timer
+0x28,
+0x2A,
+0x2C,
+0x2E,2x Looks suspicious... Count in lair?
+0x30,
+0x32,2x Link to associated lair
+0x34,
+0x36,
+0x38,
+0x3A,
+0x3C,2x Link (prev)
+0x3E,2x Link (next)
]]--