local ScriptInfo = {"Super Mario Land 2 Lua by Mugg1991", "v0.1", "8th Jul 2019",} local AddressTable1 = { [1] = {1,"Nothing",0xFFFFE0A0,"System Bus",0xC000,1,true}, [2] = {1,"Here",0xFFFFE0A0,"System Bus",0xC000,1,true}, [3] = {1,"Yet",0xFFFFE0A0,"System Bus",0xC000,1,true}, [4] = {1,"Check",0xFFFFE0A0,"System Bus",0xC000,1,true}, [5] = {1,"Back",0xFFFFE0A0,"System Bus",0xC000,1,true}, [6] = {1,"Later",0xFFFFE0A0,"System Bus",0xC000,1,true} } local Displays = { -- Name, active, col, x, y, width, height, offset of list, edit mode, table, entries shown [1]= {"General", false, 0xFFFFE0A0, 40, 40, 154, 66, 0, false, AddressTable1,6}, [2]= {"Current Oscillation", false, 0xFFFFE0A0, nil}, [3]= {"Full Oscillations", false, 0xFFFFE0A0, nil}, } local Mouse = { X = 0, Y = 0, XBefore = 0, YBefore = 0, clickedFrames = 0, clicked = false } local Color = { Selected = 0xB0A0A0A0, Normal = 0xA0303030, Grey = 0xA0C0C0C0 } function text(x, y, text, color, backcolor) if backcolor==nil then backcolor=0x00000000 end gui.drawText(x, y, text,color,backcolor,10,"Arial") end function box(x,y,x2,y2) gui.drawBox(x,y,x2,y2,0x00000000,0xD0000000) end function boxNormal(x,y,x2,y2) gui.drawBox(x,y,x2,y2,0xFF000000,0xA0000000) end function boxSelected(x,y,x2,y2) gui.drawBox(x,y,x2,y2,0xFF000000,0xA0505050) end function arrowDown(xpos,ypos,col) gui.drawLine(xpos,ypos,xpos+6,ypos,col) gui.drawLine(xpos+1,ypos+1,xpos+5,ypos+1,col) gui.drawLine(xpos+2,ypos+2,xpos+4,ypos+2,col) gui.drawPixel(xpos+3,ypos+3,col) end function arrowUp(xpos,ypos,col) gui.drawLine(xpos,ypos,xpos+6,ypos,col) gui.drawLine(xpos+1,ypos-1,xpos+5,ypos-1,col) gui.drawLine(xpos+2,ypos-2,xpos+4,ypos-2,col) gui.drawPixel(xpos+3,ypos-3,col) end local totime = function(frames,fps) hours = math.floor((frames/fps)/3600) mins = math.floor((frames/fps)/60)%60 secs = math.floor(((frames/fps-mins*60)*100+0.5)/100) %60 ms = (frames % fps)/60 * 100 if hours==0 then returnvalue = string.format("%02d:%02d.%02d",mins,secs,ms) else returnvalue = string.format("%02d:%02d:%02d.%02d",hours,mins,secs,ms) end return returnvalue end function drawDisplayBox(id,bordercolor,color) posx=Displays[id][4] posy=Displays[id][5] width=Displays[id][6] height=Displays[id][7] if Mouse.clicked then if Mouse.X > posx and Mouse.X < posx+width and Mouse.Y > posy and Mouse.Y < posy+height then if Mouse.clickedFrames > 0 then menuscreen=0 -- close menu posy = posy + (Mouse.Y-Mouse.YBefore) -- enables mouse drag posx = posx + (Mouse.X-Mouse.XBefore) if posy < 0 then posy=0 -- prevents display from going offscreen elseif posy > 159-height then posy=159-height end if posx < 0 then posx=0 elseif posx > 239-width then posx=239-width end Displays[id][4]=posx Displays[id][5]=posy end end end gui.drawBox(posx,posy,posx+width,posy+height,bordercolor,color) text(posx+3,posy-1,Displays[id][1],0xFF808080) end function drawCloseButton(id) width=Displays[id][6] x=Displays[id][4] y=Displays[id][5] drawButton(x+width-10,y,10,10,"x",Color.Grey,15,function() Displays[id][2] = false end) end function drawEditButton(id) width=Displays[id][6] x=Displays[id][4] y=Displays[id][5] if Displays[id][9] then col=Color.Selected else col=Color.Normal end drawButton(x+width-25,y,12,10,"e",col,15,function() Displays[id][9]=not Displays[id][9] end) end function drawButton(posx,posy,width,height,label,color,frequency,clickedfunction) if Mouse.X>posx and Mouse.Xposy and Mouse.Yposx and Mouse.Xposy and Mouse.Y540 then valueChangeAmount=valueChangeAmount*1000000 elseif Mouse.clickedFrames>450 then valueChangeAmount=valueChangeAmount*100000 elseif Mouse.clickedFrames>360 then valueChangeAmount=valueChangeAmount*10000 elseif Mouse.clickedFrames>270 then valueChangeAmount=valueChangeAmount*1000 elseif Mouse.clickedFrames>180 then valueChangeAmount=valueChangeAmount*100 elseif Mouse.clickedFrames>90 then valueChangeAmount=valueChangeAmount*10 end return valueChangeAmount end local addressTableSetValue = function(address, addressSize, addressEndian, newvalue) if addressSize==1 then memory.write_u8(address,newvalue) elseif addressSize==2 then if addressEndian then memory.write_u16_le(address,newvalue) else memory.write_u16_be(address,newvalue) end elseif addressSize==3 then if addressEndian then memory.write_u24_le(address,newvalue) else memory.write_u24_be(address,newvalue) end elseif addressSize==4 then if addressEndian then memory.write_u32_le(address,newvalue) else memory.write_u32_be(address,newvalue) end end end local addressTableGetValue = function(address, addressSize, addressEndian, addressSigned) if addressSigned then if addressSize==1 then value=memory.read_s8(address) elseif addressSize==2 then if addressEndian then value=memory.read_s16_le(address) else value=memory.read_s16_be(address) end elseif addressSize==3 then if addressEndian then value=memory.read_s24_le(address) else value=memory.read_s24_be(address) end elseif addressSize==4 then if addressEndian then value=memory.read_s32_le(address) else value=memory.read_s32_be(address) end end else if addressSize==1 then value=memory.read_u8(address) elseif addressSize==2 then if addressEndian then value=memory.read_u16_le(address) else value=memory.read_u16_be(address) end elseif addressSize==3 then if addressEndian then value=memory.read_u24_le(address) else value=memory.read_u24_be(address) end elseif addressSize==4 then if addressEndian then value=memory.read_u32_le(address) else value=memory.read_u32_be(address) end end end return value end local DisplayAddressTable = function(display_id, has_arrows, has_buttons, display_description, description_offset, arrows_offset, buttons_offset) inputTable=Displays[display_id][10] xpos=Displays[display_id][4] ypos=Displays[display_id][5] memorydomainBefore=memory.getcurrentmemorydomain() tableSize=table.getn(inputTable) table_start=1 table_end=Displays[display_id][11] table_iterations = 1 offset=Displays[display_id][8] list_height = 8*(table_end - table_start)+14 --display arrows: if has_arrows then --bottom arrow button if (tableSize - offset) > table_end then if Mouse.X>xpos+arrows_offset and Mouse.Xypos+list_height and Mouse.Y 0 then if Mouse.X>xpos+arrows_offset and Mouse.Xypos+list_height-10 and Mouse.Y clock time) text(5+xpos,3+ypos+table_iterations*8,totime(value,60), textColor) else text(5+xpos,3+ypos+table_iterations*8,value, textColor) end end if display_description then text(xpos+description_offset,3+ypos+table_iterations*8,description, textColor) end if has_buttons then if contenttype==7 then -- binary drawButton(xpos+buttons_offset,4+ypos+table_iterations*8,21,8,"Set",Color.Normal,8,function() currentvalue=memory.read_u8(address) if bit.check(currentvalue,currentbit) then memory.write_u8(address, bit.clear(currentvalue,currentbit)) else memory.write_u8(address, bit.set(currentvalue,currentbit)) end end) elseif contenttype~=0 then -- normal values drawButton(xpos+buttons_offset,4+ypos+table_iterations*8,9,8,"-",Color.Normal,5,function() valueChangeAmount = getChangeAmount(valueChangeAmount) -- increases when holding mouse key newvalue = value - valueChangeAmount addressTableSetValue(address,addressSize,addressEndian,newvalue) end) drawButton(12+xpos+buttons_offset,4+ypos+table_iterations*8,9,8,"+",Color.Normal,5,function() valueChangeAmount = getChangeAmount(valueChangeAmount) -- increases when holding mouse key newvalue = value + valueChangeAmount addressTableSetValue(address,addressSize,addressEndian,newvalue) end) end end table_iterations=table_iterations+1 end memory.usememorydomain(memorydomainBefore) end local drawDisplay = function(id) if Displays[id][4]~=nil then drawDisplayBox(id, 0xFF202020,0xA0000000) drawCloseButton(id) drawEditButton(id) if Displays[id][9] then DisplayAddressTable(id,true,true,true,76,158,52) else DisplayAddressTable(id,true,false,true,56,158,0) end end end local drawOscillation = function() memory.usememorydomain("System Bus") pattern_pointer= memory.read_u8(0xA200) speed= memory.read_s8(0xA202) global_timer= memory.read_u8(0xFF97) pattern_step= global_timer%8 +1 current_pattern= {} for i=1,8,1 do --val=memory.read_s8(pattern_pointer+0x1B00+i+4) val=memory.read_s8(pattern_pointer+0x1A00+i-2) if i==pattern_step then now=true else now=false end current_pattern[i]={val,now} end text(166,10,"global timer: " .. global_timer,0xFFFFFFFF,0x00FFFFFF) text(166,22,"Pattern pointer: " .. pattern_pointer,0xFFFFFFFF,0x00FFFFFF) text(166,34,"Pattern step: " .. pattern_step,0xFFFFFFFF,0x00FFFFFF) text(166,46,"spd: " .. speed,0xFFFFFFFF,0x00FFFFFF) for t=1,8,1 do if current_pattern[t][2] then text(154+t*12,68,current_pattern[t][1],0xFFFFFFFF,0xA0FF0000) else text(154+t*12,68,current_pattern[t][1],0xFFFFFFFF,0x00FFFFFF) end end end local drawOscillationFull = function() memory.usememorydomain("System Bus") pattern_pointer= memory.read_u8(0xA200) speed= memory.read_s8(0xA202) global_timer= memory.read_u8(0xFF97) pattern_step= global_timer%8 +1 current_pattern= {} bg_count=0 for i=1,8,1 do --val=memory.read_s8(pattern_pointer+0x1B00+i+4) val=memory.read_s8(pattern_pointer+0x1A00+i-2) if i==pattern_step then now=true else now=false end current_pattern[i]={val,now} end text(166,2,"glob: " .. global_timer,0xFFFFFFFF,0x00FFFFFF) text(224,2,"ptrn: " .. pattern_pointer,0xFFFFFFFF,0x00FFFFFF) text(282,2,"step: " .. pattern_step,0xFFFFFFFF,0x00FFFFFF) text(326,2,"spd: " .. speed,0xFFFFFFFF,0x00FFFFFF) for t=0,15,1 do for s=0,15,1 do val=memory.read_s8(0x1A00+t*16+s) if pattern_pointer==t*16+s+1 then bg_count=8 end if bg_count>0 then if bg_count == 9-pattern_step then bg_col=0xFFFF0000 else bg_col=0x60FF0000 end else bg_col=0x00FF0000 end gui.drawText(166+s*13,16+t*10,val,0xFFFFFFFF,bg_col,10,"Arial") if bg_count>0 then bg_count=bg_count-1 end end end end local Menu = { [1] = { [0] = "Script", [1] = 1, [2] = 2, [3] = 3 } } local drawMenu = function() verticalOffset=0 for a=1,table.getn(Menu),1 do drawMenuButton(-38+a*45,18,40,11,Menu[a][0],2,false,true,0xFFFFFFFF,function() menuscreen=a end) if menuscreen==a then for b=1,table.getn(Menu[a]),1 do id = Menu[a][b] title = Displays[id][1] indicator = Displays[id][2] col = Displays[id][3] drawMenuButton(7,32+verticalOffset*10,112,10,title,1,true,indicator,col,function() Displays[id][2] = not indicator if id==2 then -- oscillations if indicator then client.SetGameExtraPadding(0,0,0,0) else client.SetGameExtraPadding(0,0,110,0) Displays[3][2]=false end end if id==3 then -- oscillations full if indicator then client.SetGameExtraPadding(0,0,0,0) else client.SetGameExtraPadding(0,0,230,40) Displays[2][2]=false end end end) verticalOffset=verticalOffset+1 end end end if Mouse.clicked and Mouse.clickedFrames==1 then menuscreen = 0 end end event.onloadstate(function() end) event.onexit(function() client.SetGameExtraPadding(0,0,0,0) end) menuscreen=0 frames=0 console.clear() for i=1,table.getn(ScriptInfo),1 do print(ScriptInfo[i]) end while true do Mouse.X = input.getmouse().X Mouse.Y = input.getmouse().Y Mouse.clicked = input.getmouse().Left for i=1,table.getn(Displays) do -- all displays if Displays[i][2] then drawDisplay(i) end end drawMenu() -- menu if Displays[2][2] then drawOscillation() elseif Displays[3][2] then drawOscillationFull() end Mouse.XBefore=Mouse.X Mouse.YBefore=Mouse.Y if Mouse.clicked then Mouse.clickedFrames = Mouse.clickedFrames + 1 else Mouse.clickedFrames = 0 end if client.ispaused() then gui.DrawFinish() emu.yield() else emu.frameadvance() end frames=frames+1 end