LUA script for sprite debugging (#35)
Useful script adapted from one created by tokumaru (with permission)
This commit is contained in:
parent
327bb202a2
commit
bc41bc80ee
|
@ -1,45 +1,65 @@
|
|||
-- Simple sprite visualizer
|
||||
-- Draws a box around all sprites on screen.
|
||||
-- rainwarrior 8/23/2016
|
||||
|
||||
sprite_color = "#FF00FF" -- change to customize color
|
||||
|
||||
sprite_height_last = 8
|
||||
sprite_height = 8
|
||||
|
||||
function oam_dma(a,s,v)
|
||||
local oam = v * 256
|
||||
for i=1,64 do
|
||||
local is = (i-1) * 4
|
||||
local x0 = memory.readbyte(oam + is + 3)
|
||||
local x1 = x0 + 7
|
||||
local y0 = memory.readbyte(oam + is + 0) + 1
|
||||
local y1 = y0 + (sprite_height_last - 1)
|
||||
gui.box(x0,y0,x1,y1,"",sprite_color)
|
||||
end
|
||||
end
|
||||
|
||||
function ppu_ctrl(a,s,v)
|
||||
if AND(v,0x20) == 0 then
|
||||
sprite_height = 8
|
||||
else
|
||||
sprite_height = 16
|
||||
end
|
||||
end
|
||||
|
||||
function frame_end()
|
||||
-- information about sprite height will be behind by 1 frame
|
||||
-- (or potentially wrong if changed before the end of the frame)
|
||||
-- in most games this doesn't change from frame to frame, though
|
||||
sprite_height_last = sprite_height
|
||||
end
|
||||
|
||||
-- main
|
||||
|
||||
memory.registerwrite(0x4014,1,oam_dma)
|
||||
memory.registerwrite(0x2000,1,ppu_ctrl)
|
||||
emu.registerafter(frame_end)
|
||||
|
||||
while (true) do
|
||||
emu.frameadvance()
|
||||
end
|
||||
-- Sprite visualizer
|
||||
--
|
||||
-- Draws a box around all sprites on screen,
|
||||
-- hover with the mouse to inspect data.
|
||||
--
|
||||
-- Original by tokumaru 2016-10-08:
|
||||
-- https://forums.nesdev.com/viewtopic.php?p=181008#p181008
|
||||
|
||||
numSpriteHeight = 8
|
||||
strFillColor = "#ffffff3f"
|
||||
strOutlineColor = "#ff0000bf"
|
||||
strHighlightColor = "#ffffffbf"
|
||||
|
||||
function readSpriteAttributes(a,s,v)
|
||||
local numAddress = v * 256
|
||||
tabSpriteAttributes = {}
|
||||
for numIndex = 0, 255 do
|
||||
table.insert(tabSpriteAttributes, memory.readbyte(numAddress + numIndex))
|
||||
end
|
||||
end
|
||||
|
||||
function setSpriteHeight(a,s,v)
|
||||
if AND(a, 7) == 0 then
|
||||
numSpriteHeight = AND((v / 4), 8) + 8
|
||||
end
|
||||
end
|
||||
|
||||
function drawBoxes()
|
||||
local tabInput, numSpriteX, numSpriteY, numDetailsBase, numTextY = input.read()
|
||||
if tabSpriteAttributes ~= nill then
|
||||
for numBase = 252, 0, -4 do
|
||||
numSpriteX0 = tabSpriteAttributes[numBase + 4]
|
||||
numSpriteY0 = tabSpriteAttributes[numBase + 1] + 1
|
||||
numSpriteX1 = numSpriteX0 + 7
|
||||
numSpriteY1 = numSpriteY0 + numSpriteHeight - 1
|
||||
if (tabInput.xmouse >= numSpriteX0) and (tabInput.xmouse <= numSpriteX1) and (tabInput.ymouse >= numSpriteY0) and (tabInput.ymouse <= numSpriteY1) then
|
||||
gui.box(numSpriteX0, numSpriteY0, numSpriteX1, numSpriteY1, strHighlightColor, strOutlineColor)
|
||||
numDetailsBase = numBase
|
||||
else
|
||||
gui.box(numSpriteX0, numSpriteY0, numSpriteX1, numSpriteY1, strFillColor, strOutlineColor)
|
||||
end
|
||||
end
|
||||
end
|
||||
if numDetailsBase ~= nil then
|
||||
numTextY = (1 - math.floor(tabInput.ymouse / 120)) * 127 + 16
|
||||
gui.text(16, numTextY, string.format("OAM Slot: %d", numDetailsBase / 4)); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("OAM Offset: $%02X", numDetailsBase)); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Sprite X: $%02X", tabSpriteAttributes[numDetailsBase + 4])); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Sprite Y: $%02X", tabSpriteAttributes[numDetailsBase + 1])); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Tile ID: $%02X", tabSpriteAttributes[numDetailsBase + 2])); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Palette: %d", AND(tabSpriteAttributes[numDetailsBase + 3], 0x03))); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Behind Background: %d", AND(tabSpriteAttributes[numDetailsBase + 3], 0x20) / 0x20)); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Flip X: %d", AND(tabSpriteAttributes[numDetailsBase + 3], 0x40) / 0x40)); numTextY = numTextY + 9
|
||||
gui.text(16, numTextY, string.format("Flip Y: %d", AND(tabSpriteAttributes[numDetailsBase + 3], 0x80) / 0x80)); numTextY = numTextY + 9
|
||||
end
|
||||
gui.box(tabInput.xmouse - 2, tabInput.ymouse - 2, tabInput.xmouse + 2, tabInput.ymouse + 2, strHighlightColor, strOutlineColor)
|
||||
end
|
||||
|
||||
memory.registerwrite(0x4014, 0x0001, readSpriteAttributes)
|
||||
memory.registerwrite(0x2000, 0x2000, setSpriteHeight)
|
||||
gui.register(drawBoxes)
|
||||
|
||||
while (true) do
|
||||
emu.frameadvance()
|
||||
end
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
-- Simple sprite visualizer
|
||||
-- Draws a box around all sprites on screen.
|
||||
-- rainwarrior 8/23/2016
|
||||
|
||||
sprite_color = "#FF00FF" -- change to customize color
|
||||
|
||||
sprite_height_last = 8
|
||||
sprite_height = 8
|
||||
|
||||
function oam_dma(a,s,v)
|
||||
local oam = v * 256
|
||||
for i=1,64 do
|
||||
local is = (i-1) * 4
|
||||
local x0 = memory.readbyte(oam + is + 3)
|
||||
local x1 = x0 + 7
|
||||
local y0 = memory.readbyte(oam + is + 0) + 1
|
||||
local y1 = y0 + (sprite_height_last - 1)
|
||||
gui.box(x0,y0,x1,y1,"",sprite_color)
|
||||
end
|
||||
end
|
||||
|
||||
function ppu_ctrl(a,s,v)
|
||||
if AND(v,0x20) == 0 then
|
||||
sprite_height = 8
|
||||
else
|
||||
sprite_height = 16
|
||||
end
|
||||
end
|
||||
|
||||
function frame_end()
|
||||
-- information about sprite height will be behind by 1 frame
|
||||
-- (or potentially wrong if changed before the end of the frame)
|
||||
-- in most games this doesn't change from frame to frame, though
|
||||
sprite_height_last = sprite_height
|
||||
end
|
||||
|
||||
-- main
|
||||
|
||||
memory.registerwrite(0x4014,1,oam_dma)
|
||||
memory.registerwrite(0x2000,1,ppu_ctrl)
|
||||
emu.registerafter(frame_end)
|
||||
|
||||
while (true) do
|
||||
emu.frameadvance()
|
||||
end
|
|
@ -74,6 +74,7 @@
|
|||
<li>Mutlitrack2.lua - Tracks future input that FCEUX promptly loses on state-load, for <a class="rvts18" href="ToolAssistedSpeedruns.html">TAS</a></li>
|
||||
<li>Subtitler.lua - For easier use of FCEUX's built-in subtitles for <a class="rvts18" href="fm2.html">.fm2</a> files</li>
|
||||
<li>Rewinder.lua - A way to rewind backwards by pressing a button</li>
|
||||
<li>Sprites.lua - Sprite debugging highlights all sprites on screen, with mouse hover to inspect.</li>
|
||||
</ul>
|
||||
<p><br/></p>
|
||||
<p><br/></p>
|
||||
|
|
Loading…
Reference in New Issue