Advertisement
Amaraticando

Alpha - Comparison script

May 29th, 2015
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.05 KB | None | 0 0
  1. -- Ghost definitions: put the filenames here (absolute or relative to the emulator)
  2. -- example: { "SMW-any%.smwg", "C:/Folder/simpleghost837244.smwg"}
  3. local ghost_dumps  = { "SDW-120exit-amarat,panga,bruno.dump", "simpleghost837244.dump", "SDW-120-WIP-Dawn.smwg"}
  4.  
  5. -- ***********************************
  6. -- ***********************************
  7. -- Compability
  8. local unpack = unpack or table.unpack
  9.  
  10. local SMW = {
  11.     -- Game Modes
  12.     game_mode_overworld = 0x0e,
  13.     game_mode_level = 0x14,
  14.    
  15.     sprite_max = 12, -- maximum number of sprites
  16. }
  17. local Camera_x, Camera_y
  18.  
  19. -- ***********************************
  20. -- ***********************************
  21. -- Utility functions
  22.  
  23. local function screen_coordinates2(x, y, camera_x, camera_y)
  24.     x_screen = (x - camera_x) + 8
  25.     y_screen = (y - camera_y) + 15
  26.    
  27.     return x_screen, y_screen
  28. end
  29.  
  30. -- Works like Bizhawk's function: draws a box given (x,y) and (x',y') with SNES' pixel sizes
  31. local function draw_box(x1, y1, x2, y2, ...)
  32.     x = 2*x1
  33.     y = 2*y1
  34.     w = 2 * (x2 - x1) + 2  -- adds thickness
  35.     h = 2 * (y2 - y1) + 2  -- adds thickness
  36.     gui.rectangle(x, y, w, h, ...)
  37. end
  38.  
  39. function get_game_mode()
  40.     return memory.readbyte("WRAM", WRAM.game_mode)
  41. end
  42.  
  43. function ghost_vs_player(index, x_mario, x_sub_mario, x_speed_mario, direction_mario, x_ghost, x_sub_ghost, direction_ghost)
  44.     local subpixels_mario = 16*x_mario + math.floor(x_sub_mario/16)
  45.     local subpixels_ghost = 16*x_ghost + x_sub_ghost
  46.     local x_difference
  47.     local frame_difference
  48.    
  49.     --if direction_mario == 1 then
  50.         x_difference = (subpixels_mario - subpixels_ghost)
  51.     --else
  52.     --  x_difference = (subpixels_ghost - subpixels_mario)
  53.     --end
  54.    
  55.     if x_speed_mario ~= 0 then
  56.         frame_difference = x_difference/x_speed_mario
  57.     else
  58.         frame_difference = math.huge
  59.     end
  60.    
  61.     local color = gui.rainbow(index, 6, "cyan")
  62.     draw_font["snes9xtext"]((index-1)*48, 0, string.format("%.1f", frame_difference), color, 0)
  63. end
  64.  
  65. -- Gets the current room and level of the player
  66. function get_room()
  67.     local room_index = 256*256*memory.readbyte("WRAM", WRAM.room_index) + 256*memory.readbyte("WRAM", WRAM.room_index + 1) + memory.readbyte("WRAM", WRAM.room_index + 2)
  68.     room_index = string.format("%x", room_index)  -- converts room_index to hexadecimal and then to string
  69.     return room_index
  70. end
  71.  
  72. -- Plots ghost
  73. function plot_ghost(ghost, ghost_frame, camera_x, camera_y, index)
  74.     local ghost_x = ghost[ghost_frame]["x"]
  75.     local ghost_sub_x = ghost[ghost_frame]["sub_x"]
  76.     local ghost_y = ghost[ghost_frame]["y"]
  77.     local ghost_direction = ghost[ghost_frame]["direction"]
  78.     local ghost_is_lagged = ghost[ghost_frame]["is_lagged"]
  79.     local ghost_hitbox_size = ghost[ghost_frame]["hitbox_size"]
  80.    
  81.     local mario_width = 5
  82.     local mario_up, mario_down
  83.     if ghost_hitbox_size == 0 then
  84.         mario_up = 0
  85.         mario_down = 16
  86.     elseif ghost_hitbox_size == 1 then
  87.         mario_up = -8
  88.         mario_down = 16
  89.     elseif ghost_hitbox_size == 2 then
  90.         mario_up = 3
  91.         mario_down = 32
  92.     else
  93.         mario_up = 0
  94.         mario_down = 32
  95.     end
  96.    
  97.     local x_screen, y_screen = screen_coordinates2(ghost_x, ghost_y, Camera_x, Camera_y)
  98.     draw_box(x_screen - mario_width - 1, y_screen + mario_up - 1, x_screen + mario_width + 1, y_screen + mario_down + 1, 1, gui.rainbow(index, 6, 0x8000ffff), 0xf0ff0000)
  99.    
  100.     local x_mario = memory.readsword("WRAM", WRAM.x)
  101.     local x_sub_mario = memory.readbyte("WRAM", WRAM.x_sub)
  102.     local x_speed_mario = memory.readsbyte("WRAM", WRAM.x_speed)
  103.     local direction_mario
  104.     if x_speed_mario >= 0 then
  105.         direction_mario = 1
  106.     else
  107.         direction_mario = 0
  108.     end
  109.    
  110.     ghost_vs_player(index, x_mario, x_sub_mario, x_speed_mario, direction_mario, ghost_x, ghost_sub_x, ghost_direction)
  111.    
  112.     return ghost_x, ghost_sub_x, ghost_y, ghost_direction, ghost_is_lagged, ghost_hitbox_size
  113. end
  114.  
  115.  
  116. -- ***********************************
  117. -- ***********************************
  118. -- Ghost functions
  119.  
  120. -- Reads filename and gets the table of room, entrance and exit frames for the ghost
  121. function read_ghost_from_dump(filename)
  122.     local ghost_room_table = {}
  123.    
  124.     local pattern = "%s*%d+%s+(%x+)%s+(%x+)%s+(%d+)%s+(%d+)%s+(%x+)%s+(%-*%d+)%s+(%d+)%s+(%d+)%s*"
  125.     --                1486 11 f71fc1 1    0 0    0 0 0
  126.    
  127.     local previous_mode = -1
  128.     local currentframe_since_room_started
  129.    
  130.     local count = 0  -- Amarat
  131.     for line in io.lines(filename) do
  132.         --local frame = tonumber(string.match(line, "%s*(%d+)"))  -- unused
  133.         local mode, room_index, is_lagged, x, sub_x, y, direction, hitbox_size = string.match(line, pattern)
  134.        
  135.         -- In case anything goes wrong
  136.         if not mode or not room_index or not is_lagged or not x or not sub_x or not y or not direction or not hitbox_size then
  137.             print(mode, room_index, is_lagged, x, sub_x, y, direction, hitbox_size)
  138.         end
  139.        
  140.         mode, is_lagged, x, sub_x, y, direction, hitbox_size = tonumber(mode, 16), tonumber(is_lagged), tonumber(x),
  141.                                         tonumber(sub_x, 16), tonumber(y), tonumber(direction), tonumber(hitbox_size)
  142.         ;
  143.        
  144.         if (mode ~= previous_mode) and (mode == SMW.game_mode_level) then  -- entering a level
  145.             if ghost_room_table[room_index] == nil then
  146.                 ghost_room_table[room_index] = {}
  147.             end
  148.             local size = #ghost_room_table[room_index]
  149.             currentframe_since_room_started = 1  -- resets it, since we wanna know the n-th frame of this room
  150.            
  151.             ghost_room_table[room_index][size + 1] = {}
  152.         end
  153.        
  154.         if (mode == SMW.game_mode_level) then
  155.             if not ghost_room_table[room_index] then print( count) end
  156.             ghost_room_table[room_index][#ghost_room_table[room_index]][currentframe_since_room_started] = {
  157.                 ["is_lagged"] = is_lagged == 1,
  158.                 ["x"] = x, ["sub_x"] = sub_x,
  159.                 ["y"] = y, ["sub_y"] = sub_y,
  160.                 ["direction"] = direction, ["hitbox_size"] = hitbox_size
  161.             }
  162.            
  163.             currentframe_since_room_started = currentframe_since_room_started + 1
  164.         end
  165.        
  166.         previous_mode = mode
  167.         count = count + 1
  168.     end
  169.    
  170.     --print(count.." linhas")  -- Amarat
  171.     return ghost_room_table
  172. end
  173.  
  174.  
  175. -- Put all ghosts in a general table
  176. local general_ghost_table = {}
  177. local function read_all_ghosts()
  178.     for entry, filename in ipairs(ghost_dumps) do
  179.         --print(entry, filename)  -- Amarat
  180.         general_ghost_table[entry] = read_ghost_from_dump(filename)
  181.     end
  182. end
  183.  
  184. -- Display the info and hitbox of all ghosts, if possible
  185. local function display_all_ghosts(general_ghost_table, room_index, currentframe_since_room_started)
  186.     local ghost_num = 1
  187.     for entry, ghost_table in ipairs(general_ghost_table) do
  188.    
  189.         if ghost_table[room_index] then
  190.        
  191.             for entrance_number, data in ipairs(ghost_table[room_index]) do
  192.            
  193.                 if currentframe_since_room_started <= #data then
  194.                     plot_ghost(data, currentframe_since_room_started, Camera_x, Camera_y, ghost_num)
  195.                    
  196.                 end
  197.                 ghost_num = ghost_num + 1
  198.                
  199.             end
  200.            
  201.         end
  202.        
  203.     end
  204.    
  205. end
  206.  
  207. --------------------------
  208. ----- Main function ------
  209.  
  210. local Is_displaying_ghosts = false
  211. local previous_room = nil
  212. local currentframe_since_room_started = nil
  213. local initialframe_room
  214. local From_frame_advance = false
  215.  
  216. read_all_ghosts()
  217. --print(general_ghost_table)  -- Amarat
  218.  
  219. function comparison(not_synth)
  220.     if get_game_mode() == SMW.game_mode_level then
  221.         -- read player info
  222.         local player_frame = movie.currentframe() + 1
  223.         if not not_synth then player_frame = player_frame - 1 end  -- if current frame is not the result of a frame advance
  224.        
  225.         local room_index = get_room()
  226.         Camera_x = memory.readsword("WRAM", WRAM.camera_x)
  227.         Camera_y = memory.readsword("WRAM", WRAM.camera_y)
  228.         --gui.text(0, 400, string.format("%s %d %s %s %s",  -- Amarat
  229.         --room_index, player_frame, tostring(initialframe_room), tostring(currentframe_since_room_started), tostring(From_frame_advance)))
  230.        
  231.         if From_frame_advance then
  232.             if not previous_room then  -- entering a level
  233.                 Is_displaying_ghosts = true
  234.                 currentframe_since_room_started = 1
  235.                 initialframe_room = player_frame
  236.                 display_all_ghosts(general_ghost_table, room_index, currentframe_since_room_started)
  237.                
  238.             elseif Is_displaying_ghosts then
  239.                 display_all_ghosts(general_ghost_table, room_index, currentframe_since_room_started)
  240.                
  241.             end
  242.            
  243.         else  -- from loadstate
  244.             if previous_room == room_index and Is_displaying_ghosts and player_frame >= currentframe_since_room_started and player_frame >= initialframe_room then
  245.                 -- loaded back in the same room
  246.                 currentframe_since_room_started = player_frame - initialframe_room + 1
  247.                 display_all_ghosts(general_ghost_table, room_index, currentframe_since_room_started)
  248.                
  249.             else
  250.                 Is_displaying_ghosts = false
  251.                
  252.             end
  253.            
  254.         end
  255.        
  256.         previous_room = room_index
  257.        
  258.     else  -- outside level
  259.        
  260.         previous_room = nil
  261.         Is_displaying_ghosts = false
  262.        
  263.     end
  264.    
  265. end
  266.  
  267. callback.frame_emulated:register(function()
  268.     From_frame_advance = true
  269.     currentframe_since_room_started = currentframe_since_room_started and currentframe_since_room_started + 1
  270. end)
  271. callback.frame:register(function() From_frame_advance = false end)
  272. callback.pre_load:register(function() From_frame_advance = false end)
  273.  
  274. print("Comparison script loaded")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement