Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions src/core/Ghost.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
-- SPDX-License-Identifier: GPL-2.0-or-later
--

Ghost = {}
Ghost = {
object_address = 0
}

---@class GhostFrame
---@field global_timer integer
Expand All @@ -24,8 +26,14 @@ local frame = 0
local recording_base_frame = nil
local last_global_timer = nil

local OBJECT_EXTRA_MAGIC <const> = 0x4F424A54
local non_mario_graphics = nil
local animation_switches = { }
local last_recorded_animation = nil

local OBJ_POSITION_OFFSET <const> = 0x20
local OBJ_ANIMATION_OFFSET <const> = 0x38
local OBJ_ANIMATION_ID_OFFSET <const> = 0x38
local OBJ_ANIMATION_OFFSET <const> = 0x3C
local OBJ_ANIMATION_TIMER_OFFSET <const> = 0x40
local OBJ_PITCH_OFFSET <const> = 0x1A
local OBJ_YAW_OFFSET <const> = 0x1C
Expand Down Expand Up @@ -82,6 +90,18 @@ local function flush()
writebytes32(file, value.roll)
end

if non_mario_graphics then
writebytes32(file, OBJECT_EXTRA_MAGIC)
writebytes32(file, non_mario_graphics)
local count = 0
for _ in pairs(animation_switches) do count = count + 1 end
writebytes32(file, count)
for k, v in pairs(animation_switches) do
writebytes32(file, k)
writebytes32(file, v)
end
end

file:close()

return true
Expand All @@ -99,7 +119,7 @@ function Ghost.update()
end

local address_source = Addresses[Settings.address_source_index]
local mario_obj = memory.readdword(address_source.mario_object_pointer)
local mario_obj = Ghost.object_address or memory.readdword(address_source.mario_object_pointer)
local global_timer = memory.readdword(address_source.global_timer)

if recording_base_frame == nil then
Expand All @@ -116,9 +136,15 @@ function Ghost.update()
x = memory.readdword(mario_obj + OBJ_POSITION_OFFSET),
y = memory.readdword(mario_obj + OBJ_POSITION_OFFSET + 4),
z = memory.readdword(mario_obj + OBJ_POSITION_OFFSET + 8),
animation_index = memory.readword(mario_obj + OBJ_ANIMATION_OFFSET),
animation_index = memory.readword(mario_obj + OBJ_ANIMATION_ID_OFFSET),
animation_timer = memory.readword(mario_obj + OBJ_ANIMATION_TIMER_OFFSET) - 1,
}

local animation = memory.readdword(mario_obj + OBJ_ANIMATION_OFFSET)
if animation ~= last_recorded_animation then
last_recorded_animation = animation
animation_switches[#frames - 1] = animation
end
end
end

Expand Down Expand Up @@ -153,6 +179,8 @@ function Ghost.start_recording()
end

is_recording = true
non_mario_graphics = Ghost.object_address and memory.readdword(Ghost.object_address + 0x14) or 0
last_recorded_animation = nil

return true
end
Expand Down
1 change: 1 addition & 0 deletions src/core/Locales.lua
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ Locales = {}
---@field public TOOLS_RNG_USE_INDEX string
---@field public TOOLS_DUMPING string
---@field public TOOLS_GHOST string
---@field public TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP string
---@field public TOOLS_GHOST_START string
---@field public TOOLS_GHOST_STOP string
---@field public TOOLS_GHOST_START_RECORDING_FAILED string
Expand Down
1 change: 1 addition & 0 deletions src/res/lang/en_US.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ This action cannot be undone.
TOOLS_RNG_USE_INDEX = 'Use Index',
TOOLS_DUMPING = 'Dumping',
TOOLS_GHOST = 'Ghost',
TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP = 'Address of the object to record (e.g. 8033FF48). If 0, Mario is recorded.',
TOOLS_GHOST_START = 'Start Recording',
TOOLS_GHOST_STOP = 'Stop Recording',
TOOLS_GHOST_START_RECORDING_FAILED = 'Failed to start ghost recording.',
Expand Down
1 change: 1 addition & 0 deletions src/res/lang/fr_FR.lua
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ Cette action est irréversible.
TOOLS_DUMPING = 'Export',
TOOLS_EXPERIMENTS = 'Expériences',
TOOLS_GHOST = 'Fantôme',
TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP = 'Adresse de l’objet à enregistrer (par exemple 8033FF48). Si 0, Mario est enregistré.',
TOOLS_GHOST_START = 'Démarrer rec.',
TOOLS_GHOST_STOP = 'Arrêter rec.',
TOOLS_GHOST_START_RECORDING_FAILED = 'Échec du démarrage de l\'enregistrement fantôme.',
Expand Down
8 changes: 8 additions & 0 deletions src/views/Tools.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ local UID = UIDProvider.allocate_once('Tools', function(enum_next)
RngUse = enum_next(),
RngValue = enum_next(4),
Dump = enum_next(),
GhostObjectAddress = enum_next(),
RecordGhost = enum_next(),
WorldVisualizer = enum_next(),
AutoFirsties = enum_next(),
Expand Down Expand Up @@ -114,6 +115,13 @@ return {
align_y = BreitbandGraphics.alignment.center,
})

Ghost.object_address = tonumber(ugui.textbox({
uid = UID.GhostObjectAddress,
rectangle = grid_rect(4, GHOST_ROW, 4, 1),
text = string.format("%x", Ghost.object_address or 0),
tooltip = Locales.str('TOOLS_GHOST_OBJECT_ADDRESS_TOOL_TIP')
}):gsub("[^%x]", ""), 16)

if ugui.button({
uid = UID.RecordGhost,
rectangle = grid_rect(0, GHOST_ROW, 4, 1),
Expand Down