Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- outprefix = "simpleghost"..tostring(math.random(9999999))
- dumpfile = outprefix..".smwg"
- nomovie = false
- sucess = io.output(dumpfile)
- if not bit then bit = require"bit" end
- local SMW = {
- -- Game Modes
- game_mode_overworld = 0x0e,
- game_mode_level = 0x14,
- sprite_max = 12, -- maximum number of sprites
- }
- local RAM = {
- game_mode = 0x7e0100, --
- real_frame = 0x7e0013,
- effective_frame = 0x7e0014,
- RNG = 0x7e148d,
- current_level = 0x7e00fe, -- plus 1
- sprite_memory_header = 0x7e1692,
- lock_animation_flag = 0x7e009d, --Most codes will still run if this is set, but almost nothing will move or animate.
- -- cheats
- frozen = 0x7e13fb,
- level_paused = 0x7e13d4,
- level_index = 0x7e13bf,
- room_index = 0x7e00ce,
- level_flag_table = 0x7e1ea2,
- level_exit_type = 0x7e0dd5,
- midway_point = 0x7e13ce,
- -- Camera
- x_camera = 0x7e001a,
- y_camera = 0x7e001c,
- vertical_scroll = 0x7e1412, -- #$00 = Disable; #$01 = Enable; #$02 = Enable if flying/climbing/etc.
- -- Sprites
- sprite_status = 0x7e14c8,
- sprite_throw = 0x7e1504, --
- chuckHP = 0x7e1528, --
- sprite_stun = 0x7e1540,
- sprite_contact_mario = 0x7e154c,
- spriteContactSprite = 0x7e1564, --
- spriteContactoObject = 0x7e15dc, --
- sprite_number = 0x7e009e,
- sprite_x_high = 0x7e14e0,
- sprite_x_low = 0x7e00e4,
- sprite_y_high = 0x7e14d4,
- sprite_y_low = 0x7e00d8,
- sprite_x_sub = 0x7e14f8,
- sprite_y_sub = 0x7e14ec,
- sprite_x_speed = 0x7e00b6,
- sprite_y_speed = 0x7e00aa,
- sprite_x_offscreen = 0x7e15a0,
- sprite_y_offscreen = 0x7e186c,
- sprite_miscellaneous = 0x7e160e,
- sprite_tongue_length = 0x7e151c,
- sprite_tongue_timer = 0x7e1558,
- sprite_buoyancy = 0x7e190e,
- -- Player
- x = 0x7e0094,
- y = 0x7e0096,
- x_sub = 0x7e13da,
- y_sub = 0x7e13dc,
- x_speed = 0x7e007b,
- x_subspeed = 0x7e007a,
- y_speed = 0x7e007d,
- direction = 0x7e0076,
- is_ducking = 0x7e0073,
- p_meter = 0x7e13e4,
- take_off = 0x7e149f,
- powerup = 0x7e0019,
- cape_spin = 0x7e14a6,
- cape_fall = 0x7e14a5,
- flight_animation = 0x7e1407,
- diving_status = 0x7e1409,
- player_in_air = 0x7e0071,
- climbing_status = 0x7e0074,
- spinjump_flag = 0x7e140d,
- player_blocked_status = 0x7e0077,
- player_item = 0x7e0dc2, --hex
- cape_x = 0x7e13e9,
- cape_y = 0x7e13eb,
- on_ground = 0x7e13ef,
- can_jump_from_water = 0x7e13fa,
- carrying_item = 0x7e148f,
- mario_score = 0x7e0f34,
- -- Yoshi
- yoshi_riding_flag = 0x7e187a, -- #$00 = No, #$01 = Yes, #$02 = Yes, and turning around.
- -- Timer
- --keep_mode_active = 0x7e0db1,
- score_incrementing = 0x7e13d6,
- end_level_timer = 0x7e1493,
- multicoin_block_timer = 0x7e186b,
- gray_pow_timer = 0x7e14ae,
- blue_pow_timer = 0x7e14ad,
- dircoin_timer = 0x7e190c,
- pballoon_timer = 0x7e1891,
- star_timer = 0x7e1490,
- animation_timer = 0x7e1496,--
- invisibility_timer = 0x7e1497,
- fireflower_timer = 0x7e149b,
- yoshi_timer = 0x7e18e8,
- }
- -- ************
- -- COMPATIBILITY
- memory.readsbyte = memory.readbytesigned
- memory.readsword = memory.readwordsigned
- local Prev_mode = nil -- necessary, because only gui.register gets the correct RAM addresses without 1 frame delay
- -- ************
- local function get_game_mode()
- return memory.readbyte(RAM.game_mode)
- end
- local function player()
- -- Read RAM
- local x = memory.readsword(RAM.x)
- local y = memory.readsword(RAM.y)
- local x_speed = memory.readsbyte(RAM.x_speed)
- local x_sub = memory.readbyte(RAM.x_sub)
- local is_ducking = memory.readbyte(RAM.is_ducking)
- local powerup = memory.readbyte(RAM.powerup)
- local yoshi_riding_flag = memory.readbyte(RAM.yoshi_riding_flag)
- x_sub = math.floor(x_sub/0x10)
- -- Computes direction
- local direction
- if x_speed >= 0 then
- direction = 1
- else
- direction = 0
- end
- -- Computes hitbox size
- local is_small = is_ducking ~= 0 or powerup == 0
- local on_yoshi = yoshi_riding_flag ~= 0
- local hitbox_size
- if is_small and not on_yoshi then
- hitbox_size = 0
- elseif not is_small and not on_yoshi then
- hitbox_size = 1
- elseif is_small and on_yoshi then
- hitbox_size = 2
- else
- hitbox_size = 3
- end
- return x, x_sub, y, direction, hitbox_size
- end
- local function dump_info_level(room_index)
- local frame = emu.framecount() + 1
- local mode = get_game_mode()
- local real_frame = memory.readbyte(RAM.real_frame)
- if mode == SMW.game_mode_level then
- x, sub_x, y, direction, hitbox_size = player()
- else
- x, sub_x, y, direction, hitbox_size = 0, 0, 0, 0, 0
- end
- local is_lagged = real_frame == previous_real_frame
- if is_lagged then is_lagged = 1 else is_lagged = 0 end
- previous_real_frame = real_frame
- local sync = nil
- if mode == 0x14 and Prev_mode == 0x13 then sync = 0x13 end -- Prev_mode, due to delay
- local strline = string.format("%7d %2x %6x %1d %4d %x %4d %d %1d\n",
- frame, sync or mode, room_index, is_lagged, x, sub_x, y, direction, hitbox_size)
- io.write(strline)
- Prev_mode = mode
- return strline
- end
- emu.registerbefore(function()
- if not movie.playing() then gui.text(1, 16, "Put the movie in read-only mode")
- else
- local room_index = bit.lshift(memory.readbyte(RAM.room_index), 16) + bit.lshift(memory.readbyte(RAM.room_index + 1), 8) + memory.readbyte(RAM.room_index + 2)
- gui.text(1, 1, "RECORDING GHOST")
- dump_info_level(room_index)
- end
- end)
Add Comment
Please, Sign In to add comment