Skip to content

Latest commit

 

History

History

modules

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
BrainSlug module development is designed to be a simple way to extend the
functionality of games. A BrainSlug module is just compiled C code which is
patched into a game seamlessly.

For ease, I recommend you base all new BrainSlug modules on the template
project. The template project has no actual code; but it does compile to a valid
module. Hopefully you should never have to change the template's Makefile,
instead there is a makefile.mk which contains parts of the Makefile that you
would normally want to change. The list of source files to be compiled is in
this file. You can use multiple source files as normal; just remember to include
<bslug.h> when using BSLUG_ macros. To build a module simply run `make' in its
directory. The generated module will appear as a `.mod' file in the `bin'
subdirectory to delete all generated files run `make clean'. To use the module
copy it to the `bslug\modules' directory on the SD card.

All modules MUST declare the following statements ONCE at top level:
    BSLUG_MODULE_NAME("BSlug Module template");
    BSLUG_MODULE_VERSION("v1.0");
    BSLUG_MODULE_AUTHOR("Chadderz");
    BSLUG_MODULE_LICENSE("BSD");
    
The BSLUG_MODULE_NAME macro defines the name of the module as it will be
displayed to users in logging messages. This can be any string.
The BSLUG_MODULE_VERSION macro defines the version of the module as it will
be displayed to users in logging messages. This can be any string.
The BSLUG_MODULE_AUTHOR macro defines the version of the module as it will
be displayed to users in logging messages. This can be any string.
The BSLUG_MODULE_LICENSE macro defines the license under which the module is
released. This can be any string. I recommend you put a short name for the
license here rather than the full text. Recommended values include:
    "BSD" - Open source, anyone can use code for any purpose, even commercial.
    "GPL" - Open source, anyone can use code but only in open source projects.
    "Freeware" - Closed source, must be distributed for no monetary cost.
    "Proprietary" - Closed source, may cost, may be limited to individuals.

A module can also optionally specify:
    BSLUG_MODULE_GAME("RMC?");

The BSLUG_MODULE_GAME macro defines which games your module supports. This is
done using the disc ID. For example, RMCP is the disc ID of Mario Kart Wii in
PAL regions. Specifying BSLUG_MODULE_GAME("RMC?") would mark the module as
compatible with any region of Mario Kart because ? is a wildcard. Omitting this
declaration means the module is compatible with all games. Any characters not
specified are treated as wildcards so "RMC?" is the same as "RMC".

The action of the BrainSlug loader can be controlled with three commands:
    BSLUG_REPLACE
    BSLUG_MUST_REPLACE
    BSLUG_EXPORT
    
BSLUG_REPLACE and BSLUG_MUST_REPLACE instruct BrainSlug to replace one of the
games functions with another function, for example one you've defined. The
syntax is:
    BSLUG_REPLACE(game_function, replacement);
The only difference between the two is that if the function cannot be found in
the game, it is skipped for BSLUG_REPLACE but the whole module fails to load
with an error message displayed to the user for BSLUG_MUST_REPLACE. Each module
can only replace any given game function once, but multiple modules can replace
the same function.

The idea of the BrainSlug replacement system is to allow you to extend game
functionality by intercepting method calls. For example, you could intercept
library calls and log them. To do this, simply write a method with the same
arguments and return value as the method you are replacing and add the
BSLUG_REPLACE or BSLUG_MUST_REPLACE macro as above. Whenever the game attempts
to call the method you've replaced, it will instead branch to your method. The
best part is: the code you write can still call the original game method. Thus
a wrapper can be something like:
    int myIOS_Open(const char *path, int mode) {
        int result = IOS_Open(path, mode);
        printf("IOS_Open(%s, %d) = %d\n", path, mode, result);
        return result;
    }
    BSLUG_REPLACE(IOS_Open, myIOS_Open);
    
If multiple modules replace the same method, then one of them will be made to
call the other's replacement if it attempts to call the original method. So if
two modules both included the above code, the logging message would be displayed
twice. The order of these calls is dependant on the order of loading by the
loader, so should not be relied upon.

The unfortunate thing about this environment is you can only replace or call
game functions for which BrainSlug symbol information is available. The symbols
are defined by the sd:/bslug/symbols directory on the SD card. More information
can be found in the symbols/README file.

BSLUG_EXPORT makes a symbol available to other BrainSlug modules. The intention
of this is to allow library modules to be written which don't actually modify
the game, but instead just provide functionality on top of the game.

Some observations about BrainSlug module coding:
    * Games don't (typically) just have one heap, so there is no `malloc' for
      you to call. Instead they provide allocation methods to specific heaps
      (although only one `free' method). Ideally write your module to avoid
      memory allocation all together. If you must use their heaps, it won't be
      portable between games and they have a habit of freeing entire heaps
      automatically when you're not expecting it. You have been warned.
    * Games don't (typically) use stdio so don't expect fopen to even be
      available. The games tend to prefer specific methods like DVDOpen or
      NANDOpen.