pirohiko

MOTHER2 Lua Script

Sep 18th, 2018
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.32 KB | None | 0 0
  1. -- #########################################
  2. -- #                                       #
  3. -- #  EarthBound Utils Script for BizHawk  #
  4. -- #                                       #
  5. -- #  Author: BrunoValads                  #
  6. -- #                                       #
  7. -- #  Original by pirohiko for Snes9x      #
  8. -- #  https://pastebin.com/z1ueHSZG        #
  9. -- #                                       #
  10. -- #########################################
  11.  
  12. -- CONFIGURATION --
  13.  
  14. local Left_gap = 80 -- change these values if the emu doesn't fit in your screen
  15. local Top_gap = 80
  16. local Right_gap = 80
  17. local Bottom_gap = 80+32
  18.  
  19. -- MAIN --
  20.  
  21. local RNG24 = {}
  22. local RNG26 = {}
  23. local RNG   = {}
  24. local bit = 0
  25. local RNGoffset = -70
  26. local RNGend = 14592
  27. local RNGpos = -70
  28. RNG24[RNGoffset] = 4660
  29. RNG26[RNGoffset] = 120
  30. RNG[RNGoffset] = 134
  31.  
  32. for i=RNGoffset+1,RNGend do
  33.   RNG24[i] = math.floor((RNG24[i-1]+bit)/2)+32768*math.fmod(RNG24[i-1]+bit,2)
  34.   RNG26[i] = math.fmod(RNG26[i-1]+109, 256)
  35.   RNG[i] = math.fmod(math.floor(math.fmod(RNG24[i],256)*RNG26[i]/16),256)
  36.   bit = math.fmod(math.floor(math.fmod(RNG24[i],256)*RNG26[i]/4),4)
  37. end
  38.  
  39. function search_RNGpos()
  40.   local cur24 = mainmemory.read_u16_le(0x0024)
  41.   local cur26 = mainmemory.read_u8(0x0026)
  42.   RNGpos = RNGoffset
  43.   for i=RNGoffset, 256 do
  44.     if(RNG26[i]==cur26) then
  45.       for j=i, RNGend, 256 do
  46.         if(RNG24[j]==cur24) then
  47.           RNGpos = j
  48.           break
  49.         end
  50.       end
  51.       break
  52.     end
  53.   end
  54. end
  55.  
  56. function draw_RNGgraph(x,y,width,height) --draw_RNGgraph(0,288,255,32)
  57.  
  58.   local RNG_str = string.format("%5d/%5d", RNGpos, RNGend)
  59.   gui.text(2*256 - 10*string.len(RNG_str) - 2 + 2*Left_gap, 2*224 + 2*Top_gap, RNG_str)
  60.   gui.text(2 + 2*Left_gap, 2*224 + 2*Top_gap, string.format("RNG: %3d", RNG[RNGpos]))
  61.  
  62.   gui.drawBox(x + Left_gap, y-1 + Top_gap, x+width + Left_gap, y+height+1 + Top_gap, 0x50FFFFFF)
  63.   gui.drawLine(x+36 + Left_gap, y+height+2 + Top_gap, x+36 + Left_gap, y-2 + Top_gap, 0xffFFFFFF)
  64.  
  65.   local color
  66.  
  67.   for i=0,width do
  68.     color = 0x8000FF40
  69.     local curRNG = RNG[(RNGpos+i)%14592]
  70.     if curRNG==0 then
  71.       color = 0xffFF1010 -- 1/128 Item Drop
  72.       curRNG=256
  73.     elseif curRNG==128 then
  74.       color = 0xffFFFF30 -- 1/128 Item Drop
  75.     elseif curRNG==255 then
  76.       color = 0xffFF8000 -- MAX
  77.       curRNG=256
  78.     elseif curRNG<=12 then
  79.       color = 0xffFF4040 -- SMAAAASH!!
  80.       curRNG=128
  81.     --elseif curRNG>184 then
  82.     elseif curRNG>25 then
  83.       color = 0x900050FF -- 10% enemies
  84.     else
  85.       curRNG=128
  86.     end
  87.     gui.drawLine(x+i + Left_gap, y+height + Top_gap, x+i + Left_gap, y+height-math.floor(curRNG/256*height) + Top_gap,color)
  88.   end
  89.  
  90.   x, y = 2*128 + 2*Left_gap - 10*10/2, 2*(y+height) + 2*Top_gap + 4
  91.   color = 0x8000FF40
  92.   gui.text(x, y, "10% enemies", color)
  93.  
  94.   y = y + 14
  95.   color = 0xffFF4040
  96.   gui.text(x, y, "SMAAAASH!!", color)
  97.  
  98.   y = y + 14
  99.   color = 0xff0050FF
  100.   gui.text(x, y, "No enemies", color)
  101.  
  102.   y = y + 14
  103.   color = 0xffFFFF30
  104.   gui.text(x, y, "1/128 Item", color)
  105. end
  106.  
  107.  
  108. function watch_pos()
  109.  
  110.   -- General info
  111.  
  112.   gui.text(2, 2, emu.framecount())
  113.  
  114.   local game_mode = mainmemory.read_u8(0x0015) -- maybe?
  115.  
  116.   local x, y = 2*128 - 10*15/2 + 2*Left_gap, 2*Top_gap - 28
  117.   local camera_x = mainmemory.read_s16_le(0x0031)
  118.   local camera_y = mainmemory.read_s16_le(0x0033)
  119.   gui.text(x,y, string.format("Camera X: %5d \nCamera Y: %5d", camera_x, camera_y))
  120.  
  121.   if game_mode == 32 then -- map mode
  122.     gui.text(2*(256 + 64 + Left_gap) - 5*10, 2*(-64 + Top_gap), "spawn \n area", 0x80FFFFFF)
  123.     gui.drawBox(-64 + Left_gap, -64 + Top_gap, 256 + 64 + Left_gap, 256 + 64 + Top_gap, 0x80FFFFFF)
  124.   end
  125.  
  126.   -- Player info
  127.  
  128.   x, y = 36, 2*Top_gap
  129.   local ness_hp = mainmemory.read_u16_le(0x9cc5)
  130.   gui.text(x, y,"Ness HP:"..ness_hp, 0xffFFFF30)
  131.  
  132.   y = y + 14
  133.   local m = mainmemory.read_s16_le(0x9AE2)
  134.   gui.text(x, y, "Money  :"..m)
  135.  
  136.   y = y + 14
  137.   local atm = mainmemory.read_s16_le(0x9AE6)
  138.   gui.text(x, y, "ATM    :"..atm)
  139.  
  140.   y = y + 14
  141.   local ss = mainmemory.read_s16_le(0xA042)
  142.   gui.text(x, y, "Skip S.:"..ss)
  143.  
  144.   y = y + 14
  145.   local dr = mainmemory.read_s16_le(0xABE5)
  146.   gui.text(x, y, "Drop   :"..dr)
  147.  
  148.   y = y + 28
  149.   local xadr = 0x009B26 -- MOTHER 2
  150. --local xadr = 0x009875 -- EARTH BOUND
  151.   gui.text(x,y,
  152.     string.format("X-Pos: %5d \n",mainmemory.read_u16_le(xadr+2))..
  153.     string.format("X-Sub: %5d \n",mainmemory.read_u16_le(xadr-0))..
  154.     string.format("Y-Pos: %5d \n",mainmemory.read_u16_le(xadr+6))..
  155.     string.format("Y-Sub: %5d \n",mainmemory.read_u16_le(xadr+4))
  156.   )
  157.   local x_screen = mainmemory.read_u16_le(xadr+2) - camera_x + Left_gap
  158.   local y_screen = mainmemory.read_u16_le(xadr+6) - camera_y + Top_gap
  159.   gui.drawAxis(x_screen, y_screen, 3, 0xffFF0000)
  160.  
  161.  
  162.   -- Battle info
  163.  
  164.   if game_mode == 16 or game_mode == 6 then -- battle mode
  165.     local enemy_hp_str = string.format("HP: %d", mainmemory.read_u16_le(0xA431))
  166.     gui.text(2*128 - 10*string.len(enemy_hp_str)/2 + 2*Left_gap, 163 + 2*Top_gap, enemy_hp_str, 0xffFFFF30)
  167.   end
  168.  
  169.  
  170.   -- Sprite info
  171.  
  172.   if game_mode == 32 then -- map mode
  173.     for i = 0, 22-1 do -- there are 22 sprite slots
  174.       local sprite_id = mainmemory.read_u16_le(0x0A58 + 2*i)
  175.       local color_table = {
  176.           0xFF0000,0xFF4000,0xFF8000,0xFFC000,
  177.           0xFFFF00,0xC0FF00,0x80FF00,0x40FF00,
  178.           0x00FF00,0x00FF40,0x00FF80,0x00FFC0,
  179.           0x00FFFF,0x00C0FF,0x0080FF,0x0040FF,
  180.           0x0000FF,0x4000FF,0x8000FF,0xC000FF,
  181.           0xFF00FF,0xFF00C0,0xFF0080,0xFF0040
  182.       }
  183.       gui.text(Left_gap*2 + 520, Top_gap*2 + -16,string.format("Enemies:%2d/%2d", mainmemory.read_s16_le(0x4DE2), mainmemory.read_s16_le(0x4DE4) ), 0xffFFFFFF )
  184.  
  185.       if sprite_id ~= 65535 then -- sprite is active
  186.         local sprite_x_pos = mainmemory.read_u16_le(0x0B84 + 2*i)
  187.         local sprite_y_pos = mainmemory.read_u16_le(0x0BC0 + 2*i)
  188.        
  189.         local x_screen = sprite_x_pos - camera_x + Left_gap
  190.         local y_screen = sprite_y_pos - camera_y + Top_gap
  191.        
  192.         gui.drawAxis(x_screen, y_screen, 3, 0xffFF0000)
  193.         --gui.drawRectangle(x_screen - 8, y_screen - 24, 16, 32)
  194.         local color = color_table[i+1] + 0xff000000
  195.         local sprite_slot_str = string.format("#%02d", i)
  196.         gui.text(2*x_screen - 10*string.len(sprite_slot_str)/2, 2*y_screen + 14, sprite_slot_str, color)
  197.         local sprite_id_str = string.format("(%04X)", sprite_id)
  198.         gui.text(2*x_screen - 10*string.len(sprite_id_str)/2, 2*y_screen + 28, sprite_id_str, color)
  199.         gui.text(Left_gap*2 + 520, Top_gap*2 + i*16, string.format("#%02d:%04X", i, sprite_id), color)
  200.       else
  201.         local color = color_table[i+1] + 0x20000000
  202.         gui.text(Left_gap*2 + 520, Top_gap*2 + i*16, string.format("#%02d:%04X", i, sprite_id), color)
  203.       end
  204.     end
  205.   end
  206.  
  207.   --[[
  208.   enemy 1 x pos: 0x0B8E
  209.   Ness x pos: 0x0BBE
  210.   2nd partner x pos: 0x0BC6
  211.   1st partner x pos: 0x0BC8
  212.  
  213.   enemy 1 y pos: 0x0BCA
  214.   Ness y pos: 0x0BFA
  215.   2nd partner y pos: 0x0C02
  216.   1st partner y pos: 0x0C04
  217.  
  218.   tables are offset by 0x3C bytes (60 bytes, 30 slots)
  219.   ]]
  220. end
  221.  
  222. event.onframestart(search_RNGpos)
  223.  
  224. client.SetGameExtraPadding(Left_gap, Top_gap, Right_gap, Bottom_gap)
  225.  
  226.  
  227.  
  228. while true do
  229.   draw_RNGgraph(0,238,255,32)
  230.   watch_pos()
  231.  
  232.   emu.frameadvance()
  233. end
Add Comment
Please, Sign In to add comment