diff --git a/Common/Common.s b/Common/Common.s index d139db29..45a03da2 100644 --- a/Common/Common.s +++ b/Common/Common.s @@ -521,6 +521,7 @@ add \reg, r3, r4 .set CONST_ExiWrite, 1 # arg value to make an EXI write # For Slippi communication +.set CONST_SlippiCmdSendMenuFrame, 0x3E .set CONST_SlippiCmdGetFrame, 0x76 .set CONST_SlippiCmdCheckForReplay, 0x88 .set CONST_SlippiCmdCheckForStockSteal,0x89 @@ -612,6 +613,14 @@ add \reg, r3, r4 .set isWidescreen,-0x5020 .set OFST_R13_SB_ADDR,-0x503C # Scene buffer, persists throughout scenes +################################################################################ +# CSS Screen Player Cursor State Offsets +################################################################################ +.set CSS_CURSOR_STRUCT_PTR_P1, 0x804A0BC0 +.set CSS_CURSOR_STRUCT_PTR_P2, 0x804A0BC4 +.set CSS_CURSOR_STRUCT_PTR_P3, 0x804A0BC8 +.set CSS_CURSOR_STRUCT_PTR_P4, 0x804A0BCC + ################################################################################ # Log levels ################################################################################ diff --git a/Common/ExtractMenuInfo/SendMenuFrame.asm b/Common/ExtractMenuInfo/SendMenuFrame.asm new file mode 100644 index 00000000..28fcd8ac --- /dev/null +++ b/Common/ExtractMenuInfo/SendMenuFrame.asm @@ -0,0 +1,293 @@ +################################################################################ +# Address: 0x801a4fa4 +################################################################################ + +################################################################################ +# Routine: SendMenuFrame +# ------------------------------------------------------------------------------ +# Description: Gets menu information and sends it to the Slippi device +################################################################################ + +.include "Common/Common.s" + +.set PAYLOAD_LEN, 0x40 +.set EXI_BUF_LEN, PAYLOAD_LEN + 1 + +.set STACK_FREE_SPACE, EXI_BUF_LEN + 0x20 # Add 0x20 to deal with byte alignment + +.set STACK_OFST_EXI_BUF, BKP_FREE_SPACE_OFFSET + +backup STACK_FREE_SPACE + +# check if NOT VS Mode +getMinorMajor r8 +cmpwi r8, SCENE_VERSUS_IN_GAME +beq Injection_Exit +cmpwi r8, SCENE_ONLINE_IN_GAME +beq Injection_Exit + +addi r3, sp, STACK_OFST_EXI_BUF # This is the start address for the free space +byteAlign32 r3 # Align to next 32 byte boundary + +li r4, CONST_SlippiCmdSendMenuFrame # Command byte +stb r4, 0x0(r3) + +# Two bytes for major / minor scene +sth r8, 0x1(r3) + +# send player 1 cursor x position +# Each player has a heap-allocated struct, make sure the ptr is not NULL before reading + +load r4, CSS_CURSOR_STRUCT_PTR_P1 +lwz r4, 0(r4) +cmpwi r4, 0 +bne SendP1Cursor + +# set cursor values to 0 +load r5, 0x00000000 +stw r5, 0x3(r3) +stw r5, 0x7(r3) +b P2_Cursor + +SendP1Cursor: +# Load cursor x position +lwz r5, 0x0c(r4) +stw r5, 0x3(r3) +# Load cursor y position +lwz r5, 0x10(r4) +stw r5, 0x7(r3) + +P2_Cursor: +load r4, CSS_CURSOR_STRUCT_PTR_P2 +lwz r4, 0(r4) +cmpwi r4, 0 +bne SendP2Cursor + +# set cursor values to 0 +load r5, 0x00000000 +stw r5, 0xB(r3) +stw r5, 0xF(r3) +b P3_Cursor + +SendP2Cursor: +# Load cursor x position +lwz r5, 0x0c(r4) +stw r5, 0xB(r3) +# Load cursor y position +lwz r5, 0x10(r4) +stw r5, 0xF(r3) + +P3_Cursor: +load r4, CSS_CURSOR_STRUCT_PTR_P3 +lwz r4, 0(r4) +cmpwi r4, 0 +bne SendP3Cursor + +# set p1 cursor values to 0 +load r5, 0x00000000 +stw r5, 0x13(r3) +stw r5, 0x17(r3) +b P4_Cursor + +SendP3Cursor: +# Load cursor x position +lwz r5, 0x0c(r4) +stw r5, 0x13(r3) +# Load cursor y position +lwz r5, 0x10(r4) +stw r5, 0x17(r3) + +P4_Cursor: +load r4, CSS_CURSOR_STRUCT_PTR_P4 +lwz r4, 0(r4) +cmpwi r4, 0 +bne SendP4Cursor + +# set p1 cursor values to 0 +load r5, 0x00000000 +stw r5, 0x1B(r3) +stw r5, 0x1F(r3) +b CURSORS_DONE + +SendP4Cursor: +# Load cursor x position +lwz r5, 0x0c(r4) +stw r5, 0x1B(r3) +# Load cursor y position +lwz r5, 0x10(r4) +stw r5, 0x1F(r3) + +CURSORS_DONE: + +# Ready to fight banner visible (one byte) +# banner "swoops in" frame by frame +# value of 10 is fully invisible (not ready to play) +# value of 0 is fully visible (ready to play) +load r4 0x804d6cf2 +lbz r4, 0(r4) +stb r4, 0x23(r3) + +# Stage selected (one byte) +load r4 0x804D6CAD +lbz r4, 0(r4) +stb r4, 0x24(r3) + +# controller port statuses at CSS (each one byte) +# 0 == Human +# 1 == CPU +# 3 == Off +# Player 1 +load r4 0x803F0E08 +lbz r4, 0(r4) +stb r4, 0x25(r3) +# Player 2 +load r4 0x803F0E2C +lbz r4, 0(r4) +stb r4, 0x26(r3) +# Player 3 +load r4 0x803F0E50 +lbz r4, 0(r4) +stb r4, 0x27(r3) +# Player 4 +load r4 0x803F0E74 +lbz r4, 0(r4) +stb r4, 0x28(r3) + +# Character selected (each one byte) +# Player 1 +load r4 0x803F0E0A +lbz r4, 0(r4) +stb r4, 0x29(r3) +# Player 2 +load r4 0x803F0E2E +lbz r4, 0(r4) +stb r4, 0x2A(r3) +# Player 3 +load r4 0x803F0E52 +lbz r4, 0(r4) +stb r4, 0x2B(r3) +# Player 4 +load r4 0x803F0E76 +lbz r4, 0(r4) +stb r4, 0x2C(r3) + +# Coin down +# 0 == No coin +# 1 == Coin in hand +# 2 == Coin down +# 3 == Not plugged in + +# Reading this value involves needing to follow a dynamic pointer +# This can segfault when not in the right scene +# So just return 0's when not in there and don't follow the pointers + +# Load 0's into player coins +load r4 0x00000000 +stw r4, 0x2D(r3) + +cmpwi r8, 0x0002 +bne Not_CSS + +# Player 1 +load r4 0x804a0bc0 +lwz r4, 0(r4) +addi r4, r4, 5 +lbz r4, 0(r4) +stb r4, 0x2D(r3) +# Player 2 +load r4 0x804a0bc4 +lwz r4, 0(r4) +addi r4, r4, 5 +lbz r4, 0(r4) +stb r4, 0x2E(r3) +# Player 3 +load r4 0x804a0bc8 +lwz r4, 0(r4) +addi r4, r4, 5 +lbz r4, 0(r4) +stb r4, 0x2F(r3) +# Player 4 +load r4 0x804a0bcc +lwz r4, 0(r4) +addi r4, r4, 5 +lbz r4, 0(r4) +stb r4, 0x30(r3) + +Not_CSS: + +# Reading this value involves needing to follow a dynamic pointer +# This can segfault when not in the right scene +# So just return 0's when not in there and don't follow the pointers + +# Load 0's into cursors +load r4 0x00000000 +stw r4, 0x31(r3) +load r4 0x00000000 +stw r4, 0x35(r3) + +# 0x0102 is offline SSS +# 0x0108 is online SSS +cmpwi r8, 0x0102 +beq Is_SSS +cmpwi r8, 0x0108 +beq Is_SSS +b Not_SSS + +Is_SSS: + +# Stage Select Cursor X +# 4-byte float +load r4 0x804D7820 +lwz r4, 0(r4) +addi r4, r4, 0x10 +lwz r4, 0(r4) +addi r4, r4, 0x28 +lwz r4, 0(r4) +addi r4, r4, 0x38 +lwz r4, 0(r4) +stw r4, 0x31(r3) + +# Stage Select Cursor y +# 4-byte float +load r4 0x804D7820 +lwz r4, 0(r4) +addi r4, r4, 0x10 +lwz r4, 0(r4) +addi r4, r4, 0x28 +lwz r4, 0(r4) +addi r4, r4, 0x3C +lwz r4, 0(r4) +stw r4, 0x35(r3) + +Not_SSS: + +# Frame count +load r4 0x80479D60 +lwz r4, 0(r4) +stw r4, 0x39(r3) + +# Sub-menu +load r4 0x804A04F0 +lbz r4, 0(r4) +stb r4, 0x3D(r3) + +# Menu selection index +load r4 0x804A04F3 +lbz r4, 0(r4) +stb r4, 0x3E(r3) + +# Online character costume +load r4 0x803F0E09 +lbz r4, 0(r4) +stb r4, 0x3F(r3) + +#------------- Transfer Buffer ------------ +# r3 is the buffer arg, but it's already set +li r4, EXI_BUF_LEN +li r5, CONST_ExiWrite +branchl r12, FN_EXITransferBuffer + +Injection_Exit: + +restore STACK_FREE_SPACE +lwz r3, 0(r25) # replaced code line diff --git a/Output/InjectionLists/list_netplay.json b/Output/InjectionLists/list_netplay.json index 71b9f580..07f93b6a 100644 --- a/Output/InjectionLists/list_netplay.json +++ b/Output/InjectionLists/list_netplay.json @@ -2085,6 +2085,13 @@ "Codetype": "Auto", "Annotation": "Online/Optional/ShowAllyIndicator/ShowAllyIndicator.asm", "Tags": "" + }, + { + "InjectionAddress": "801A4FA4", + "Name": "Optional: Extract Menu Info", + "Codetype": "Auto", + "Annotation": "Common/ExtractMenuInfo/SendMenuFrame.asm", + "Tags": "" } ] } \ No newline at end of file diff --git a/Output/Netplay/GALE01r2.ini b/Output/Netplay/GALE01r2.ini index b366df71..05cd2a40 100644 --- a/Output/Netplay/GALE01r2.ini +++ b/Output/Netplay/GALE01r2.ini @@ -7081,3 +7081,108 @@ C0230064 BA810008 BA810008 800100B4 382100B0 7C0803A6 60000000 00000000 + +$Optional: Extract Menu Info [altf4, Fizzi] +*Extracts menu info. Useful for bots. +C21A4FA4 00000065 #Common/ExtractMenuInfo/SendMenuFrame.asm +7C0802A6 90010004 +9421FF64 BE81006C +3D008048 81089D30 +5508443E 2C080202 +418202EC 2C080208 +418202E4 38610008 +3863001F 54630034 +3880003E 98830000 +B1030001 3C80804A +60840BC0 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A30003 90A30007 +48000014 80A4000C +90A30003 80A40010 +90A30007 3C80804A +60840BC4 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A3000B 90A3000F +48000014 80A4000C +90A3000B 80A40010 +90A3000F 3C80804A +60840BC8 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A30013 90A30017 +48000014 80A4000C +90A30013 80A40010 +90A30017 3C80804A +60840BCC 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A3001B 90A3001F +48000014 80A4000C +90A3001B 80A40010 +90A3001F 3C80804D +60846CF2 88840000 +98830023 3C80804D +60846CAD 88840000 +98830024 3C80803F +60840E08 88840000 +98830025 3C80803F +60840E2C 88840000 +98830026 3C80803F +60840E50 88840000 +98830027 3C80803F +60840E74 88840000 +98830028 3C80803F +60840E0A 88840000 +98830029 3C80803F +60840E2E 88840000 +9883002A 3C80803F +60840E52 88840000 +9883002B 3C80803F +60840E76 88840000 +9883002C 3C800000 +60840000 9083002D +2C080002 40820064 +3C80804A 60840BC0 +80840000 38840005 +88840000 9883002D +3C80804A 60840BC4 +80840000 38840005 +88840000 9883002E +3C80804A 60840BC8 +80840000 38840005 +88840000 9883002F +3C80804A 60840BCC +80840000 38840005 +88840000 98830030 +3C800000 60840000 +90830031 3C800000 +60840000 90830035 +2C080102 41820010 +2C080108 41820008 +48000054 3C80804D +60847820 80840000 +38840010 80840000 +38840028 80840000 +38840038 80840000 +90830031 3C80804D +60847820 80840000 +38840010 80840000 +38840028 80840000 +3884003C 80840000 +90830035 3C808047 +60849D60 80840000 +90830039 3C80804A +608404F0 88840000 +9883003D 3C80804A +608404F3 88840000 +9883003E 3C80803F +60840E09 88840000 +9883003F 38800041 +38A00001 3D808000 +618C55F0 7D8903A6 +4E800421 BA81006C +800100A0 3821009C +7C0803A6 80790000 +60000000 00000000 diff --git a/Output/Netplay/GALJ01r2.ini b/Output/Netplay/GALJ01r2.ini index a306c554..c24739bf 100644 --- a/Output/Netplay/GALJ01r2.ini +++ b/Output/Netplay/GALJ01r2.ini @@ -7080,3 +7080,108 @@ C0230064 BA810008 BA810008 800100B4 382100B0 7C0803A6 60000000 00000000 + +$Optional: Extract Menu Info [altf4, Fizzi] +*Extracts menu info. Useful for bots. +C21A4FA4 00000065 #Common/ExtractMenuInfo/SendMenuFrame.asm +7C0802A6 90010004 +9421FF64 BE81006C +3D008048 81089D30 +5508443E 2C080202 +418202EC 2C080208 +418202E4 38610008 +3863001F 54630034 +3880003E 98830000 +B1030001 3C80804A +60840BC0 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A30003 90A30007 +48000014 80A4000C +90A30003 80A40010 +90A30007 3C80804A +60840BC4 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A3000B 90A3000F +48000014 80A4000C +90A3000B 80A40010 +90A3000F 3C80804A +60840BC8 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A30013 90A30017 +48000014 80A4000C +90A30013 80A40010 +90A30017 3C80804A +60840BCC 80840000 +2C040000 40820018 +3CA00000 60A50000 +90A3001B 90A3001F +48000014 80A4000C +90A3001B 80A40010 +90A3001F 3C80804D +60846CF2 88840000 +98830023 3C80804D +60846CAD 88840000 +98830024 3C80803F +60840E08 88840000 +98830025 3C80803F +60840E2C 88840000 +98830026 3C80803F +60840E50 88840000 +98830027 3C80803F +60840E74 88840000 +98830028 3C80803F +60840E0A 88840000 +98830029 3C80803F +60840E2E 88840000 +9883002A 3C80803F +60840E52 88840000 +9883002B 3C80803F +60840E76 88840000 +9883002C 3C800000 +60840000 9083002D +2C080002 40820064 +3C80804A 60840BC0 +80840000 38840005 +88840000 9883002D +3C80804A 60840BC4 +80840000 38840005 +88840000 9883002E +3C80804A 60840BC8 +80840000 38840005 +88840000 9883002F +3C80804A 60840BCC +80840000 38840005 +88840000 98830030 +3C800000 60840000 +90830031 3C800000 +60840000 90830035 +2C080102 41820010 +2C080108 41820008 +48000054 3C80804D +60847820 80840000 +38840010 80840000 +38840028 80840000 +38840038 80840000 +90830031 3C80804D +60847820 80840000 +38840010 80840000 +38840028 80840000 +3884003C 80840000 +90830035 3C808047 +60849D60 80840000 +90830039 3C80804A +608404F0 88840000 +9883003D 3C80804A +608404F3 88840000 +9883003E 3C80803F +60840E09 88840000 +9883003F 38800041 +38A00001 3D808000 +618C55F0 7D8903A6 +4E800421 BA81006C +800100A0 3821009C +7C0803A6 80790000 +60000000 00000000 diff --git a/netplay.json b/netplay.json index 4eb35eb3..94905e1c 100644 --- a/netplay.json +++ b/netplay.json @@ -521,6 +521,23 @@ "isRecursive": true } ] + }, + { + "name": "Optional: Extract Menu Info", + "authors": [ + "altf4", + "Fizzi" + ], + "description": [ + "Extracts menu info. Useful for bots." + ], + "build": [ + { + "type": "injectFolder", + "sourceFolder": "Common/ExtractMenuInfo", + "isRecursive": true + } + ] } ] } \ No newline at end of file