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
32 changes: 21 additions & 11 deletions HackSources/Ghosts/ghost_loop.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ NumRequestedGhosts equ 0x7FFF ; Offset from extended RAM start to the b
PointerToFirstGhost equ 0x7FF8 ; Offset from extended RAM start to the 4 byte pointer to the first ghost node
NegativeGhostStructSize equ 0xFF98 ; The negative size of a single ghost node, used to iterate ghosts like a reversed array
AnimationBufferSize equ 0x4000 ; The number of bytes reserved for animation data for each ghost
FirstAnimationBufferAddrHi equ 0x8050 ; The Hi part of the address pointing to the animation buffer used by the first ghost
FirstAnimationBufferAddrHi equ GhostBaseHi + 0x10 ; The Hi part of the address pointing to the animation buffer used by the first ghost
InitializedGhostsFlag equ 0x40 ; A custom bit flag that can be set on the Mario object, indicating whether the ghost hack is active

.n64
Expand Down Expand Up @@ -112,7 +112,7 @@ sll t1, RegProcessedGhostCount, 0xC
addu t0, t0, t1

GhostBaseHi_LUI_PLUS_1:
lui at, GhostBaseHi + 1
lui at, GhostBaseHi + 1 ; +1 because the addiu 0x9B00 below sign-extends; the pair lands at base + 0x9B00
addu t0, t0, at
addiu t0, t0, 0x9B00

Expand All @@ -126,30 +126,40 @@ sw t1, 0x24 (RegCurrentGhost)
lw t1, 0x08 (t0)
sw t1, 0x28 (RegCurrentGhost)

; angles (TODO: store angles as s16 in file?)
lw t1, 0x10 (t0)
; angles
lh t1, 0x10 (t0)
sh t1, 0x1A (RegCurrentGhost)
lw t1, 0x14 (t0)
lh t1, 0x12 (t0)
sh t1, 0x1C (RegCurrentGhost)
lw t1, 0x18 (t0)
lh t1, 0x14 (t0)
sh t1, 0x1E (RegCurrentGhost)

lw t1, 0x18 (t0) ; "graphics" in STROOP
lw t3, 0x0C (t0) ; "animation" in STROOP
bnez t1, @TREAT_AS_OBJECT
lh t2, 0x16 (t0) ; animation frame
; do the hacky thing with Mario animations
lui t8, 0x8037
sw RegCurrentGhost, 0x0580 (t8)
sw RegAnimationBuffer, 0x05C0 (t8)
lh t1, 0x1C (t0)
sh t1, 0x38 (SP)
sh t2, 0x38 (SP)
ori a0, t8, 0x04F8
sh r0, 0x38 (RegCurrentGhost)
sw r0, 0x05BC (t8)
jal set_mario_animation
lw a1, 0xC (t0)
lh t1, 0x38 (SP)
sh t1, 0x40 (RegCurrentGhost)
lh t2, 0x38 (SP)
lui t1, 0x800F
ori t1, t1, 0x0860
beq r0, r0, @COMMON_SETTERS
addiu RegAnimationBuffer, RegAnimationBuffer, AnimationBufferSize
@TREAT_AS_OBJECT:
sw t3, 0x3C (RegCurrentGhost)
@COMMON_SETTERS:
sw t1, 0x14 (RegCurrentGhost)
sh t2, 0x40 (RegCurrentGhost)

; move on to next ghost
addiu RegAnimationBuffer, RegAnimationBuffer, AnimationBufferSize
addiu RegPointerToCurrentGhost, RegPointerToCurrentGhost, NegativeGhostStructSize
addiu RegProcessedGhostCount, RegProcessedGhostCount, 0x1

Expand Down
4 changes: 2 additions & 2 deletions STROOP/Resources/Hacks/GhostHackJP.hck
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
8027ABD8: 0C 10 20 00

80408000: 27 BD FF C0 3C 08 80 36 8D 08 FD E8 10 08 00 6B AF BF 00 34 AF B4 00 30 AF B3 00 2C AF B2 00 28 AF B1 00 24 AF B0 00 20 00 08 A0 25 86 88 00 02 31 09 00 40 15 20 00 06 35 09 00 40 A6 89 00 02 10 00 00 58 3C 11 80 40 10 00 00 53 36 31 7F F8 3C 13 80 50 3C 18 80 37 34 01 00 BD A7 01 05 A8 37 01 05 B8 AF 01 05 98 3C 01 80 06 24 21 40 40 AF 01 05 B8 00 00 80 25 3C 01 80 40 34 31 7F F8 80 21 7F FF 10 01 00 44 00 00 00 00 8E 28 00 00 15 00 00 0E 00 00 20 25 26 25 FF 9C 8E 86 00 14 3C 07 80 38 34 E1 5F DC AF A1 00 10 34 E1 5F E4 AF A1 00 14 0C 0D EE 78 34 E7 5F D0 AE 22 00 00 8E 84 00 0C 0C 0D F0 11 00 40 28 25 8E 32 00 00 82 89 00 18 A2 49 00 18 8E 89 00 38 AE 49 00 38 3C 01 80 33 8C 28 C6 94 31 08 00 7F 00 08 41 40 00 10 4B 00 01 09 40 21 3C 01 80 41 01 01 40 21 25 08 9B 00 8D 09 00 00 AE 49 00 20 8D 09 00 04 AE 49 00 24 8D 09 00 08 AE 49 00 28 8D 09 00 10 A6 49 00 1A 8D 09 00 14 A6 49 00 1C 8D 09 00 18 A6 49 00 1E 3C 18 80 37 AF 12 05 80 AF 13 05 C0 85 09 00 1C A7 A9 00 38 37 04 04 F8 A6 40 00 38 AF 00 05 BC 0C 09 41 FA 8D 05 00 0C 87 A9 00 38 A6 49 00 40 26 73 40 00 26 31 FF 98 26 10 00 01 3C 01 80 40 80 21 7F FF 02 01 40 2B 15 00 FF C3 A2 50 00 60 8E 32 00 00 12 40 00 06 00 12 20 25 0C 0D F0 2F AE 20 00 00 8E 24 00 00 14 80 FF FC 26 31 FF 98 8F BF 00 34 8F B4 00 30 8F B3 00 2C 8F B2 00 28 8F B1 00 24 8F B0 00 20 03 E0 00 08 27 BD 00 40
80408000: 27 BD FF C0 3C 08 80 36 8D 08 FD E8 10 08 00 73 AF BF 00 34 AF B4 00 30 AF B3 00 2C AF B2 00 28 AF B1 00 24 AF B0 00 20 00 08 A0 25 86 88 00 02 31 09 00 40 15 20 00 06 35 09 00 40 A6 89 00 02 10 00 00 60 3C 11 80 40 10 00 00 5B 36 31 7F F8 3C 13 80 50 3C 18 80 37 34 01 00 BD A7 01 05 A8 37 01 05 B8 AF 01 05 98 3C 01 80 06 24 21 40 40 AF 01 05 B8 00 00 80 25 3C 01 80 40 34 31 7F F8 80 21 7F FF 10 01 00 4C 00 00 00 00 8E 28 00 00 15 00 00 0E 00 00 20 25 26 25 FF 9C 8E 86 00 14 3C 07 80 38 34 E1 5F DC AF A1 00 10 34 E1 5F E4 AF A1 00 14 0C 0D EE 78 34 E7 5F D0 AE 22 00 00 8E 84 00 0C 0C 0D F0 11 00 40 28 25 8E 32 00 00 82 89 00 18 A2 49 00 18 8E 89 00 38 AE 49 00 38 3C 01 80 33 8C 28 C6 94 31 08 00 7F 00 08 41 40 00 10 4B 00 01 09 40 21 3C 01 80 41 01 01 40 21 25 08 9B 00 8D 09 00 00 AE 49 00 20 8D 09 00 04 AE 49 00 24 8D 09 00 08 AE 49 00 28 85 09 00 10 A6 49 00 1A 85 09 00 12 A6 49 00 1C 85 09 00 14 A6 49 00 1E 8D 09 00 18 8D 0B 00 0C 15 20 00 0F 85 0A 00 16 3C 18 80 37 AF 12 05 80 AF 13 05 C0 A7 AA 00 38 37 04 04 F8 A6 40 00 38 AF 00 05 BC 0C 09 41 FA 8D 05 00 0C 87 AA 00 38 3C 09 80 0F 35 29 08 60 10 00 00 02 26 73 40 00 AE 4B 00 3C AE 49 00 14 A6 4A 00 40 26 31 FF 98 26 10 00 01 3C 01 80 40 80 21 7F FF 02 01 40 2B 15 00 FF BB A2 50 00 60 8E 32 00 00 12 40 00 06 00 12 20 25 0C 0D F0 2F AE 20 00 00 8E 24 00 00 14 80 FF FC 26 31 FF 98 8F BF 00 34 8F B4 00 30 8F B3 00 2C 8F B2 00 28 8F B1 00 24 8F B0 00 20 03 E0 00 08 27 BD 00 40

