Guest User

Super Mario Land lua

a guest
May 3rd, 2025
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.27 KB | Gaming | 0 0
  1. -- this outputs some information related to the map loading procedure when the screen scrolls,
  2. -- hopefully helpful for researching and recreating the scroll bug
  3. -- script by mugg ; with help from ais523, Sand
  4.  
  5. local PRINT_INFO = false
  6.  
  7. console.clear()
  8. memory.usememorydomain("System Bus")
  9.  
  10. local cycles_at_frame_start = emu.totalexecutedcycles()
  11. local cycles_at_frame_end = emu.totalexecutedcycles()
  12. local print_after_this_frame = emu.framecount() + 1
  13. local game_version = "-"
  14. local t = ""
  15. local t_frame_info = ""
  16. local frames_processed = 0
  17.  
  18. -- these have to happen in the same frame
  19. local requirement1 = false -- timer interrupt happens while ffea is 0x01
  20. local requirement2 = false -- ffea gets set to 0x03
  21.  
  22. local bugframe_tbl = {}
  23. local double_timer_interrupt_tbl = {}
  24. local timer_interrupts_same_frame = 0
  25.  
  26. if gameinfo.getromhash() == "3A4DDB39B234A67FFB361EE7ABC3D23E0A8B1C89" then
  27.     game_version = "1.0"
  28. elseif gameinfo.getromhash() == "418203621B887CAA090215D97E3F509B79AFFD3E" then
  29.     game_version = "1.1"
  30. else
  31.     print("This script will work only with GB Super Mario Land v1.0 or v1.1.")
  32.     return
  33. end
  34.  
  35. function text(x, y, text, color, backcolor)
  36.     gui.pixelText(x, y, text, color, backcolor)
  37. end
  38.  
  39. event.onframestart(function()
  40.     cycles_at_frame_start = emu.totalexecutedcycles()
  41.    
  42.     if emu.framecount() > print_after_this_frame then
  43.         local prefix = ""
  44.         if frames_processed > 1 then
  45.             prefix = "\n"
  46.         end
  47.         t_frame_info = prefix .. "   FRAME " .. emu.framecount() + 1
  48.     end
  49. end)
  50.  
  51. event.onframeend(function()
  52.  
  53.     if emu.framecount()-1 > print_after_this_frame then
  54.         t_frame_info = t_frame_info .. "  Cy:" .. emu.totalexecutedcycles() - cycles_at_frame_end
  55.     end
  56.    
  57.     if emu.islagged()
  58.     and emu.framecount()-1 > print_after_this_frame then
  59.         t_frame_info = t_frame_info .. "  **LAG**"
  60.     end
  61.        
  62.     cycles_at_frame_end = emu.totalexecutedcycles()
  63.  
  64.     -- only print if the string isn't empty
  65.     if PRINT_INFO then
  66.         if #t_frame_info > 0 and #t > 0 then
  67.             print(t_frame_info .. "\n" .. t)
  68.         elseif #t_frame_info > 0 then
  69.             print(t_frame_info)
  70.         end
  71.     end
  72.    
  73.     -- bugframe happened, save framecount and pixel pos
  74.     if requirement1 and requirement2 then
  75.         print("Bug frame!!!")
  76.         local bugframe_info = {emu.framecount(), memory.read_u8(0xFFE9)*8}
  77.         table.insert(bugframe_tbl, bugframe_info)
  78.     end
  79.    
  80.     -- reset values
  81.     requirement1 = false
  82.     requirement2 = false
  83.     t = ""
  84.     t_frame_info = ""
  85.     timer_interrupts_same_frame = 0
  86.  
  87.     frames_processed = frames_processed + 1
  88. end)
  89.  
  90. tastudio.onbranchload(function()
  91.     print_after_this_frame = emu.framecount() + 1
  92.     frames_processed = -1
  93.     console.clear()
  94.     bugframe_tbl = {}
  95.     double_timer_interrupt_tbl = {}
  96. end)
  97.  
  98. event.onloadstate(function()
  99.     print_after_this_frame = emu.framecount() + 1
  100.     frames_processed = -1
  101.     console.clear()
  102.     bugframe_tbl = {}
  103.     double_timer_interrupt_tbl = {}
  104. end)
  105.  
  106. -- Write to $FFEA
  107. -- passed val is always 0, it seems, hinting that this hook is not fully implemented
  108. event.on_bus_write(function(addr, val, flags)
  109.     if emu.framecount() > print_after_this_frame then
  110.         local raw_val = memory.read_u8(0xFFEA)
  111.         local val = string.upper(string.format("%02x",raw_val))
  112.         local myname = "Write $FFEA (" .. val .. ")"
  113.         t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  114.        
  115.         if raw_val == 0x03 then
  116.             requirement2 = true
  117.         end
  118.     end
  119. end, 0xFFEA)
  120.  
  121. -- Write to $FFE9
  122. event.on_bus_write(function(addr, val, flags)
  123.     if emu.framecount() > print_after_this_frame then
  124.         local val = string.upper(string.format("%02x",memory.read_u8(0xFFE9)))
  125.         local myname = "Write $FFE9 (" .. val .. ")"
  126.         t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  127.     end
  128. end, 0xFFE9)
  129.  
  130. -- Exec $0040
  131. event.on_bus_exec(function(addr, val, flags)
  132.     if emu.framecount() > print_after_this_frame then
  133.         local myname = "Execu $0040 (VBLANK INTERRUPT)"
  134.         t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  135.     end
  136. end, 0x0040)
  137.  
  138. -- Exec $0050
  139. event.on_bus_exec(function(addr, val, flags)
  140.     if emu.framecount() > print_after_this_frame then
  141.         local myname = "Execu $0050 (TIMER INTERRUPT)"
  142.         t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  143.        
  144.         local ffea = memory.read_u8(0xFFEA)
  145.         if ffea == 0x01 then
  146.             requirement1 = true
  147.         end
  148.        
  149.         timer_interrupts_same_frame = timer_interrupts_same_frame + 1
  150.         if timer_interrupts_same_frame >= 2 then
  151.             t = t .. "\nTwo Timer Interrupts!"
  152.             table.insert(double_timer_interrupt_tbl, emu.framecount()+1)
  153.         end
  154.     end
  155. end, 0x0050)
  156.  
  157. -- Exec $0060
  158. --[[
  159. event.on_bus_exec(function(addr, val, flags)
  160.     if emu.framecount() > print_after_this_frame then
  161.         local myname = "Execu $0060 (JOYPAD INTERRUPT)"
  162.         t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  163.     end
  164. end, 0x0060)
  165. --]]
  166.  
  167. -- game version dependent execs
  168. if game_version == "1.0" then
  169.  
  170.     event.on_bus_exec(function(addr, val, flags)
  171.         if emu.framecount() > print_after_this_frame then
  172.             local myname = "Execu $2258 (READ $FFEA)"
  173.             t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  174.         end
  175.     end, 0x224F)
  176.    
  177.     event.on_bus_exec(function(addr, val, flags)
  178.         if emu.framecount() > print_after_this_frame then
  179.             local myname = "Execu $2254 (READ $FFE9)"
  180.             t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  181.         end
  182.     end, 0x2254)
  183.  
  184. elseif game_version == "1.1" then
  185.  
  186.     event.on_bus_exec(function(addr, val, flags)
  187.         if emu.framecount() > print_after_this_frame then
  188.             local myname = "Execu $2258 (READ $FFEA)"
  189.             t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  190.         end
  191.     end, 0x2258)
  192.    
  193.     event.on_bus_exec(function(addr, val, flags)
  194.         if emu.framecount() > print_after_this_frame then
  195.        
  196.             local myname = "Execu $225D (READ $FFE9)"
  197.             t = t .. "\n" .. string.format("%-32s", myname) .. " cycle: " .. emu.totalexecutedcycles() - cycles_at_frame_start
  198.         end
  199.     end, 0x225D)
  200.  
  201. end
  202.  
  203. while true do
  204.    
  205.     gui.clearGraphics()
  206.    
  207.     if #bugframe_tbl > 0 then
  208.         for i=1, #bugframe_tbl, 1 do
  209.             local bugframe_entry = bugframe_tbl[i]
  210.            
  211.             if bugframe_entry ~= nil then
  212.            
  213.                 local bugframe_framecount = bugframe_entry[1]
  214.                 local bugframe_pixel = bugframe_entry[2]
  215.                 local current_pixel = memory.read_u8(0xFFE9) * 8
  216.                 local display_pixel = (bugframe_pixel - current_pixel) - memory.read_u8(0xFF43)%8 + 216
  217.  
  218.                 text(10, 10 + i*8, "bug Frame " .. bugframe_framecount, 0xFF00FF00, 0x80000000)
  219.            
  220.                 if display_pixel > 160 then
  221.                     text(136,10 + i*8, "--->", 0xFFFF0000, 0x80000000)
  222.                 else
  223.                     gui.drawLine(display_pixel, 17, display_pixel, 144, 0xFFFF0000)
  224.                 end
  225.                
  226.                 if display_pixel < 0 then
  227.                     bugframe_tbl[i] = nil
  228.                 end
  229.                
  230.             end
  231.         end
  232.     end
  233.    
  234.     --[[
  235.     if #double_timer_interrupt_tbl > 0 then
  236.         for j=1, #double_timer_interrupt_tbl, 1 do
  237.             local frame = double_timer_interrupt_tbl[j]
  238.             text(10, 80 + j*8, "two timer interrupts frame " .. frame, 0xFF00FF00, 0x80000000)
  239.         end
  240.     end
  241.     --]]
  242.  
  243.     emu.frameadvance()
  244. end
  245.  
Advertisement
Add Comment
Please, Sign In to add comment