diff --git a/.gitattributes b/.gitattributes index 937de2b..c4403ff 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,6 +10,8 @@ *.vue text eol=crlf *.xml text eol=crlf linguist-detectable *.yml text eol=crlf +*.ct text eol=crlf +*.CEA text eol=crlf # Special files .dockerignore text eol=crlf @@ -20,3 +22,4 @@ LICENSE text eol=crlf *.jpg binary *.png binary *.zip binary +*.xslx binary diff --git a/Readme.md b/Readme.md index 5802818..f903bfd 100644 --- a/Readme.md +++ b/Readme.md @@ -23,6 +23,12 @@ The codes are stored in the `Codes.xml` file. If you want to add or change codes When adding new codes keep in mind that the English title/description are mandatory. +#### Reserved Memory + +Some codes store some states in the games memory starting from address 0x81F70000. To avoid collisions use a memory range in the unallocated ranges: + +![](./docs/reserved_memory.png) + ### Adding translations 1. Create a new file `.json` in `site/.vuepress/i18n`, where `` is the language code you want to add. Copy the contents of `en-US.json` into your file and translate each entry in the JSON file. diff --git a/docs/Reserved_Memory.xlsx b/docs/Reserved_Memory.xlsx new file mode 100644 index 0000000..4134ba2 Binary files /dev/null and b/docs/Reserved_Memory.xlsx differ diff --git a/docs/reserved_memory.png b/docs/reserved_memory.png new file mode 100644 index 0000000..f04b9b3 Binary files /dev/null and b/docs/reserved_memory.png differ diff --git a/utils/2_Byte_Big_Endian.CEA b/utils/2_Byte_Big_Endian.CEA new file mode 100644 index 0000000..1e633fe --- /dev/null +++ b/utils/2_Byte_Big_Endian.CEA @@ -0,0 +1,82 @@ +alloc(TypeName,256) +alloc(ByteSize,4) +alloc(ConvertRoutine,1024) +alloc(ConvertBackRoutine,1024) + +TypeName: +db '2 Byte Big Endian',0 + +ByteSize: +dd 2 + +//The convert routine should hold a routine that converts the data to an integer (in eax) +//function declared as: stdcall int ConvertRoutine(unsigned char *input); +//Note: Keep in mind that this routine can be called by multiple threads at the same time. +ConvertRoutine: +//jmp dllname.functionname +[64-bit] +//or manual: +//parameters: (64-bit) +//rcx=address of input +xor eax,eax +mov ax,[rcx] //eax now contains the bytes 'input' pointed to +xchg ah,al //convert to big endian + +ret +[/64-bit] + +[32-bit] +//jmp dllname.functionname +//or manual: +//parameters: (32-bit) +push ebp +mov ebp,esp +//[ebp+8]=input +//example: +mov eax,[ebp+8] //place the address that contains the bytes into eax +mov ax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value +and eax,ffff //cleanup +xchg ah,al //convert to big endian + +pop ebp +ret 4 +[/32-bit] + +//The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value) +//function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output); +ConvertBackRoutine: +//jmp dllname.functionname +//or manual: +[64-bit] +//parameters: (64-bit) +//ecx=input +//rdx=address of output +//example: +xchg ch,cl //convert the little endian input into a big endian input +mov [rdx],cx //place the integer the 4 bytes pointed to by rdx + +ret +[/64-bit] + +[32-bit] +//parameters: (32-bit) +push ebp +mov ebp,esp +//[ebp+8]=input +//[ebp+c]=address of output +//example: +push eax +push ebx +mov eax,[ebp+8] //load the value into eax +mov ebx,[ebp+c] //load the address into ebx + +//convert the value to big endian +xchg ah,al + +mov [ebx],ax //write the value into the address +pop ebx +pop eax + +pop ebp +ret 8 +[/32-bit] diff --git a/utils/4_Byte_Big_Endian.CEA b/utils/4_Byte_Big_Endian.CEA new file mode 100644 index 0000000..dc8f294 --- /dev/null +++ b/utils/4_Byte_Big_Endian.CEA @@ -0,0 +1,82 @@ +alloc(TypeName,256) +alloc(ByteSize,4) +alloc(ConvertRoutine,1024) +alloc(ConvertBackRoutine,1024) + +TypeName: +db '4 Byte Big Endian',0 + +ByteSize: +dd 4 + +//The convert routine should hold a routine that converts the data to an integer (in eax) +//function declared as: stdcall int ConvertRoutine(unsigned char *input); +//Note: Keep in mind that this routine can be called by multiple threads at the same time. +ConvertRoutine: +//jmp dllname.functionname +[64-bit] +//or manual: +//parameters: (64-bit) +//rcx=address of input +xor eax,eax +mov eax,[rcx] //eax now contains the bytes 'input' pointed to +bswap eax //convert to big endian + +ret +[/64-bit] + +[32-bit] +//jmp dllname.functionname +//or manual: +//parameters: (32-bit) +push ebp +mov ebp,esp +//[ebp+8]=input +//example: +mov eax,[ebp+8] //place the address that contains the bytes into eax +mov eax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value + +bswap eax + +pop ebp +ret 4 +[/32-bit] + +//The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value) +//function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output); +ConvertBackRoutine: +//jmp dllname.functionname +//or manual: +[64-bit] +//parameters: (64-bit) +//ecx=input +//rdx=address of output +//example: +bswap ecx //convert the little endian input into a big endian input +mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx + +ret +[/64-bit] + +[32-bit] +//parameters: (32-bit) +push ebp +mov ebp,esp +//[ebp+8]=input +//[ebp+c]=address of output +//example: +push eax +push ebx +mov eax,[ebp+8] //load the value into eax +mov ebx,[ebp+c] //load the address into ebx + +//convert the value to big endian +bswap eax + +mov [ebx],eax //write the value into the address +pop ebx +pop eax + +pop ebp +ret 8 +[/32-bit] diff --git a/utils/Sunshine.CT b/utils/Sunshine.CT new file mode 100644 index 0000000..8507cf0 --- /dev/null +++ b/utils/Sunshine.CT @@ -0,0 +1,462 @@ + + + + + 24 + "Base Address Lookup" + + + Auto Assembler Script + // Uncomment the version you're targeting + +// GMSE01 (NTSC-U) +// define(INPUT_OFFSET,404454) +// define(COIN_COUNT_OFFSET,578A60) +// define(LIFE_COUNT_OFFSET,578A04) +// define(POS_PTR_OFFSET, 40E10C) + + +// GMSJ01 (NTSC-J 1.0) +// define(INPUT_OFFSET, 400D50) +// define(LIFE_COUNT_OFFSET, 575224) +// define(COIN_COUNT_OFFSET, 575280) +// define(POS_PTR_OFFSET, 40A39C) + +// GMSJ01 (NTSC-J 1.1) +// define(INPUT_OFFSET, 3F5428) +// define(LIFE_COUNT_OFFSET, 569724) +// define(COIN_COUNT_OFFSET, 569780) +// define(POS_PTR_OFFSET, 3FEFAC) + +// GMSP01 (PAL) +define(INPUT_OFFSET, 3FBBF4) +define(LIFE_COUNT_OFFSET, 570964) +define(COIN_COUNT_OFFSET, 5709C0) +define(POS_PTR_OFFSET, 4057D4) + +registerSymbol(INPUT_OFFSET) +registerSymbol(COIN_COUNT_OFFSET) +registerSymbol(LIFE_COUNT_OFFSET) +registerSymbol(POS_PTR_OFFSET) + + +[ENABLE] +define(PRACTICE_CODE_MEMORY_OFFSET, 17F0000) +registerSymbol(PRACTICE_CODE_MEMORY_OFFSET) + +label(BASE_ADDRESS) +registerSymbol(BASE_ADDRESS) + +aobScan(aob1,47 4D 53 ?? 30 31 00 ?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C2 33 9F 3D) +aob1: +BASE_ADDRESS: + +[DISABLE] +unregisterSymbol(BASE_ADDRESS) +unregisterSymbol(PRACTICE_CODE_MEMORY_OFFSET) +unregisterSymbol(POS_PTR_OFFSET) +unregisterSymbol(LIFE_COUNT_OFFSET) +unregisterSymbol(COIN_COUNT_OFFSET) +unregisterSymbol(INPUT_OFFSET) + + + + + Toggle Activation + + 97 + + 0 + + + + + 50 + "Practice Code Values (Start at PRACTICE_CODE_MEMORY_OFFSET / 0x817F0000)" + + + FF0000 + 1 + + + 57 + "0x000 Level Select Stage Data" + + 1 + Array of byte + 8 +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET
+
+ + 53 + "0x008 Stored Position (Mario)" + + 1 + Array of byte + 12 +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+8
+
+ + 54 + "0x014 Stored Angle (Mario)" + + 1 + Array of byte + 2 +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+14
+
+ + 56 + "0x016 Stored Position (Camera)" + + 1 + Array of byte + 6 +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+16
+
+ + 63 + "0x020 Stored Coins" + + 1 + Custom + 4 Byte Big Endian +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+20
+
+ + 58 + "0x100 Reset Stopwatch In Demo Screen Flag" + + 1 + Byte +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+100
+
+ + 59 + "0x101 Disable Custom IG Timer Flag" + + 1 + Byte +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+101
+
+ + 62 + "0x102 Stopwatch Save State" + + 1 + Array of byte + 8 +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+102
+
+ + 60 + "0x10C Stop Timer Flag" + + 1 + Byte +
BASE_ADDRESS+PRACTICE_CODE_MEMORY_OFFSET+10C
+
+
+
+ + 0 + "Current Base Address" + + 1 + C0C0C0 + 4 Bytes +
BASE_ADDRESS
+
+ + 27 + "Coin Count" + + 008000 + Custom + 4 Byte Big Endian +
BASE_ADDRESS+COIN_COUNT_OFFSET
+
+ + 25 + "Life Count" + + 008000 + Custom + 4 Byte Big Endian +
BASE_ADDRESS+LIFE_COUNT_OFFSET
+
+ + 29 + "Mario's Position" + + + C08000 + Auto Assembler Script + // Get marios position +[ENABLE] + +// Allocate 4 bytes for the position +registerSymbol(INT_POS_ADDRESS) +alloc(INT_POS_ADDRESS, 4) + +// Read the address of the controller input +// into INT_CONTROLLER_INPUT_ADDRESS +// Since GC uses big endian we have to reverse +// the 4 bytes of the pointer +INT_POS_ADDRESS: +readMem(BASE_ADDRESS + POS_PTR_OFFSET + 3, 1) +readMem(BASE_ADDRESS + POS_PTR_OFFSET + 2, 1) +readMem(BASE_ADDRESS + POS_PTR_OFFSET + 1, 1) +readMem(BASE_ADDRESS + POS_PTR_OFFSET, 1) + +// Calculate the final address for use with Dolphin +define(POS_ADDRESS, BASE_ADDRESS + [INT_POS_ADDRESS] - 80000000) +registerSymbol(POS_ADDRESS) + +[DISABLE] +dealloc(INT_POS_ADDRESS) +unregisterSymbol(INT_POS_ADDRESS) +unregisterSymbol(POS_ADDRESS) + + + + Toggle Activation + + 97 + + 0 + + + + + 30 + "Marios Position" + + 1 + Array of byte + 12 +
POS_ADDRESS
+
+
+
+ + 34 + "Controller Inputs" + + + C08000 + 1 + + + 40 + "A" + 0:- +1:Pressed + + + Binary + 0 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET
+
+ + 41 + "B" + 0:- +1:Pressed + + + Binary + 1 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET
+
+ + 38 + "X" + 0:- +1:Pressed + + + Binary + 2 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET
+
+ + 39 + "Y" + 0:- +1:Pressed + + + Binary + 3 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET
+
+ + 49 + "Start" + 0:- +1:Pressed + + + Binary + 4 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET
+
+ + 48 + "Z" + 0:- +1:Pressed + + + Binary + 4 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET+1
+
+ + 32 + "DPAD UP" + 0:- +1:Pressed + + + 1 + Binary + 3 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET + 1
+
+ + 35 + "DPAD DOWN" + 0:- +1:Pressed + + + Binary + 2 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET + 1
+
+ + 36 + "DPAD LEFT" + 0:- +1:Pressed + + + Binary + 0 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET + 1
+
+ + 37 + "DPAD RIGHT" + 0:- +1:Pressed + + + Binary + 1 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET + 1
+
+ + 42 + "L" + 0:- +1:Pressed + + + Binary + 6 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET + 1
+
+ + 44 + "L (Analog)" + + Byte +
BASE_ADDRESS+INPUT_OFFSET + 6
+
+ + 43 + "R" + 0:- +1:Pressed + + + Binary + 5 + 1 + 0 +
BASE_ADDRESS+INPUT_OFFSET + 1
+
+ + 45 + "R (Analog)" + + Byte +
BASE_ADDRESS+INPUT_OFFSET + 7
+
+ + 46 + "L Stick" + + Custom + 2 Byte Big Endian +
BASE_ADDRESS+INPUT_OFFSET + 2
+
+ + 47 + "R-Stick" + + Custom + 2 Byte Big Endian +
BASE_ADDRESS+INPUT_OFFSET+4
+
+
+
+
+
+
+ + + Group 0 + + + + + label5 +
004E3739
+
+ + label1 +
01733513
+
+ + xlivekiller +
59151605
+
+
+ Grey -> Informational +