80408200: 27 BD FF C0 AF BF 00 14 3C 09 04 01 35 28 19 A0 3C 01 80 36 8C 21 FD E8 3C 18 80 33 8F 18 CF A0 13 01 00 02 00 00 50 25 83 0A 00 60 35 29 19 78 AF A8 00 18 AF A9 00 1C AF AA 00 20 24 01 00 01 14 24 00 1B 34 04 00 38 0C 09 E2 5F 00 00 00 00 3C 0C 06 00 AC 4C 00 10 8F A1 00 18 AC 41 00 14 3C 01 03 88 34 21 00 10 AC 41 00 18 AC 41 00 00 3C 08 80 40 35 08 83 00 8F A9 00 20 00 09 49 40 01 28 50 21 AC 4A 00 1C AC 4A 00 04 3C 01 03 86 34 21 00 10 AC 41 00 20 AC 41 00 08 25 4B 00 08 AC 4B 00 24 AC 4B 00 0C AC 4C 00 28 8F A8 00 1C AC 48 00 2C 3C 01 B8 00 AC 41 00 30 8F BF 00 14 03 E0 00 08 27 BD 00 40

Expand All @@ -10,4 +10,4 @@

80276AF4: 27 BD FF D0 AF BF 00 14 24 01 00 01 14 81 00 1A 00 00 10 25 00 A0 20 25 3C 08 80 34 25 08 A0 40 8C B8 00 18 00 18 C8 80 03 38 C8 21 00 19 C8 C0 03 28 48 21 3C 08 80 33 8D 08 CF A0 3C 01 80 36 8C 21 FD E8 15 01 00 06 85 2C 00 08 31 8D 01 00 11 A0 00 07 34 05 00 FF 10 00 00 05 31 85 00 FF 81 18 00 61 13 00 00 02 34 05 00 FF 34 05 00 7F 0C 09 DA 78 00 00 00 00 8F BF 00 14 03 E0 00 08 27 BD 00 30

80277128: 3C 08 80 33 8D 08 CF A0 3C 01 80 36 8C 21 FD E8 15 01 00 05 3C 19 80 34 87 2A A0 48 00 0A 52 02 10 00 00 03 A4 AA 00 1E 81 0A 00 61 A4 AA 00 1E 03 E0 00 08 00 00 10 25
80277128: 3C 08 80 33 8D 08 CF A0 3C 01 80 36 8C 21 FD E8 15 01 00 05 3C 19 80 34 87 2A A0 48 00 0A 52 02 10 00 00 03 A4 AA 00 1E 81 0A 00 61 A4 AA 00 1E 03 E0 00 08 00 00 10 25
2 changes: 1 addition & 1 deletion STROOP/Resources/Hacks/GhostHackUS.hck
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
8027B188: 0C 10 20 00

80408000: 27 BD FF C0 3C 08 80 36 8D 08 11 58 10 08 00 6B AF BF 00 34 AF B4 00 30 AF B3 00 2C AF B2 00 28 AF B1 00 24 AF B0 00 20 00 08 A0 25 86 88 00 02 31 09 00 40 15 20 00 06 35 09 00 40 A6 89 00 02 10 00 00 58 3C 11 80 40 10 00 00 53 36 31 7F F8 3C 13 80 50 3C 18 80 37 34 01 00 BD A7 01 05 A8 37 01 05 B8 AF 01 05 98 3C 01 80 06 24 21 40 40 AF 01 05 B8 00 00 80 25 3C 01 80 40 34 31 7F F8 80 21 7F FF 10 01 00 44 00 00 00 00 8E 28 00 00 15 00 00 0E 00 00 20 25 26 25 FF 9C 8E 86 00 14 3C 07 80 38 34 E1 5F DC AF A1 00 10 34 E1 5F E4 AF A1 00 14 0C 0D EE 78 34 E7 5F D0 AE 22 00 00 8E 84 00 0C 0C 0D F0 11 00 40 28 25 8E 32 00 00 82 89 00 18 A2 49 00 18 8E 89 00 38 AE 49 00 38 3C 01 80 33 8C 28 D5 D4 31 08 00 7F 00 08 41 40 00 10 4B 00 01 09 40 21 3C 01 80 41 01 01 40 21 25 08 9B 00 8D 09 00 00 AE 49 00 20 8D 09 00 04 AE 49 00 24 8D 09 00 08 AE 49 00 28 8D 09 00 10 A6 49 00 1A 8D 09 00 14 A6 49 00 1C 8D 09 00 18 A6 49 00 1E 3C 18 80 37 AF 12 05 80 AF 13 05 C0 85 09 00 1C A7 A9 00 38 37 04 04 F8 A6 40 00 38 AF 00 05 BC 0C 09 42 6E 8D 05 00 0C 87 A9 00 38 A6 49 00 40 26 73 40 00 26 31 FF 98 26 10 00 01 3C 01 80 40 80 21 7F FF 02 01 40 2B 15 00 FF C3 A2 50 00 60 8E 32 00 00 12 40 00 06 00 12 20 25 0C 0D F0 2F AE 20 00 00 8E 24 00 00 14 80 FF FC 26 31 FF 98 8F BF 00 34 8F B4 00 30 8F B3 00 2C 8F B2 00 28 8F B1 00 24 8F B0 00 20 03 E0 00 08 27 BD 00 40
80408000: 27 BD FF C0 3C 08 80 36 8D 08 11 58 10 08 00 73 AF BF 00 34 AF B4 00 30 AF B3 00 2C AF B2 00 28 AF B1 00 24 AF B0 00 20 00 08 A0 25 86 88 00 02 31 09 00 40 15 20 00 06 35 09 00 40 A6 89 00 02 10 00 00 60 3C 11 80 40 10 00 00 5B 36 31 7F F8 3C 13 80 50 3C 18 80 37 34 01 00 BD A7 01 05 A8 37 01 05 B8 AF 01 05 98 3C 01 80 06 24 21 40 40 AF 01 05 B8 00 00 80 25 3C 01 80 40 34 31 7F F8 80 21 7F FF 10 01 00 4C 00 00 00 00 8E 28 00 00 15 00 00 0E 00 00 20 25 26 25 FF 9C 8E 86 00 14 3C 07 80 38 34 E1 5F DC AF A1 00 10 34 E1 5F E4 AF A1 00 14 0C 0D EE 78 34 E7 5F D0 AE 22 00 00 8E 84 00 0C 0C 0D F0 11 00 40 28 25 8E 32 00 00 82 89 00 18 A2 49 00 18 8E 89 00 38 AE 49 00 38 3C 01 80 33 8C 28 D5 D4 31 08 00 7F 00 08 41 40 00 10 4B 00 01 09 40 21 3C 01 80 41 01 01 40 21 25 08 9B 00 8D 09 00 00 AE 49 00 20 8D 09 00 04 AE 49 00 24 8D 09 00 08 AE 49 00 28 85 09 00 10 A6 49 00 1A 85 09 00 12 A6 49 00 1C 85 09 00 14 A6 49 00 1E 8D 09 00 18 8D 0B 00 0C 15 20 00 0F 85 0A 00 16 3C 18 80 37 AF 12 05 80 AF 13 05 C0 A7 AA 00 38 37 04 04 F8 A6 40 00 38 AF 00 05 BC 0C 09 42 6E 8D 05 00 0C 87 AA 00 38 3C 09 80 0F 35 29 08 60 10 00 00 02 26 73 40 00 AE 4B 00 3C AE 49 00 14 A6 4A 00 40 26 31 FF 98 26 10 00 01 3C 01 80 40 80 21 7F FF 02 01 40 2B 15 00 FF BB A2 50 00 60 8E 32 00 00 12 40 00 06 00 12 20 25 0C 0D F0 2F AE 20 00 00 8E 24 00 00 14 80 FF FC 26 31 FF 98 8F BF 00 34 8F B4 00 30 8F B3 00 2C 8F B2 00 28 8F B1 00 24 8F B0 00 20 03 E0 00 08 27 BD 00 40

80408200: 27 BD FF C0 AF BF 00 14 3C 09 04 01 35 28 19 A0 3C 01 80 36 8C 21 11 58 3C 18 80 33 8F 18 DF 00 13 01 00 02 00 00 50 25 83 0A 00 60 35 29 19 78 AF A8 00 18 AF A9 00 1C AF AA 00 20 24 01 00 01 14 24 00 1B 34 04 00 38 0C 09 E3 CB 00 00 00 00 3C 0C 06 00 AC 4C 00 10 8F A1 00 18 AC 41 00 14 3C 01 03 88 34 21 00 10 AC 41 00 18 AC 41 00 00 3C 08 80 40 35 08 83 00 8F A9 00 20 00 09 49 40 01 28 50 21 AC 4A 00 1C AC 4A 00 04 3C 01 03 86 34 21 00 10 AC 41 00 20 AC 41 00 08 25 4B 00 08 AC 4B 00 24 AC 4B 00 0C AC 4C 00 28 8F A8 00 1C AC 48 00 2C 3C 01 B8 00 AC 41 00 30 8F BF 00 14 03 E0 00 08 27 BD 00 40

Expand Down
51 changes: 45 additions & 6 deletions STROOP/Tabs/GhostTab/Ghost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ public GhostPositionAngle(Ghost g) : base()
public void SetGlobalTimer(uint globalTimer)
{
GhostFrame newFrame;
if (g.playbackFrames.TryGetValue(globalTimer, out newFrame))
if (g.frames.TryGetValue(globalTimer, out newFrame))
currentFrame = newFrame;
}

public override Vector4 GetArrowColor(Vector4 baseColor) => color;
}

public record struct PlaybackFrame(GhostFrame frame, uint animation);

const uint OBJECT_EXTRA_MAGIC = 0x4F424A54;

public uint playbackBaseFrame = 0;
public Dictionary<uint, GhostFrame> playbackFrames = new Dictionary<uint, GhostFrame>();
public GhostFrame lastValidPlaybackFrame, currentFrame;
public Dictionary<uint, GhostFrame> frames = new Dictionary<uint, GhostFrame>();
public PlaybackFrame lastValidPlaybackFrame;
public GhostFrame currentFrame;
public uint originalPlaybackBaseFrame { get; private set; }
public uint maxFrame { get; private set; }
public uint numFrames => maxFrame + 1;
Expand All @@ -53,15 +58,19 @@ public void SetGlobalTimer(uint globalTimer)
public GhostPositionAngle positionAngle { get; private set; }
public bool transparent = true;

/// <summary> The graphics pointer to pass to the hack - 0 is interpreted as "Mario" by the hack. </summary>
public uint nonMarioGraphics = 0;
public Dictionary<uint, uint> animationSwitches = new();

public Ghost()
{
positionAngle = new GhostPositionAngle(this);
}

public Ghost(uint playbackBaseFrame, Dictionary<uint, GhostFrame> playbackFrames)
public Ghost(uint playbackBaseFrame, Dictionary<uint, GhostFrame> frames)
{
this.playbackBaseFrame = originalPlaybackBaseFrame = playbackBaseFrame;
this.playbackFrames = playbackFrames;
this.frames = frames;
}

public static Ghost FromFile(BinaryReader reader)
Expand All @@ -75,9 +84,21 @@ public static Ghost FromFile(BinaryReader reader)
{
var index = reader.ReadUInt32();
var frame = GhostFrame.ReadFrom(reader);
result.playbackFrames[index] = frame;
result.frames[index] = frame;
result.maxFrame = Math.Max(result.maxFrame, index);
}

if (reader.BaseStream.Position > reader.BaseStream.Length - 4 || reader.ReadUInt32() != OBJECT_EXTRA_MAGIC)
return result;

result.nonMarioGraphics = reader.ReadUInt32();
var numAnimationSwitches = reader.ReadUInt32();
for (int i = 0; i < numAnimationSwitches; i++)
{
var key = reader.ReadUInt32();
var value = reader.ReadUInt32();
result.animationSwitches[key] = value;
}
}
catch (IOException)
{
Expand All @@ -86,6 +107,24 @@ public static Ghost FromFile(BinaryReader reader)

return result;
}
public void ToFile(BinaryWriter wr)
{
wr.Write(originalPlaybackBaseFrame);
wr.Write(frames.Count);
foreach (var frame in frames)
{
wr.Write(frame.Key);
frame.Value.WriteTo(wr);
}

wr.Write(OBJECT_EXTRA_MAGIC);
wr.Write(animationSwitches.Count);
foreach (var kvp in animationSwitches)
{
wr.Write(kvp.Key);
wr.Write(kvp.Value);
}
}

public override string ToString()
{
Expand Down
Loading
Loading