--*****************************************************************************
local Draw= {}
--*****************************************************************************
--Coordinates is the top-left pixel of the 3x5 digit.
--Used for drawing compact, colored numbers.
local Px,Li= gui.pixel, gui.line
Draw[0]= function(x,y,c) -- ###
Li(x ,y ,x ,y+4,c)-- # #
Li(x+2,y ,x+2,y+4,c)-- # #
Px(x+1,y ,c) -- # #
Px(x+1,y+4,c) -- ###
end
Draw[1]= function(x,y,c) -- #
Li(x ,y+4,x+2,y+4,c)-- ##
Li(x+1,y ,x+1,y+3,c)-- #
Px(x ,y+1,c) -- #
end -- ###
Draw[2]= function(x,y,c) -- ###
Li(x ,y ,x+2,y ,c)-- #
Li(x ,y+3,x+2,y+1,c)-- ###
Li(x ,y+4,x+2,y+4,c)-- #
Px(x ,y+2,c) -- ###
Px(x+2,y+2,c)
end
Draw[3]= function(x,y,c) -- ###
Li(x ,y ,x+1,y ,c)-- #
Li(x ,y+2,x+1,y+2,c)-- ###
Li(x ,y+4,x+1,y+4,c)-- #
Li(x+2,y ,x+2,y+4,c)-- ###
end
Draw[4]= function(x,y,c) -- # #
Li(x ,y ,x ,y+2,c)-- # #
Li(x+2,y ,x+2,y+4,c)-- ###
Px(x+1,y+2,c) -- #
end -- #
Draw[5]= function(x,y,c) -- ###
Li(x ,y ,x+2,y ,c)-- #
Li(x ,y+1,x+2,y+3,c)-- ###
Li(x ,y+4,x+2,y+4,c)-- #
Px(x ,y+2,c) -- ###
Px(x+2,y+2,c)
end
Draw[6]= function(x,y,c) -- ###
Li(x ,y ,x+2,y ,c)-- #
Li(x ,y+1,x ,y+4,c)-- ###
Li(x+2,y+2,x+2,y+4,c)-- # #
Px(x+1,y+2,c) -- ###
Px(x+1,y+4,c)
end
-- ###
Draw[7]= function(x,y,c) -- #
Li(x ,y ,x+1,y ,c)-- ##
Li(x+2,y ,x+1,y+4,c)-- #
end -- #
Draw[8]= function(x,y,c) -- ###
Li(x ,y ,x ,y+4,c)-- # #
Li(x+2,y ,x+2,y+4,c)-- ###
Px(x+1,y ,c) -- # #
Px(x+1,y+2,c) -- ###
Px(x+1,y+4,c)
end
Draw[9]= function(x,y,c) -- ###
Li(x ,y ,x ,y+2,c)-- # #
Li(x+2,y ,x+2,y+3,c)-- ###
Li(x ,y+4,x+2,y+4,c)-- #
Px(x+1,y ,c) -- ###
Px(x+1,y+2,c)
end
Draw[10]=function(x,y,c) -- #
Li(x ,y+1,x ,y+4,c)-- # #
Li(x+2,y+1,x+2,y+4,c)-- # #
Px(x+1,y ,c) -- ###
Px(x+1,y+3,c) -- # #
end
Draw[11]=function(x,y,c) -- ##
Li(x ,y ,x ,y+4,c)-- # #
Li(x+1,y ,x+2,y+1,c)-- ##
Li(x+1,y+4,x+2,y+3,c)-- # #
Px(x+1,y+2,c) -- ##
end
Draw[12]=function(x,y,c) -- #
Li(x ,y+1,x ,y+3,c)-- # #
Li(x+1,y ,x+2,y+1,c)-- #
Li(x+1,y+4,x+2,y+3,c)-- # #
end -- #
Draw[13]=function(x,y,c) -- ##
Li(x ,y ,x ,y+4,c)-- # #
Li(x+2,y+1,x+2,y+3,c)-- # #
Px(x+1,y ,c) -- # #
Px(x+1,y+4,c) -- ##
end
Draw[14]=function(x,y,c) -- ###
Li(x ,y ,x ,y+4,c)-- #
Li(x+1,y ,x+2,y ,c)-- ##
Li(x+1,y+4,x+2,y+4,c)-- #
Px(x+1,y+2,c) -- ###
end
Draw[15]=function(x,y,c) -- ###
Li(x ,y ,x ,y+4,c)-- #
Li(x+1,y ,x+2,y ,c)-- ##
Px(x+1,y+2,c) -- #
end -- #
--*****************************************************************************
local function __DN_AnyBase(right, y, Number, c, bkgnd, div)
--*****************************************************************************
-- Works with any base from 2 to 16. Paints the input number.
-- Returns the x position where it would paint another digit.
-- It only works with integers. Rounds fractions toward zero.
if div < 2 then return end -- Prevents the function from never returning.
local Digit= {}
local Negative= false
if Number < 0 then
Number= -Number
Negative= true
end
Number= math.floor(Number)
c= c or "white"
bkgnd= bkgnd or "clear"
local i= 0
if Number < 1 then
Digit[1]= 0
i= 1
end
while (Number >= 1) do
i= i+1
Digit[i]= Number % div
Number= math.floor(Number/div)
end
if Negative then i= i+1 end
local x= right - i*4
gui.box(x+1, y-1, right+1, y+5,bkgnd,bkgnd)
i= 1
while Draw[Digit[i]] do
Draw[Digit[i]](right-2,y,c)
right= right-4
i=i+1
end
if Negative then
gui.line(right, y+2,right-2,y+2,c)
right= right-4
end
return right
end
--*****************************************************************************
local function DrawNum(right, y, Number, c, bkgnd)
--*****************************************************************************
-- Paints the input number as right-aligned. Decimal version.
return __DN_AnyBase(right, y, Number, c, bkgnd, 10)
end
--*****************************************************************************
local function DrawNumx(right, y, Number, c, bkgnd)
--*****************************************************************************
-- Paints the input number as right-aligned. Hexadecimal version.
return __DN_AnyBase(right, y, Number, c, bkgnd, 16)
end
-------------------------------------------------------------------------------
local R1u= memory.readbyte
local keys, lastkeys= {},{}
local function UpdateKeys() lastkeys= keys; keys= input.get() end
local function Press(k) return keys[k] and not lastkeys[k] end
local IDchar= { -- Dang it, I need to figure out the best ASCII characters.
[0]=" ","/","&","[","X","%",nil,"A","B","C","a","b","c","+","+",nil,
"e","E","g","h","j","y","m","n","d","z","q","W","G","G","G","H",
"H","H","J","J","J","Y","Y","Y","M","M","M","N","N","N","$","L",
"5","f","F","p","P","K","i","r","R",nil,"S","I","w",nil,"*","?",
nil,"U","U","U","U","U","\\","v","t","1",nil,"0"
}
local IDname= { -- Here's all the objects I've identified.
[0x00]= "empty",
[0x01]= "panel_stun",
[0x02]= "wall?",
[0x03]= "block",
[0x04]= "wall_secret",
[0x05]= "wall_break",
--[0x06]
[0x07]= "wall_switch1" ,[0x08]= "wall_switch2" ,[0x09]= "wall_switch3",
[0x0A]= "panel_switch1",[0x0B]= "panel_switch2",[0x0C]= "panel_switch3",
[0x0D]= "door1" ,[0x0E]= "door2",
--[0x0F]
[0x10]= "exit1" ,[0x11]= "exit2",
[0x12]= "ghost",
[0x13]= "grunt",
[0x14]= "demon",
[0x15]= "lobber",
[0x16]= "sorc",
[0x17]= "gruntX",
[0x18]= "death",
[0x19]= "bubble",
[0x1A]= "sorcDX",
[0x1B]= "dragon_head",
[0x1C]= "gen_ghost1" ,[0x1D]= "gen_ghost2" ,[0x1E]= "gen_ghost3",
[0x1F]= "gen_grunt1" ,[0x20]= "gen_grunt2" ,[0x21]= "gen_grunt3",
[0x22]= "gen_demon1" ,[0x23]= "gen_demon2" ,[0x24]= "gen_demon3",
[0x25]= "gen_lobber1" , [0x27]= "gen_lobber3",
[0x28]= "gen_sorc1" ,[0x29]= "gen_sorc2" ,[0x2A]= "gen_sorc3",
[0x2D]= "gen_gruntX3",
[0x2E]= "treasure",
[0x2F]= "chest",
[0x30]= "treasure5",
[0x31]= "foodjug",
[0x32]= "foodbowl",
[0x33]= "potion1",
[0x34]= "potion2",
[0x35]= "key",
[0x36]= "invisibility",
[0x37]= "repulsive",
[0x38]= "reflecting",
--[0x39]
[0x3A]= "super_shot",
[0x3B]= "invincibility",
[0x3C]= "dragon_body",
--[0x3D]
[0x3E]= "transporter",
[0x3F]= "clue?",
--[0x40]
[0x41]= "upgrade_shot",
[0x42]= "upgrade_speed",
[0x43]= "upgrade_magic",
[0x44]= "upgrade_fight",
[0x45]= "upgrade_armor",
[0x46]= "potion_bad",
[0x47]= "fake_exit",
[0x48]= "dragon_tail",
[0x49]= "player",
--[0x4A]
[0x4B]= "orb"
}
local container= { -- To let me know which things can hold other things.
[0x04]=true, -- Secret wall
[0x2F]=true -- Chest
}
local bitchar= {[0]=" ","#"} -- For text mapping.
--*****************************************************************************
local function DetailMapperPrint()
--*****************************************************************************
--Prints an ASCII map to the Output Console.
--This version will fill in all those neat little objects, too.
--The tilde ~ is used if it doesn't find a defined character in IDchar
local map= {}
for i= 0, 31 do map[i]= {} end
--Fill map walls
for y= 0, 27 do
local a= 0x0300+4*y
local v= R1u(a)+R1u(a+1)*0x100+R1u(a+2)*0x10000+R1u(a+3)*0x1000000
for x= 0, 31 do
local b= bit.band(1,bit.rshift(v,x))
map[x][y]= bitchar[b]
end
end
--Insert objects
for i= 0, 0x7E do
local ID= R1u(0x0400+i)
if ID ~= 0 then
local x,y= math.floor(R1u(0x0480+i)/8), math.floor(R1u(0x0500+i)/8)
map[x][y]= IDchar[ID] or "~"
end
end
--Print map
print("+--------------------------------+")
for y= 0, 27 do
local str= "|"
for x= 0, 31 do
str= str .. map[x][y]
end
print(str.."|")
end
print("+--------------------------------+")
end
--*****************************************************************************
local function MapperPrint()
--*****************************************************************************
--Prints an ASCII map to the Output Console.
--This does just the solid walls and potential floor. Nothing else.
--Currently unused, though.
print("+--------------------------------+")
for y= 0, 31 do
local s= "|"
local a= 0x0300+4*y
local v= R1u(a)+R1u(a+1)*0x100+R1u(a+2)*0x10000+R1u(a+3)*0x1000000
for x= 0, 31 do
local b= bit.band(1,bit.rshift(v,x))
s= s .. bitchar[b]
end
print(s.."|")
end
print("+--------------------------------+")
end
--*****************************************************************************
local function ListStuff()
--*****************************************************************************
--Lists stuff to Output Console. Well, every single object on the map.
--ID number, X pos, Y pos, spare number, spare timer, my name for object.
--Alas, it's not smart enough to detect contained "exit2". Peek at spare number
for i= 0, 0x7F do
local ID= R1u(0x0400+i)
if ID ~= 0 then
local str= "%02X %02d %02d %02X %02X:%s"
if container[ID] then str= str .. " > " .. (IDname[R1u(0x0580+i)] or "???") end
print(string.format(str,
ID,
R1u(0x0480+i)/8, -- X loc
R1u(0x0500+i)/8, -- Y loc
R1u(0x0580+i), -- Spare num
R1u(0x0600+i), -- Timer?
IDname[ID] or "???"
))
end
end
print("===")
end
--*****************************************************************************
local function ExitScan()
--*****************************************************************************
--Scans the level for exits, contained or otherwise.
--After finding any, they are printed to Output Console.
print(R1u(0x00A3)+1)
for i= 0, 0x7F do
local ID= R1u(0x0400 + i)
local str= "open: "
if ID == 0x04 then
str= "secret: "
ID= R1u(0x0580 + i)
elseif ID == 0x2F then
str= "chest: "
ID= R1u(0x0580 + i)
end
--Notably, if it doesn't contain an exit, I won't display it anyway.
if ID == 0x10 then -- Normal exit
print(string.format("%s%sx%02d y%02d",str,"exit @ ",
R1u(0x0480+i)/8,R1u(0x0500+i)/8
))
elseif (ID == 0x11) or (ID >= 0x80) then -- Special exit
--By smart design, the container doesn't hold special exit.
--Instead, it holds the exit's destination. Then morphs into the special exit,
--I only need to read that same byte anyway, ha!
print(string.format("%s%s%03d)x%02d y%02d",str,"EXIT(",
R1u(0x0580+i)-127,R1u(0x0480+i)/8,R1u(0x0500+i)/8
))
end
end
print("-=-=-")
end
--*****************************************************************************
local function ScanKeys()
--*****************************************************************************
--Handles the input so I can use the print functions on demand.
UpdateKeys()
if Press("space") then DetailMapperPrint(); ListStuff() end
if Press("B") then ExitScan() end
end
local bitcolor= {[0]="grey","white"}
--*****************************************************************************
local function Mapper()
--*****************************************************************************
--Map display. Just the basic walls, however.
gui.box(0,8,33,41,"black","black")
for y= 0, 31 do
local Y= y+9
local a= 0x0300+4*y
local v= R1u(a)+R1u(a+1)*0x100+R1u(a+2)*0x10000+R1u(a+3)*0x1000000
for x= 0, 31 do
local b= bit.band(1,bit.rshift(v,x))
gui.pixel(x+1,Y,bitcolor[b])
end
end
end
--*****************************************************************************
local function BasicHUD()
--*****************************************************************************
--This will reveal ALL secrets! Mwahaha!
ScanKeys()
Mapper()
--... Uh, all it does is paint numbers where all objects are...
local mapx= (R1u(0x0000)%2)*256 + R1u(0x0002)
local mapy= R1u(0x0003)
for i= 0, 0x7F do
local ID= R1u(0x0400+i)
if ID ~= 0 then
local x,y= R1u(0x0480+i)*2,R1u(0x0500+i)*2
x= (x-mapx)%512
y= (y-mapy)%512
if x < 246 and y < 216 then -- At least try to paint it on screen
DrawNumx(x+8,y ,ID ,"white","black")
DrawNumx(x+8,y+6,R1u(0x0580+i),"white","black")
end
end
end
end
gui.register(BasicHUD)