Altimor
Smash Rookie
- Joined
- Feb 26, 2017
- Messages
- 10
From traditional fighting game terminology, a reversal is an action performed immediately after regaining control from knockdown, hitstun, or blockstun.
Z+Dpad down: Start reversal recording. You will take control of the CPU and be able to record up to 40 frames. Recording starts from your first input.
Z+Dpad up: Clear recording.
Z+Dpad right: Toggle force shield.
Z+Dpad left: Toggle force crouch.
$Advanced CPU Control [Altimor]
C206B02C 0000008D
4800000D 48000098
00000000 7C6802A6
90610004 9421FFF8
80630004 2C030000
4082003C 3C008037
6000F1E4 7C0803A6
386003FC 4E800021
80A1000C 90650004
38A00000 38000000
7C832A14 90040000
38A50004 2C0503FC
4180FFF0 7C651B78
8001000C 38210008
7C0803A6 4E800020
38600000 907F0620
907F0624 907F0638
907F063C 907F0650
907F065C 4E800020
2C040000 40820134
4E800020 7FE3FB78
3C00800A 60002040
7C0803A6 4E800021
2C030000 40820180
809F065C 2C040014
40820018 38600001
9065000C 887E006C
9065001C 4800037C
2C040018 40820010
38600000 90650038
48000368 88DE006C
1CC60004 7CC62A14
80660028 70630012
2C030012 41820018
2C040012 40820010
80650020 68630001
90650020 80660028
70630011 2C030011
41820018 2C040011
40820010 80650024
68630001 90650024
90860028 80C5001C
887E006C 7C033000
40820300 8065000C
2C030001 40820020
2C040000 408202EC
38600001 90650010
38600000 90650014
9065000C 80650010
2C030001 408202CC
80650014 2C030000
41810040 809F0620
4BFFFEF9 809F0624
4BFFFEF1 809F0638
4BFFFEE9 809F063C
4BFFFEE1 809F0650
4BFFFED9 809F065C
4BFFFED1 4800028C
38600001 90650038
80650014 1C630018
3863003C 7C651A14
C03F0620 D0230000
C03F0624 D0230004
C03F0638 D0230008
C03F063C D023000C
C03F0650 D0230010
809F065C 90830014
4BFFFE61 80650014
38630001 2C030028
4082000C 38600000
90650010 90650014
48000220 80650014
2C030000 4182005C
2C030001 4182000C
C01F002C D0050018
80650014 3863FFFF
1C630018 3863003C
7C651A14 C0230000
D03F0620 C0230004
D03F0624 C0230008
D03F0638 C023000C
D03F063C C0230010
D03F0650 80830014
909F065C 480001BC
80850010 2C040001
4082000C 4BFFFDCD
480001A8 809F0010
2C04000E 41820038
2C040027 41820030
2C040028 41820028
2C0400B2 41820020
2C0400B3 41820018
2C0400B5 41820010
2C0400B6 41820008
40820038 80650020
2C030001 40820014
4BFFFD79 38600040
907F065C 4800001C
80650024 2C030001
40820010 4BFFFD5D
3C60BF80 907F0624
80650038 2C030001
40820128 2C0400B5
41820014 2C04004B
41800020 2C04005B
41810018 38600001
90650000 38600000
90650004 480000FC
80650000 2C030001
408200F0 80650004
2C030000 4181005C
2C040026 4182004C
2C04000E 41820044
2C0400B3 4182003C
2C04002A 40820024
809E002C C0240894
C00401F4 FC010040
41800010 80042340
2C000000 40820014
809E002C 88042218
5400CFFF 41820094
C01F002C D0050008
80650004 1C630018
3863003C 7C651A14
C0230000 C0050008
FC210032 C0050018
FC210032 D03F0620
C0230004 D03F0624
C0230008 D03F0638
C023000C D03F063C
C0230010 D03F0650
80830014 807F0010
2C0300B3 40820014
80650004 2C030000
40820008 60840040
909F065C 80650004
38630001 2C030028
4082000C 38600000
90650000 90650004
3C008016 6000B0FC
7C0803A6 4E800021
60000000 00000000
*Control with Z+Dpad
C206B02C 0000008D
4800000D 48000098
00000000 7C6802A6
90610004 9421FFF8
80630004 2C030000
4082003C 3C008037
6000F1E4 7C0803A6
386003FC 4E800021
80A1000C 90650004
38A00000 38000000
7C832A14 90040000
38A50004 2C0503FC
4180FFF0 7C651B78
8001000C 38210008
7C0803A6 4E800020
38600000 907F0620
907F0624 907F0638
907F063C 907F0650
907F065C 4E800020
2C040000 40820134
4E800020 7FE3FB78
3C00800A 60002040
7C0803A6 4E800021
2C030000 40820180
809F065C 2C040014
40820018 38600001
9065000C 887E006C
9065001C 4800037C
2C040018 40820010
38600000 90650038
48000368 88DE006C
1CC60004 7CC62A14
80660028 70630012
2C030012 41820018
2C040012 40820010
80650020 68630001
90650020 80660028
70630011 2C030011
41820018 2C040011
40820010 80650024
68630001 90650024
90860028 80C5001C
887E006C 7C033000
40820300 8065000C
2C030001 40820020
2C040000 408202EC
38600001 90650010
38600000 90650014
9065000C 80650010
2C030001 408202CC
80650014 2C030000
41810040 809F0620
4BFFFEF9 809F0624
4BFFFEF1 809F0638
4BFFFEE9 809F063C
4BFFFEE1 809F0650
4BFFFED9 809F065C
4BFFFED1 4800028C
38600001 90650038
80650014 1C630018
3863003C 7C651A14
C03F0620 D0230000
C03F0624 D0230004
C03F0638 D0230008
C03F063C D023000C
C03F0650 D0230010
809F065C 90830014
4BFFFE61 80650014
38630001 2C030028
4082000C 38600000
90650010 90650014
48000220 80650014
2C030000 4182005C
2C030001 4182000C
C01F002C D0050018
80650014 3863FFFF
1C630018 3863003C
7C651A14 C0230000
D03F0620 C0230004
D03F0624 C0230008
D03F0638 C023000C
D03F063C C0230010
D03F0650 80830014
909F065C 480001BC
80850010 2C040001
4082000C 4BFFFDCD
480001A8 809F0010
2C04000E 41820038
2C040027 41820030
2C040028 41820028
2C0400B2 41820020
2C0400B3 41820018
2C0400B5 41820010
2C0400B6 41820008
40820038 80650020
2C030001 40820014
4BFFFD79 38600040
907F065C 4800001C
80650024 2C030001
40820010 4BFFFD5D
3C60BF80 907F0624
80650038 2C030001
40820128 2C0400B5
41820014 2C04004B
41800020 2C04005B
41810018 38600001
90650000 38600000
90650004 480000FC
80650000 2C030001
408200F0 80650004
2C030000 4181005C
2C040026 4182004C
2C04000E 41820044
2C0400B3 4182003C
2C04002A 40820024
809E002C C0240894
C00401F4 FC010040
41800010 80042340
2C000000 40820014
809E002C 88042218
5400CFFF 41820094
C01F002C D0050008
80650004 1C630018
3863003C 7C651A14
C0230000 C0050008
FC210032 C0050018
FC210032 D03F0620
C0230004 D03F0624
C0230008 D03F0638
C023000C D03F063C
C0230010 D03F0650
80830014 807F0010
2C0300B3 40820014
80650004 2C030000
40820008 60840040
909F065C 80650004
38630001 2C030028
4082000C 38600000
90650000 90650004
3C008016 6000B0FC
7C0803A6 4E800021
60000000 00000000
*Control with Z+Dpad
Code:
# 8006B02C - PlayerThink_ControllerInputsToDataOffset, after buttons are set
bl get_data
b start
.set OFFSET_PLAYING, 0
.set OFFSET_PLAY_FRAME, 4
.set OFFSET_PLAY_DIR, 8
.set OFFSET_RECORD_ON_RELEASE, 12
.set OFFSET_RECORDING, 16
.set OFFSET_RECORD_FRAME, 20
.set OFFSET_RECORD_DIR, 24
.set OFFSET_RECORD_PORT, 28
.set OFFSET_SHIELD, 32
.set OFFSET_CROUCH, 36
.set OFFSET_LAST_BUTTONS, 40
.set OFFSET_REVERSAL_ENABLED, 56
.set OFFSET_RECORDING_BUF, 60
.set RECORDING_FRAME_SIZE, 24 # joystick X+Y, cstick X+Y, L/R, Buttons, 4 bytes each
.set RECORDING_FRAME_COUNT, 40
.set DATA_SIZE, OFFSET_RECORDING_BUF + RECORDING_FRAME_SIZE * RECORDING_FRAME_COUNT
.space 4 # Pointer to data on heap
.align 2
# Store pointer to data in r5
get_data:
mflr r3
stw r3, 4(r1)
stwu r1, -8(r1)
lwz r3, 4(r3)
cmpwi r3, 0
bne initialized
# Call #_HSD_MemAlloc
lis r0, 0x8037
ori r0, r0, 0xF1E4
mtlr r0
li r3, DATA_SIZE
blrl
# Store in data pointer
lwz r5, 12(r1)
stw r3, 4(r5)
# Fill with zeroes
li r5, 0
li r0, 0
memset_loop:
add r4, r3, r5
stw r0, 0(r4)
addi r5, r5, 4
cmpwi r5, DATA_SIZE
blt memset_loop
initialized:
mr r5, r3
lwz r0, 12(r1)
addi r1, r1, 8
mtlr r0
blr
zero_inputs:
li r3, 0
stw r3, 0x620(r31)
stw r3, 0x624(r31)
stw r3, 0x638(r31)
stw r3, 0x63C(r31)
stw r3, 0x650(r31)
stw r3, 0x65C(r31)
blr
# Function to check if the recording should start (saves space)
check_input:
cmpwi r4, 0
bne recording_start
blr
start:
# Check DataOffset_HumanOrCPUCheck_0ForHuman
mr r3, r31
lis r0, 0x800A
ori r0, r0, 0x2040
mtlr r0
blrl
cmpwi r3, 0
bne cpu
# Check for Z+dpad down to start recording
lwz r4, 0x65C(r31)
cmpwi r4, 0x14
bne no_recording_input
li r3, 1
stw r3, OFFSET_RECORD_ON_RELEASE(r5)
lbz r3, 0x6C(r30)
stw r3, OFFSET_RECORD_PORT(r5)
b end
no_recording_input:
# Check for Z+dpad up to clear recording
cmpwi r4, 0x18
bne no_clear_input
li r3, 0
stw r3, OFFSET_REVERSAL_ENABLED(r5)
b end
no_clear_input:
# r6 = r5 + port * 4, for acccessing last buttons
lbz r6, 0x6C(r30)
mulli r6, r6, 4
add r6, r6, r5
# Check for Z+dpad right to toggle CPU shield
lwz r3, OFFSET_LAST_BUTTONS(r6)
andi. r3, r3, 0x12
cmpwi r3, 0x12
beq no_toggle_shield_input
cmpwi r4, 0x12
bne no_toggle_shield_input
lwz r3, OFFSET_SHIELD(r5)
xori r3, r3, 1
stw r3, OFFSET_SHIELD(r5)
no_toggle_shield_input:
# Check for Z+dpad left to toggle CPU crouch
lwz r3, OFFSET_LAST_BUTTONS(r6)
andi. r3, r3, 0x11
cmpwi r3, 0x11
beq no_toggle_crouch_input
cmpwi r4, 0x11
bne no_toggle_crouch_input
lwz r3, OFFSET_CROUCH(r5)
xori r3, r3, 1
stw r3, OFFSET_CROUCH(r5)
no_toggle_crouch_input:
# Store buttons
stw r4, OFFSET_LAST_BUTTONS(r6)
# Check that this is the port that started the recording
lwz r6, OFFSET_RECORD_PORT(r5)
lbz r3, 0x6C(r30)
cmpw r3, r6
bne end
# Check if recording on release of buttons
lwz r3, OFFSET_RECORD_ON_RELEASE(r5)
cmpwi r3, 1
bne no_record_on_release
cmpwi r4, 0
bne end
li r3, 1
stw r3, OFFSET_RECORDING(r5)
li r3, 0
stw r3, OFFSET_RECORD_FRAME(r5)
stw r3, OFFSET_RECORD_ON_RELEASE(r5)
no_record_on_release:
# Check if recording
lwz r3, OFFSET_RECORDING(r5)
cmpwi r3, 1
bne end
# Check if recording has already started
lwz r3, OFFSET_RECORD_FRAME(r5)
cmpwi r3, 0
bgt recording
# Wait until input is received to record the first frame
lwz r4, 0x620(r31) # Joystick X
bl check_input
lwz r4, 0x624(r31) # Joystick Y
bl check_input
lwz r4, 0x638(r31) # CStick X
bl check_input
lwz r4, 0x63C(r31) # CStick Y
bl check_input
lwz r4, 0x650(r31) # L/R
bl check_input
lwz r4, 0x65C(r31) # Buttons
bl check_input
b end
recording_start:
li r3, 1
stw r3, OFFSET_REVERSAL_ENABLED(r5)
recording:
# Write to reversal recording
lwz r3, OFFSET_RECORD_FRAME(r5)
mulli r3, r3, RECORDING_FRAME_SIZE
addi r3, r3, OFFSET_RECORDING_BUF
add r3, r5, r3
lfs f1, 0x620(r31) # Joystick X
stfs f1, 0(r3)
lfs f1, 0x624(r31) # Joystick Y
stfs f1, 4(r3)
lfs f1, 0x638(r31) # CStick X
stfs f1, 8(r3)
lfs f1, 0x63C(r31) # CStick Y
stfs f1, 12(r3)
lfs f1, 0x650(r31) # L/R
stfs f1, 16(r3)
lwz r4, 0x65C(r31) # Buttons
stw r4, 20(r3)
# Zero them out so only CPU moves
bl zero_inputs
# Increment frame counter
lwz r3, OFFSET_RECORD_FRAME(r5)
addi r3, r3, 1
# Check if recording is complete
cmpwi r3, RECORDING_FRAME_COUNT
bne continue_recording
li r3, 0
stw r3, OFFSET_RECORDING(r5)
continue_recording:
stw r3, OFFSET_RECORD_FRAME(r5)
b end
cpu:
# Use inputs that are currently being recorded
lwz r3, OFFSET_RECORD_FRAME(r5)
cmpwi r3, 0
beq recording_not_started
cmpwi r3, 1
beq after_first_frame
# Store direction
lfs f0, 0x2C(r31)
stfs f0, OFFSET_RECORD_DIR(r5)
after_first_frame:
lwz r3, OFFSET_RECORD_FRAME(r5)
subi r3, r3, 1 # Current frame index hasn't been written yet
mulli r3, r3, RECORDING_FRAME_SIZE
addi r3, r3, OFFSET_RECORDING_BUF
add r3, r5, r3
lfs f1, 0(r3) # Joystick X
stfs f1, 0x620(r31)
lfs f1, 4(r3) # Joystick Y
stfs f1, 0x624(r31)
lfs f1, 8(r3) # CStick X
stfs f1, 0x638(r31)
lfs f1, 12(r3) # CStick Y
stfs f1, 0x63C(r31)
lfs f1, 16(r3) # L/R
stfs f1, 0x650(r31)
lwz r4, 20(r3) # Buttons
stw r4, 0x65C(r31)
b end
recording_not_started:
# Stop inputting things if getting ready to record
lwz r4, OFFSET_RECORDING(r5)
cmpwi r4, 1
bne recording_not_pending
bl zero_inputs
b end
recording_not_pending:
# Animation state
lwz r4, 0x10(r31)
cmpwi r4, 0x0E # Wait
beq check_shield
cmpwi r4, 0x27 # Squat
beq check_shield
cmpwi r4, 0x28 # SquatWait
beq check_shield
cmpwi r4, 0xB2 # GuardOn
beq check_shield
cmpwi r4, 0xB3 # Guard
beq check_shield
cmpwi r4, 0xB5 # GuardSetOff
beq check_shield
cmpwi r4, 0xB6 # GuardReflect
beq check_shield
bne no_crouch
check_shield:
# Set shield
lwz r3, OFFSET_SHIELD(r5)
cmpwi r3, 1
bne no_shield
bl zero_inputs
li r3, 0x40
stw r3, 0x65C(r31)
b no_crouch
no_shield:
# Set crouch
lwz r3, OFFSET_CROUCH(r5)
cmpwi r3, 1
bne no_crouch
bl zero_inputs
lis r3, 0xBF80 # -1.0
stw r3, 0x624(r31)
no_crouch:
# Check if reversals are enabled
lwz r3, OFFSET_REVERSAL_ENABLED(r5)
cmpwi r3, 1
bne end
# Start reversal playback if in damage state
cmpwi r4, 0xB5 # GuardSetOff
beq hit
cmpwi r4, 0x4B
blt no_hit
cmpwi r4, 0x5B
bgt no_hit
hit:
li r3, 1
stw r3, OFFSET_PLAYING(r5)
li r3, 0
stw r3, OFFSET_PLAY_FRAME(r5)
b end
no_hit:
# Check that a reversal should be played back
lwz r3, OFFSET_PLAYING(r5)
cmpwi r3, 1
bne end
# Check if playback has already started
lwz r3, OFFSET_PLAY_FRAME(r5)
cmpwi r3, 0
bgt playback
# Check for neutral state
cmpwi r4, 0x26 # DamageFall
beq playback_start
cmpwi r4, 0x0E # Wait
beq playback_start
cmpwi r4, 0xB3 # Guard
beq playback_start
# Landing
cmpwi r4, 0x2A
bne iasa
lwz r4, 0x2C(r30)
lfs f1, 0x894(r4)
lfs f0, 0x1F4(r4)
fcmpo cr0, f1, f0
blt iasa
lwz r0, 0x2340(r4)
cmpwi r0, 0
bne playback_start
# Other IASA
iasa:
lwz r4, 0x2C(r30)
lbz r0, 0x2218(r4)
extrwi. r0, r0, 1, 24
beq end
playback_start:
# Store direction
lfs f0, 0x2C(r31)
stfs f0, OFFSET_PLAY_DIR(r5)
playback:
# Read from reversal recording
lwz r3, OFFSET_PLAY_FRAME(r5)
mulli r3, r3, RECORDING_FRAME_SIZE
addi r3, r3, OFFSET_RECORDING_BUF
add r3, r5, r3
lfs f1, 0(r3) # Joystick X
lfs f0, OFFSET_PLAY_DIR(r5)
fmul f1, f1, f0
lfs f0, OFFSET_RECORD_DIR(r5)
fmul f1, f1, f0
stfs f1, 0x620(r31)
lfs f1, 4(r3) # Joystick Y
stfs f1, 0x624(r31)
lfs f1, 8(r3) # CStick X
stfs f1, 0x638(r31)
lfs f1, 12(r3) # CStick Y
stfs f1, 0x63C(r31)
lfs f1, 16(r3) # L/R
stfs f1, 0x650(r31)
lwz r4, 20(r3) # Buttons
# Hold shield for the first frame of an OOS reversal
lwz r3, 0x10(r31)
cmpwi r3, 0xB3 # Guard
bne no_oos
lwz r3, OFFSET_PLAY_FRAME(r5)
cmpwi r3, 0
bne no_oos
ori r4, r4, 0x40
no_oos:
stw r4, 0x65C(r31)
# Increment frame counter
lwz r3, OFFSET_PLAY_FRAME(r5)
addi r3, r3, 1
# Check if playback is complete
cmpwi r3, RECORDING_FRAME_COUNT
bne continue_playback
li r3, 0
stw r3, OFFSET_PLAYING(r5)
continue_playback:
stw r3, OFFSET_PLAY_FRAME(r5)
end:
# Overwritten instruction
lis r0, 0x8016
ori r0, r0, 0xB0FC
mtlr r0
blrl
Last edited: