Splitting Assets from Code

From N64brew Wiki
Revision as of 16:45, 26 September 2021 by Buu342 (talk | contribs) (Added a new section that I'm going to need)
Jump to navigation Jump to search

This first page will cover the important aspect of keeping your game assets separate from the game code (where assets are things like textures, models, sounds, etc...). Depending on how you've structured your project, or more importantly how far you are into it currently, this can be a relatively simple or relatively difficult task.

Start by looking at the original sample, before any modifications. It is a simple ROM with two rooms that can be switched between by pressing the A button, with a texture that is displayed in the middle.

If you take a look at the makefile, you will see that our textures (spr_bear and spr_burger) are being compiled as C code and then being linked into the codesegment. It's not a big concern for this small project, but due to the 1MB IPL limit, this will become a problem as the project gets bigger. The idea here is that we want to have the assets elsewhere in the ROM, and we load them from the cartridge only as we need them.

So first and foremost, lets move our assets over to ROM.

Moving our assets to ROM

For simplification reasons, we're going to convert our textures to binary data, instead of keeping their current form as C arrays. You should be able to do this for pretty much any sort of assets your game will need, such as static display lists. The process of actually converting your data to binary form will not be covered here, as there are plenty of tools to do that for you already.

Once your assets are in a binary format, you must remove the original code files from your makefile (as they're redundant) as well as any #include's relating to them. You can leave the array pointers in the code for the time being, as they'll be substituted later.

The actual process of putting your assets in ROM depends on your SDK setup:

Your Spec file, before adding the assets to it, would look something like this:

beginseg
    name    "code"
    flags   BOOT OBJECT
    entry   nuBoot
    address NU_SPEC_BOOT_ADDR
    stack   NU_SPEC_BOOT_STACK
    include "codesegment.o"
    // Microcode includes here
endseg

// Wave's aren't used for anything in the PC SDK, they're just for visual reference
beginwave
    name    "original"
    include "code"
endwave

Adding in new raw assets is as simple as creating a new segment and specifying the RAW flag. For instance, having the data from spr_bear.c converted into binary form (with the name spr_bear.bin) and linking it to our ROM is as simple as:

beginseg
    name    "spr_bear"     // This name is important, and should be unique
    flags   RAW            // Specify that this segment is raw data (and not code)
    after   "code"         // Specify to put this data in ROM, right after our code segment (Although you can omit this line if you want)
    include "spr_bear.bin" // The file to link
endseg

Do this for all the assets, and you're almost done. The next step is to open a C header file (or better yet, create a new one) and to create some extern calls for your new segments:

extern u8 _spr_bearSegmentRomStart[];
extern u8 _spr_bearSegmentRomEnd[];

Remember that segment name I told you that was important and had to be unique? Whatever you set your segment name to, it needs to match the extern's. Meaning, if you called your segment NAME, then you would need to define the extern's as _NAMESegmentRomStart and _NAMESegmentRomEnd respectively.

If you want to know more about Spec files, the online manuals do not contain a lot of information about them. Instead, it is highly recommended that you check out the Specfile Format chapter of the N64 EXEGCC Compiler User Guide for more information.

TODO

Now that our assets are in ROM, we need to DMA them to be able to use them in our game.

Loading assets from ROM

TODO

Having a buffer in the codesegment

TODO

Having a buffer somewhere in RAM

TODO