From aeb14dd90c516948204fba74a1eb1b67199c5c0c Mon Sep 17 00:00:00 2001 From: Robert Peralta Date: Thu, 29 Jul 2021 18:14:46 -0400 Subject: [PATCH 1/2] Add new Gecko Code Type for text binaries - Appends existing gecko code "binary" - Replaces annotations if present --- .gitignore | 1 + README.md | 7 ++ examples/asm/Rumble Off/Rumble Off.asm | 5 ++ examples/bin/FasterMeleeSettings/4Stocks.bin | Bin 0 -> 8 bytes examples/buid.json | 64 +++++++++++++++++++ examples/gct/FreezeGlitchFix.gct | Bin 0 -> 24 bytes examples/output/codes.bin | Bin 0 -> 40 bytes examples/output/codes.gct | Bin 0 -> 56 bytes examples/output/codes.ini | 40 ++++++++++++ examples/text/LocalPlayerTag.ini | 27 ++++++++ gecko.go | 37 ++++++++++- go.mod | 3 + 12 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 examples/asm/Rumble Off/Rumble Off.asm create mode 100644 examples/bin/FasterMeleeSettings/4Stocks.bin create mode 100644 examples/buid.json create mode 100644 examples/gct/FreezeGlitchFix.gct create mode 100644 examples/output/codes.bin create mode 100644 examples/output/codes.gct create mode 100644 examples/output/codes.ini create mode 100644 examples/text/LocalPlayerTag.ini create mode 100644 go.mod diff --git a/.gitignore b/.gitignore index c5b63f2..acbc297 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ $ IDE stuff .idea/ +.vscode # Test binary, build with `go test -c` *.test diff --git a/README.md b/README.md index ac5309a..74ee4dc 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,13 @@ I feel like it's easiest to lead by example. The `codes.json` file is relatively ``` #### Real example For a more complex example view the [codes.json file](https://github.com/project-slippi/project-slippi/blob/15533b366d3fad0ec3dae9e9c66794696c1f2624/Gecko%20Codes/codes.json) in my project and the resulting [CodeList.txt file](https://github.com/project-slippi/project-slippi/blob/15533b366d3fad0ec3dae9e9c66794696c1f2624/Gecko%20Codes/CodeList.txt) + +#### Even more examples +Look at `build.json` on `./examples` directory, you can execute them from the root of the project by running this on the console: +``` +.\gecko build -c .\gecko\buid.json +``` + #### Relative paths I haven't tested this but it should be possible to define relative paths for `sourceFile` and `outputFile` if you have a nested directory structure. #### File watchers diff --git a/examples/asm/Rumble Off/Rumble Off.asm b/examples/asm/Rumble Off/Rumble Off.asm new file mode 100644 index 0000000..cfbee51 --- /dev/null +++ b/examples/asm/Rumble Off/Rumble Off.asm @@ -0,0 +1,5 @@ +################################################################################ +# Address: 803d4a70 +################################################################################ + +.long 0x00000000 diff --git a/examples/bin/FasterMeleeSettings/4Stocks.bin b/examples/bin/FasterMeleeSettings/4Stocks.bin new file mode 100644 index 0000000000000000000000000000000000000000..c5f228bfd2619df0886362cf6fbdcbed783b425e GIT binary patch literal 8 PcmZRv_3~k1;9>v(1up>R literal 0 HcmV?d00001 diff --git a/examples/buid.json b/examples/buid.json new file mode 100644 index 0000000..1133aac --- /dev/null +++ b/examples/buid.json @@ -0,0 +1,64 @@ +{ + "outputFiles": [ + { + "file": "gecko/output/codes.gct" + }, + { + "file": "gecko/output/codes.ini" + }, + { + "file": "gecko/output/codes.bin" + } + ], + "codes": [ + { + "name": "ASM Codes", + "authors": [], + "description": [], + "build": [ + { + "type": "injectFolder", + "isRecursive": true, + "sourceFolder": "gecko/asm", + "annotation": "Rumble Off [UnclePunch]" + } + ] + }, + { + "name": "Bin Codes", + "authors": [], + "description": [], + "build": [ + { + "type": "binary", + "sourceFile": "gecko/bin/FasterMeleeSettings/4Stocks.bin", + "annotation": "4 Stocks [Magus]" + } + ] + }, + { + "name": "GCT Codes", + "authors": [], + "description": [], + "build": [ + { + "type": "binary", + "sourceFile": "gecko/gct/FreezeGlitchFix.gct", + "annotation": "Prevent freeze glitch [tauKhan]" + } + ] + }, + { + "name": "Text Codes", + "authors": [], + "description": [], + "build": [ + { + "type": "gecko", + "sourceFile": "gecko/text/LocalPlayerTag.ini" + } + ] + } + ] + } + \ No newline at end of file diff --git a/examples/gct/FreezeGlitchFix.gct b/examples/gct/FreezeGlitchFix.gct new file mode 100644 index 0000000000000000000000000000000000000000..59d540e6e27bd114831e0a6e2e875bd29d44f103 GIT binary patch literal 24 acmZR$aNr&T5VHtbu1H{DVE6#UAOHY*AO|D> literal 0 HcmV?d00001 diff --git a/examples/output/codes.bin b/examples/output/codes.bin new file mode 100644 index 0000000000000000000000000000000000000000..74e2022117329ebb8b85140abe59a189a84ddb97 GIT binary patch literal 40 ncmZRv^(tTh0v1~@9~K5K28IgxYfyIR^S0n(%KY%2G07e4<20#wb literal 0 HcmV?d00001 diff --git a/examples/output/codes.ini b/examples/output/codes.ini new file mode 100644 index 0000000..c01bcb3 --- /dev/null +++ b/examples/output/codes.ini @@ -0,0 +1,40 @@ +$ASM Codes [] +043D4A70 00000000 #gecko/asm/Rumble Off/Rumble Off.asm + +$Bin Codes [] +043D4A4C 04000A00 #4 Stocks [Magus] + +$GCT Codes [] +00D0C0DE 00D0C0DE #Prevent freeze glitch [tauKhan] +041239A8 60000000 +F0000000 00000000 + +$Text Codes [] +$Optional: Force Nametag for Local Player [Fizzi] +*When playing online, nametag YOU will show above your character --------------------- +*Will not cause desyncs when playing online +C20355B4 00000008 #Online/Optional/IndicateLocalPlayer/ForceLocalPlayerTag.asm +3C608048 80639D30 +5463443E 2C030208 +40820028 806DB61C +88630000 7C03F800 +40820018 38600000 +3D808003 618C55CC +7D8903A6 4E800420 +1C9F0E90 00000000 +C22FD1EC 0000000E #Online/Optional/IndicateLocalPlayer/SetLocalPlayerTag.asm +48000010 4E800021 +8278826E 82740000 +3C608048 80639D30 +5463443E 2C030208 +40820020 806DB61C +88630000 7C03D800 +40820010 4BFFFFD1 +7C6802A6 4800002C +7F63DB78 3D808003 +618C556C 7D8903A6 +4E800421 5463063E +3D808023 618C754C +7D8903A6 4E800421 +60000000 00000000 + diff --git a/examples/text/LocalPlayerTag.ini b/examples/text/LocalPlayerTag.ini new file mode 100644 index 0000000..aa62030 --- /dev/null +++ b/examples/text/LocalPlayerTag.ini @@ -0,0 +1,27 @@ +$Optional: Force Nametag for Local Player [Fizzi] +*When playing online, nametag YOU will show above your character --------------------- +*Will not cause desyncs when playing online +C20355B4 00000008 #Online/Optional/IndicateLocalPlayer/ForceLocalPlayerTag.asm +3C608048 80639D30 +5463443E 2C030208 +40820028 806DB61C +88630000 7C03F800 +40820018 38600000 +3D808003 618C55CC +7D8903A6 4E800420 +1C9F0E90 00000000 +C22FD1EC 0000000E #Online/Optional/IndicateLocalPlayer/SetLocalPlayerTag.asm +48000010 4E800021 +8278826E 82740000 +3C608048 80639D30 +5463443E 2C030208 +40820020 806DB61C +88630000 7C03D800 +40820010 4BFFFFD1 +7C6802A6 4800002C +7F63DB78 3D808003 +618C556C 7D8903A6 +4E800421 5463063E +3D808023 618C754C +7D8903A6 4E800421 +60000000 00000000 diff --git a/gecko.go b/gecko.go index 65bf1d5..3c7c6f4 100644 --- a/gecko.go +++ b/gecko.go @@ -12,6 +12,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "sort" "strconv" @@ -62,6 +63,7 @@ const ( InjectFolder = "injectFolder" ReplaceBinary = "replaceBinary" Binary = "binary" + Gecko = "gecko" ) type assemblerArgConfig struct { @@ -264,6 +266,10 @@ func generateCodeLines(desc CodeDescription) []string { lines := generateBinaryLines(geckoCode.SourceFile) lines[0] = addLineAnnotation(lines[0], geckoCode.Annotation) result = append(result, lines...) + case Gecko: + lines := generateGeckoLines(geckoCode.SourceFile, geckoCode.Annotation) + lines[0] = addLineAnnotation(lines[0], geckoCode.Annotation) + result = append(result, lines...) case Branch: fallthrough case BranchAndLink: @@ -638,6 +644,31 @@ func generateBinaryLines(file string) []string { return lines } +func generateGeckoLines(file string, annotation string) []string { + + contents, err := ioutil.ReadFile(file) + if err != nil { + log.Panicf("Failed to read binary file %s\n%s\n", file, err.Error()) + } + + instructions := contents + + if len(instructions) == 0 { + log.Panicf("Binary file must not be empty: %s\n", file) + } + + lines := []string{} + + if len(annotation) != 0 { + reg := regexp.MustCompile(`/[A-F0-9]{8} [A-F0-9]{8}/g`) + lines = reg.FindAllString(string(contents), -1) + } else { + lines = strings.Split(string(contents), `\n`) + } + + return lines +} + func compile(file, addressExp string) ([]byte, string) { fileExt := filepath.Ext(file) outputFilePath := file[0:len(file)-len(fileExt)] + ".out" @@ -712,14 +743,14 @@ func compile(file, addressExp string) ([]byte, string) { if aserr != nil || objcopyerr != nil { // Add $DEVKITPPC/bin to $PATH and try again if envDEVKITPPC, exists := os.LookupEnv("DEVKITPPC"); exists { - os.Setenv("PATH", envDEVKITPPC + "/bin" + ":" + os.Getenv("PATH")); + os.Setenv("PATH", envDEVKITPPC+"/bin"+":"+os.Getenv("PATH")) _, err := exec.LookPath(asCmdLinux) if err != nil { - log.Panicf("%s not available in $PATH. You may need to install devkitPPC", asCmdLinux) + log.Panicf("%s not available in $PATH. You may need to install devkitPPC", asCmdLinux) } _, err = exec.LookPath(objcopyCmdLinux) if err != nil { - log.Panicf("%s not available in $PATH. You may need to install devkitPPC", objcopyCmdLinux) + log.Panicf("%s not available in $PATH. You may need to install devkitPPC", objcopyCmdLinux) } } else { log.Panicf("%s and %s are not available in $PATH, and $DEVKITPPC has not been set. You may need to install devkit-env", asCmdLinux, objcopyCmdLinux) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b48dafc --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module main + +go 1.16 From 81ae9915c3b529781ebddd846c546a91dacb2636 Mon Sep 17 00:00:00 2001 From: Robert Peralta Date: Thu, 29 Jul 2021 18:25:50 -0400 Subject: [PATCH 2/2] Add missing examples --- examples/asm/Rumble Off/Rumble Off.asm | 1 + examples/buid.json | 14 +++++++------- examples/output/codes.ini | 2 +- examples/text/LocalPlayerTag.ini | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/asm/Rumble Off/Rumble Off.asm b/examples/asm/Rumble Off/Rumble Off.asm index cfbee51..60d0d8b 100644 --- a/examples/asm/Rumble Off/Rumble Off.asm +++ b/examples/asm/Rumble Off/Rumble Off.asm @@ -3,3 +3,4 @@ ################################################################################ .long 0x00000000 + \ No newline at end of file diff --git a/examples/buid.json b/examples/buid.json index 1133aac..e4c116d 100644 --- a/examples/buid.json +++ b/examples/buid.json @@ -1,13 +1,13 @@ { "outputFiles": [ { - "file": "gecko/output/codes.gct" + "file": "examples/output/codes.gct" }, { - "file": "gecko/output/codes.ini" + "file": "examples/output/codes.ini" }, { - "file": "gecko/output/codes.bin" + "file": "examples/output/codes.bin" } ], "codes": [ @@ -19,7 +19,7 @@ { "type": "injectFolder", "isRecursive": true, - "sourceFolder": "gecko/asm", + "sourceFolder": "examples/asm", "annotation": "Rumble Off [UnclePunch]" } ] @@ -31,7 +31,7 @@ "build": [ { "type": "binary", - "sourceFile": "gecko/bin/FasterMeleeSettings/4Stocks.bin", + "sourceFile": "examples/bin/FasterMeleeSettings/4Stocks.bin", "annotation": "4 Stocks [Magus]" } ] @@ -43,7 +43,7 @@ "build": [ { "type": "binary", - "sourceFile": "gecko/gct/FreezeGlitchFix.gct", + "sourceFile": "examples/gct/FreezeGlitchFix.gct", "annotation": "Prevent freeze glitch [tauKhan]" } ] @@ -55,7 +55,7 @@ "build": [ { "type": "gecko", - "sourceFile": "gecko/text/LocalPlayerTag.ini" + "sourceFile": "examples/text/LocalPlayerTag.ini" } ] } diff --git a/examples/output/codes.ini b/examples/output/codes.ini index c01bcb3..797118d 100644 --- a/examples/output/codes.ini +++ b/examples/output/codes.ini @@ -1,5 +1,5 @@ $ASM Codes [] -043D4A70 00000000 #gecko/asm/Rumble Off/Rumble Off.asm +043D4A70 00000000 #examples/asm/Rumble Off/Rumble Off.asm $Bin Codes [] 043D4A4C 04000A00 #4 Stocks [Magus] diff --git a/examples/text/LocalPlayerTag.ini b/examples/text/LocalPlayerTag.ini index aa62030..7113f4d 100644 --- a/examples/text/LocalPlayerTag.ini +++ b/examples/text/LocalPlayerTag.ini @@ -1,6 +1,6 @@ $Optional: Force Nametag for Local Player [Fizzi] *When playing online, nametag YOU will show above your character --------------------- -*Will not cause desyncs when playing online +*Will not cause desyncs when playing online C20355B4 00000008 #Online/Optional/IndicateLocalPlayer/ForceLocalPlayerTag.asm 3C608048 80639D30 5463443E 2C030208