Advertisement
Guest User

cps2-hitbox.lua

a guest
Aug 15th, 2010
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.82 KB | None | 0 0
  1. print("CPS-2 hitbox display")
  2. print("August 15, 2010") print()
  3.  
  4. local DRAW_DELAY            = 1
  5. local SCREEN_WIDTH          = 384
  6. local SCREEN_HEIGHT         = 224
  7. local MAX_GAME_PROJECTILES  = 32
  8. local AXIS_COLOUR           = 0xFFFFFFFF
  9. local MINI_AXIS_COLOUR      = 0xFFFF00FF
  10. local AXIS_SIZE             = 25
  11. local MINI_AXIS_SIZE        = 2
  12. local HITBOX_VULNERABILITY  = 0
  13. local HITBOX_ATTACK         = 1
  14. local HITBOX_PUSH           = 2
  15. local HITBOX_VULNERABILITY_COLOUR = 0x0000FF40
  16. local HITBOX_ATTACK_COLOUR  = 0xFF000040
  17. local HITBOX_PUSH_COLOUR    = 0x00FF0040
  18. local GAME_PHASE_NOT_PLAYING= 0
  19. if fba then DRAW_DELAY = DRAW_DELAY + 1 end
  20.  
  21. local profile = {
  22.     {
  23.         games = {"sfa3"},
  24.         address = {
  25.             player1          = 0x00FF8400,
  26.             player2          = 0x00FF8800,
  27.             projectile       = 0x00FF8D00,
  28.             left_screen_edge = 0x00FF8026,
  29.             top_screen_edge  = 0x00FF8028,
  30.             game_phase       = 0x00FF812D,
  31.         },
  32.         offset = {
  33.             v_hb_addr_table  = 0x90,
  34.             v_hb_curr_id     = 0xC8,
  35.             a_hb_addr_table  = 0xA0,
  36.             a_hb_curr_id     = 0x09,
  37.             p_hb_addr_table  = 0x9c,
  38.             p_hb_curr_id     = 0xCB,
  39.         },
  40.     },
  41.     {
  42.         games = {"vsav","vhunt2"},
  43.         address = {
  44.             player1          = 0x00FF8400,
  45.             player2          = 0x00FF8800,
  46.             projectile       = 0x00FF9400,
  47.             left_screen_edge = 0x00FF8026,
  48.             top_screen_edge  = 0x00FF8028,
  49.             game_phase       = 0x00FF812D,
  50.         },
  51.         offset = {
  52.             v_hb_addr_table  = 0x80,
  53.             v_hb_curr_id     = 0x94,
  54.             a_hb_addr_table  = 0x8c,
  55.             a_hb_curr_id     = 0x0A,
  56.             p_hb_addr_table  = 0x90,
  57.             p_hb_curr_id     = 0x97,
  58.         },
  59.     },
  60. }
  61.  
  62. local address, offset
  63. local globals = {
  64.     game_phase       = 0,
  65.     left_screen_edge = 0,
  66.     top_screen_edge  = 0,
  67.     num_projectiles  = 0
  68. }
  69. local player1     = {}
  70. local player2     = {}
  71. local projectiles = {}
  72. local frame_buffer_array = {}
  73. for f = 1, DRAW_DELAY + 1 do
  74.     frame_buffer_array[f] = {}
  75.     frame_buffer_array[f][projectiles] = {}
  76. end
  77.  
  78. function update_globals()
  79.     globals.left_screen_edge = memory.readword(address.left_screen_edge)
  80.     globals.top_screen_edge  = memory.readword(address.top_screen_edge)
  81.     globals.game_phase       = memory.readword(address.game_phase)
  82. end
  83.  
  84.  
  85. function hitbox_load(obj, i, type, facing_dir, offset_x, offset_y, addr)
  86.     local hval    = memory.readwordsigned(addr + 0)
  87.     local vval    = memory.readwordsigned(addr + 2)
  88.     local hrad    = memory.readwordsigned(addr + 4)
  89.     local vrad    = memory.readwordsigned(addr + 6)
  90.  
  91.     if facing_dir == 1 then
  92.         hval  = -hval
  93.     end
  94.  
  95.     local left   = offset_x + hval - hrad
  96.     local top    = offset_y + vval - vrad
  97.     local right  = offset_x + hval + hrad
  98.     local bottom = offset_y + vval + vrad
  99.  
  100.     if type == HITBOX_VULNERABILITY then
  101.         obj[HITBOX_VULNERABILITY][i] = {
  102.             left   = left,
  103.             right  = right,
  104.             bottom = bottom,
  105.             top    = top,
  106.             hval   = offset_x+hval,
  107.             vval   = offset_y+vval,
  108.             type   = type
  109.         }
  110.     else
  111.         obj[type] = {
  112.             left   = left,
  113.             right  = right,
  114.             bottom = bottom,
  115.             top    = top,
  116.             hval   = offset_x+hval,
  117.             vval   = offset_y+vval,
  118.             type   = type
  119.         }
  120.     end
  121. end
  122.  
  123.  
  124. function update_game_object(obj, base)
  125.     obj.facing_dir   = memory.readbyte(base + 0xB)
  126.     obj.pos_x        = memory.readword(base + 0x10)
  127.     obj.pos_y        = memory.readword(base + 0x14)
  128.     obj.opponent_dir = memory.readbyte(base + 0x5D)
  129.  
  130.     -- Load the vulnerability hitboxes
  131.     obj[HITBOX_VULNERABILITY] = {}
  132.     for i = 0, 2 do
  133.         local v_hb_addr_table = memory.readdword(base + offset.v_hb_addr_table + (i*4))
  134.         local v_hb_curr_id    = memory.readbyte(base + offset.v_hb_curr_id + i)
  135.         hitbox_load(obj, i, HITBOX_VULNERABILITY, obj.facing_dir, obj.pos_x, obj.pos_y, v_hb_addr_table+(v_hb_curr_id*8))
  136.     end
  137.  
  138.     -- Load the attack hitbox
  139.     local a_hb_addr_table = memory.readdword(base + offset.a_hb_addr_table)
  140.     local animation_ptr   = memory.readdword(base + 0x1C)
  141.     local a_hb_curr_id    = memory.readbyte(animation_ptr + offset.a_hb_curr_id)
  142.     hitbox_load(obj, 0, HITBOX_ATTACK, obj.facing_dir, obj.pos_x, obj.pos_y, a_hb_addr_table+(a_hb_curr_id*0x20))
  143.  
  144.     -- Load the push hitbox
  145.     local p_hb_addr_table = memory.readdword(base + offset.p_hb_addr_table)
  146.     local p_hb_curr_id    = memory.readbyte(base + offset.p_hb_curr_id)
  147.     hitbox_load(obj, 0, HITBOX_PUSH, obj.facing_dir, obj.pos_x, obj.pos_y, p_hb_addr_table+(p_hb_curr_id*8))
  148. end
  149.  
  150.  
  151. function read_projectiles()
  152.     globals.num_projectiles = 0
  153.     for i = 0,MAX_GAME_PROJECTILES do
  154.         local base = address.projectile + (i*0x100)
  155.  
  156.         if memory.readbyte(base) ~= 0 then
  157.             projectiles[globals.num_projectiles] = {}
  158.             update_game_object(projectiles[globals.num_projectiles], base)
  159.             globals.num_projectiles = globals.num_projectiles+1
  160.         end
  161.     end
  162. end
  163.  
  164.  
  165. function game_x_to_mame(x)
  166.     return (x - globals.left_screen_edge)
  167. end
  168.  
  169.  
  170. function game_y_to_mame(y)
  171.     -- Why subtract 17? No idea, the game driver does the same thing.
  172.     return (SCREEN_HEIGHT - (y - 17) + globals.top_screen_edge)
  173. end
  174.  
  175.  
  176. function draw_hitbox(hb)
  177.     local left   = game_x_to_mame(hb.left)
  178.     local bottom = game_y_to_mame(hb.bottom)
  179.     local right  = game_x_to_mame(hb.right)
  180.     local top    = game_y_to_mame(hb.top)
  181.     local hval   = game_x_to_mame(hb.hval)
  182.     local vval   = game_y_to_mame(hb.vval)
  183.  
  184.     if hb.type == HITBOX_VULNERABILITY then
  185.         colour = HITBOX_VULNERABILITY_COLOUR
  186.     elseif hb.type == HITBOX_ATTACK then
  187.         colour = HITBOX_ATTACK_COLOUR
  188.     elseif hb.type == HITBOX_PUSH then
  189.         colour = HITBOX_PUSH_COLOUR
  190.     end
  191.  
  192.     -- draw mini axis
  193. --  gui.drawline(hval, vval-MINI_AXIS_SIZE, hval, vval+MINI_AXIS_SIZE, MINI_AXIS_COLOUR)
  194. --  gui.drawline(hval-MINI_AXIS_SIZE, vval, hval+MINI_AXIS_SIZE, vval, MINI_AXIS_COLOUR)
  195.     gui.box(left, top, right, bottom, colour)
  196. end
  197.  
  198.  
  199. function draw_game_object(obj)
  200.     if not obj then return end
  201.  
  202.     local x = game_x_to_mame(obj.pos_x)
  203.     local y = game_y_to_mame(obj.pos_y)
  204.  
  205.     for i = 0, 2 do
  206.         draw_hitbox(obj[HITBOX_VULNERABILITY][i])
  207.     end
  208.     draw_hitbox(obj[HITBOX_ATTACK])
  209.     draw_hitbox(obj[HITBOX_PUSH])
  210.  
  211.     gui.drawline(x, y-AXIS_SIZE, x, y+AXIS_SIZE, AXIS_COLOUR)
  212.     gui.drawline(x-AXIS_SIZE, y, x+AXIS_SIZE, y, AXIS_COLOUR)
  213. end
  214.  
  215.  
  216. local function whatgame()
  217.     address, offset = nil, nil
  218.     for n, module in ipairs(profile) do
  219.         for m, shortname in ipairs(module.games) do
  220.             if emu.romname() == shortname or emu.parentname() == shortname then
  221.                 print("drawing " .. shortname .. " hitboxes")
  222.                 address = module.address
  223.                 offset = module.offset
  224.                 return
  225.             end
  226.         end
  227.     end
  228.     print("not prepared for " .. emu.romname() .. " hitboxes")
  229. end
  230.  
  231.  
  232. local function update_cps2_hitboxes()
  233.     if not address then return end
  234.     update_globals()
  235.     if globals.game_phase == GAME_PHASE_NOT_PLAYING then
  236.         return
  237.     end
  238.  
  239.     update_game_object(player1, address.player1)
  240.     update_game_object(player2, address.player2)
  241.     read_projectiles()
  242.  
  243.     for f = 1, DRAW_DELAY do
  244.         frame_buffer_array[f][player1] = copytable(frame_buffer_array[f+1][player1])
  245.         frame_buffer_array[f][player2] = copytable(frame_buffer_array[f+1][player2])
  246.         for i = 0, globals.num_projectiles-1 do
  247.             frame_buffer_array[f][projectiles][i] = copytable(frame_buffer_array[f+1][projectiles][i])
  248.         end
  249.     end
  250.  
  251.     frame_buffer_array[DRAW_DELAY+1][player1] = copytable(player1)
  252.     frame_buffer_array[DRAW_DELAY+1][player2] = copytable(player2)
  253.     for i = 0, globals.num_projectiles-1 do
  254.         frame_buffer_array[DRAW_DELAY+1][projectiles][i] = copytable(projectiles[i])
  255.     end
  256. end
  257.  
  258.  
  259. function render_cps2_hitboxes()
  260.     if not address or globals.game_phase == GAME_PHASE_NOT_PLAYING then
  261.         gui.clearuncommitted()
  262.         return
  263.     end
  264.  
  265.     draw_game_object(frame_buffer_array[1][player1])
  266.     draw_game_object(frame_buffer_array[1][player2])
  267.  
  268.     for i = 0, globals.num_projectiles-1 do
  269.         draw_game_object(frame_buffer_array[1][projectiles][i])
  270.     end
  271. end
  272.  
  273.  
  274. emu.registerstart( function()
  275.     whatgame()
  276. end)
  277.  
  278.  
  279. emu.registerafter( function()
  280.     update_cps2_hitboxes()
  281. end)
  282.  
  283.  
  284. gui.register( function()
  285.     render_cps2_hitboxes()
  286. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement