brunovalads

EarthBound Lua Script

Aug 13th, 2018
636
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.44 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
  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 = 0x8000FF20
  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 = 0xffFF5050 -- SMAAAASH!!
  80.     elseif curRNG>184 then
  81.       color = 0x900080FF -- No enemies
  82.     end
  83.     gui.drawLine(x+i + Left_gap, y+height + Top_gap, x+i + Left_gap, y+height-math.floor(curRNG/256*height) + Top_gap,color)
  84.   end
  85.  
  86.   x, y = 2*128 + 2*Left_gap - 10*10/2, 2*(y+height) + 2*Top_gap + 4
  87.   color = 0x8000FF20
  88.   gui.text(x, y, "  No use  ", color)
  89.  
  90.   y = y + 14
  91.   color = 0xffFF5050
  92.   gui.text(x, y, "SMAAAASH!!", color)
  93.  
  94.   y = y + 14
  95.   color = 0xff0080FF
  96.   gui.text(x, y, "No enemies", color)
  97.  
  98.   y = y + 14
  99.   color = 0xffFFFF30
  100.   gui.text(x, y, "1/128 Item", color)
  101. end
  102.  
  103.  
  104. function watch_pos()
  105.  
  106.   -- General info
  107.  
  108.   gui.text(2, 2, emu.framecount())
  109.  
  110.   local game_mode = mainmemory.read_u8(0x0015) -- maybe?
  111.  
  112.   local x, y = 2*128 - 10*15/2 + 2*Left_gap, 2*Top_gap - 28
  113.   local camera_x = mainmemory.read_s16_le(0x0031)
  114.   local camera_y = mainmemory.read_s16_le(0x0033)
  115.   gui.text(x,y, string.format("Camera X: %5d \nCamera Y: %5d", camera_x, camera_y))
  116.  
  117.   if game_mode == 32 then -- map mode
  118.     gui.text(2*(256 + 64 + Left_gap) - 5*10, 2*(-64 + Top_gap), "spawn \n area", 0x80FFFFFF)
  119.     gui.drawBox(-64 + Left_gap, -64 + Top_gap, 256 + 64 + Left_gap, 224 + 64 + Top_gap, 0x80FFFFFF)
  120.   end
  121.  
  122.   -- Player info
  123.  
  124.   x, y = 2, 2*Top_gap
  125.   local ness_hp = mainmemory.read_u16_le(0x9FBF)
  126.   gui.text(x, y,"Ness HP:  "..ness_hp, 0xffFFFF30)
  127.  
  128.   y = y + 14
  129.   local m = mainmemory.read_s16_le(0x9831)
  130.   gui.text(x, y, "Money:    "..m)
  131.  
  132.   y = y + 14
  133.   local atm = mainmemory.read_s16_le(0x9835)
  134.   gui.text(x, y, "ATM:      "..atm)
  135.  
  136.   y = y + 14
  137.   local ss = mainmemory.read_s16_le(0x9E3C)
  138.   gui.text(x, y, "Skip S.:  "..ss)
  139.  
  140.   y = y + 14
  141.   local dr = mainmemory.read_s16_le(0xA934)
  142.   gui.text(x, y, "Drop   :  "..dr)
  143.  
  144.   y = y + 28
  145.   local xadr = 0x9875
  146.   gui.text(x,y,
  147.     string.format("X-Pos: %5d \n",mainmemory.read_u16_le(xadr+2))..
  148.     string.format("X-Sub: %5d \n",mainmemory.read_u16_le(xadr-0))..
  149.     string.format("Y-Pos: %5d \n",mainmemory.read_u16_le(xadr+6))..
  150.     string.format("Y-Sub: %5d \n",mainmemory.read_u16_le(xadr+4))
  151.   )
  152.   local x_screen = mainmemory.read_u16_le(xadr+2) - camera_x + Left_gap
  153.   local y_screen = mainmemory.read_u16_le(xadr+6) - camera_y + Top_gap
  154.   gui.drawAxis(x_screen, y_screen, 3, 0xffFF0000)
  155.  
  156.  
  157.   -- Battle info
  158.  
  159.   if game_mode == 16 or game_mode == 6 then -- battle mode
  160.     local enemy_hp_str = string.format("HP: %d", mainmemory.read_u16_le(0xA22F))
  161.     gui.text(2*128 - 10*string.len(enemy_hp_str)/2 + 2*Left_gap, 163 + 2*Top_gap, enemy_hp_str, 0xffFFFF30)
  162.   end
  163.  
  164.  
  165.   -- Sprite info
  166.  
  167.   if game_mode == 32 then -- map mode
  168.     for i = 0, 14-1 do -- there are 14 sprite slots, apparently
  169.       local sprite_id = mainmemory.read_u16_le(0x0A62 + 2*i)
  170.      
  171.       if sprite_id ~= 65535 then -- sprite is active
  172.         local sprite_x_pos = mainmemory.read_u16_le(0x0B8E + 2*i)
  173.         local sprite_y_pos = mainmemory.read_u16_le(0x0BCA + 2*i)
  174.        
  175.         local x_screen = sprite_x_pos - camera_x + Left_gap
  176.         local y_screen = sprite_y_pos - camera_y + Top_gap
  177.        
  178.         gui.drawAxis(x_screen, y_screen, 3, 0xffFF0000)
  179.         --gui.drawRectangle(x_screen - 8, y_screen - 24, 16, 32)
  180.        
  181.         local sprite_slot_str = string.format("#%02d", i)
  182.         gui.text(2*x_screen - 10*string.len(sprite_slot_str)/2, 2*y_screen + 14, sprite_slot_str, 0xffFF0000)
  183.         local sprite_id_str = string.format("(%d)", sprite_id)
  184.         gui.text(2*x_screen - 10*string.len(sprite_id_str)/2, 2*y_screen + 28, sprite_id_str, 0xffFF0000)
  185.       end
  186.     end
  187.   end
  188.  
  189.   --[[
  190.   enemy 1 x pos: 0x0B8E
  191.   Ness x pos: 0x0BBE
  192.   2nd partner x pos: 0x0BC6
  193.   1st partner x pos: 0x0BC8
  194.  
  195.   enemy 1 y pos: 0x0BCA
  196.   Ness y pos: 0x0BFA
  197.   2nd partner y pos: 0x0C02
  198.   1st partner y pos: 0x0C04
  199.  
  200.   tables are offset by 0x3C bytes (60 bytes, 30 slots)
  201.   ]]
  202. end
  203.  
  204. event.onframestart(search_RNGpos)
  205.  
  206. client.SetGameExtraPadding(Left_gap, Top_gap, Right_gap, Bottom_gap)
  207.  
  208. while true do
  209.   draw_RNGgraph(0,238,255,32)
  210.   watch_pos()
  211.  
  212.   emu.frameadvance()
  213. end
Add Comment
Please, Sign In to add comment