Skip to content
JLaferriPublic

About

Gecko code command line tools

Resources

Stars

38 stars

Watchers

3 watching

Forks

Repository files navigation

Gecko Tools

Purpose

I quickly put together this project to solve a problem I was having while developing codes for Super Smash Bros Melee. I was finding it really annoying, every time I made an ASM code change, having to copy my new code into CodeWrite, set the address, click the arrow, and then copy the contents and replace the correct portion of my composite code in GALE01r2.ini.

Composite codes (perhaps there's a better term) is a trend I've been seeing where Melee developers package multiple individual Gecko codes as one single code. The process I described earlier gets even more annoying when I make changes to say 3 asm files at once. I have to correctly compile and replace every single one. I wanted an easier, faster, and less error prone method.

Drawing inspiration from package managers such as npm, I thought it would be a good idea to just define what codes I wanted to compile and what addresses I wanted to inject at in a configuration file and just say "build". So that's what I did and currently that's the full scope of this simple project.

Installation

  1. Visit the releases page to download the latest version
  2. Extract the files to a directory such as C:\gecko\bin. The contents include:
    • gecko.exe - main program binary for running commands
    • powerpc-eabi-as.exe - assembler used to compile code
    • powerpc-eabi-objcopy.exe - pulls the compiled code out of the assembler's output
  3. Add C:\gecko\bin (or whatever path you placed the files in) to your PATH environment variable.
  4. Done!

If you have devkitPPC installed, gecko will also find the assembler tools in $DEVKITPPC/bin when they aren't on your PATH.

Usage

Important

We very rarely use anything other than "type": "injectFolder" now. This option allows an entire folder of code files to be converted to gecko codes according to their headers. The headers support Address, Codetype, and Annotation as options.

build command

All you have to do to use the build command is write a codes.json file and put it in a directory which contains all of your files containing your assembly code, cd to that file from the command line, and type gecko build. This will create a text file with all of your compiled composite codes where you specified.

codes.json

I feel like it's easiest to lead by example. The codes.json file is relatively self explanatory. I'll show a very simple version here and then link to a more complex solution in my project to show off all the possibilities.

{
    "settings": {
        "areIncludesRelativeFromFile": true
    },
    "outputFiles": [
        {
            "file": "CodeList.txt"
        }
    ],
    "codes": [
        {
            "name": "My Cool Codes!",
            "authors": [
                "Fizzi",
                "The Melee Modding Community"
            ],
            "description": [
                "Here's a description of what",
                "these codes do. You can even",
                "split it into multiple lines!"
            ],
            "build": [
                {
                    "type": "injectFolder",
                    "sourceFolder": "InjectionCodes",
                    "isRecursive": true,
                    "annotation": "My Injected Codes (C2) [Fizzi]"
                }
            ]
        }
    ]
}

Real example

For a more complex example view the .json files in my project.

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.

Batched builds

Version 4.1.0 added the -batched flag on build and assemble. This collects and assembles all ASM files together which can save time on large codebases. It can also be less taxing on certain systems as it does not spawn hundreds of powerpc-eabi-as processes.

Batched builds can potentially cause problems. The program attempts to isolate symbol and label names from each other but there may be bugs. Additionally, headers need to be handled a bit differently. Since many files include the same headers, in order to avoid duplicated definitions, headers should be wrapped in the following:

.ifndef HEADER_UNIQUE_NAME
# Header contents here
.endif
.set HEADER_UNIQUE_NAME, 1

Additionally, I believe the assembler will act as if all files include all headers. So if you have symbols with the same name defined in different headers, the value used in any given file may not match the one in the file it itself included.

File watchers

If you use a code editer that supports file watchers, you could consider hooking up the command to run automatically whenever you save one of your assembly code files. This strategy would save you the trouble of having to gecko build manually.

Undefined symbols

The assembler doesn't complain about symbols that aren't defined anywhere. It leaves them for a linker to fill in, and since gecko codes are never linked they would end up as zeros, so a misspelled symbol or label would quietly build into broken code. Instead the build fails and points at the lines using the symbol. The same goes for code that needs the absolute address of one of its own labels, such as lis r3, MyLabel@ha, which also isn't known until the code is placed in memory.

Caching

The -cache flag on build and assemble reuses code assembled by earlier builds. The cache is kept in .gecko/cache next to the config file, and gecko puts a .gitignore in it so it stays out of source control. Delete the .gecko/cache folder to clear it.

A file's code is only reused when nothing that could change it has changed:

  • The file's contents and injection address
  • The contents of every file it includes, directly or through other includes, and of every file it pulls in with .incbin. These are the files the assembler reports reading, so includes inside macros or .if blocks are tracked as they are actually used
  • Where each include is found. If a file with the same name appears somewhere the assembler looks first, the code is rebuilt
  • The -defsym, -warn and -batched flags. Each combination keeps its own entries so alternating between them doesn't rebuild everything
  • The gecko and assembler binaries

With -batched, files are assembled together and can see each other's symbols, so the batch is cached as a whole and any change rebuilds all of it. Using -cache without -batched is recommended instead. Only the files that changed get assembled, which avoids most of the cost batching was meant to save.

A file saved within a few seconds of a build starting is assembled as usual but not cached until a later build, in case it changed while the assembler was reading it.

Other Commands

If anyone has any ideas as to some other commands that might be useful I'm more than open to contributions. Please just fork my project and submit a pull request. I called this project Gecko Tool(s) for a reason. Hopefully there are more useful things that can be done with it.

About

Gecko code command line tools

Resources

Stars

38 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages