Texture Pack Replacement - X-Hax/SADXModdingGuide GitHub Wiki
Texture edits are the easiest mods to make. They usually don’t require custom code, and unless you’re adding new textures or replacing entire levels you don’t need to compile a DLL in Visual Studio. Let’s discuss SADX textures in general and then focus on making a simple texture swap mod.
Prerequisites
- SA Tools for TextureEditor, a tool that can open, convert and export PVM, GVM, PVMX and PAK files and for ArchiveTool which exports PVR files from PVMs.
- PVR Viewer tool and Adobe Photoshop with the PVR Plugin for the PVR file format.
- (Optional) the oxipng tool to optimize PNG textures
Of course, you also need to know where the texture you want to edit is located. Use this page to locate the PVM archive with the textures you need to edit.
Understanding textures
Before working with textures in SADX it’s important to understand what defines a texture. There are several characteristics that are common to textures in all games, and some that are specific to SADX. There are also several format quirks specific to SADX.
Each texture in SADX is defined by the following:
- Dimensions: this is the horizontal and vertical size of the texture, like 128×128 or 2048×2048.
- Pixel format, which can be one of the following for PVR textures: RGB565 – an opaque texture with 5 bits for red and blue and 6 bits for green. ARGB1555 – a transparent texture with 5 bits for each color and 1 bit for transparency (so each pixel can be either fully transparent or fully opaque) ARGB4444 – a transparent texture that uses 4 bits for each color and transparency. All of the above pixel formats are lossy, which means the original texture loses some color information when saved as PVR. RGB565 is the best format for opaque PVR textures, ARGB1555 works best for textures with basic transparency, and ARGB4444 should be used for textures that need partial transparency. The above limitations are irrelevant when using PNG textures. PNG textures are ARGB8888, storing 8 bits for each color and transparency, which is effectively lossless.
- Data format: This applies only to PVR textures. A rectangular PVR texture uses a different format than a square PVR texture, there are also various VQ (compressed) formats and mipmap variations of the above. Unless you’re modding the Dreamcast version, you probably shouldn’t worry about this.
- Mipmaps: a PVR texture may include smaller copies of itself to display from a distance. This helps achieve a smoother look even without texture filtering. Dreamcast and Gamecube versions of the game had mipmapped textures, however in the PC version and all subsequent ports the mipmaps were removed, even though the game still supports them. The Mod Loader has an option to generate mipmaps while the game is running, so this is no longer a problem.
- In addition, each texture in SADX has a Global Index value, which is important so we’ll discuss it in a separate section.
Texture caching and Global Indices
Global Index (GBIX) is a value used in the game’s texture caching system. Each texture in SADX has an index that is a number using anywhere between 1 and 10 digits. For example, part of the “press start” texture in AVA_GTITLE0_E.PVM
has a global index of 3489661283
, while chair2.pvr
in ADVSS00.PVM
uses a global index of 13
. In PVR textures the GBIX value is embedded in the texture file. When using PNG textures the GBIX value is loaded from the texture pack’s index.txt.
Before the game loads a new texture, it compares the new texture’s global index value with indices of other textures that are already loaded. If a match is found, the game reuses the already loaded texture instead of loading the new one, so the developers could put the same texture into multiple PVMs without making the game reload it between levels. This helped minimize memory usage in the Dreamcast days, but today the global index system is more of a nuisance than anything else. To make sure your textures load correctly you must double check all your textures for GBIX conflicts.
The game has a lot of textures that share the same GBIX value. Sometimes that can cause your custom textures to load incorrectly, or override textures in unwanted areas. You can check this list by MainMemory to find textures that use the same GBIX values. If you’re replacing a texture that has the same GBIX as textures in other PVMs, it might be a good idea to give it a unique GBIX value that isn’t used by anything else in the game. If you want to take advantage of this system in your mod, give the same GBIX value to each series of identical textures, and the game will load the identical textures only once.
Understanding texture lists and texture order
When working with PVM archives and texture packs in SADX you have to be extremely careful about the order of your textures in the PVM/texture pack. This is because of the way the game’s texturing system works. When the game loads a PVM or a texture pack, it associates the loaded textures with a structure known as texture list (texlist). Before displaying a texture or rendering a model, the game’s code specifies a texlist, which also determines which of the loaded PVMs/texture packs the game should pull the textures from. The game then uses texture IDs to determine which texture to display. For example, a texture ID of 0
will load the first texture in the PVM. Texture IDs are usually specified in a model’s material, but sometimes the game can override material texture IDs (for example, when using animated textures). GUI textures are rendered using function calls that have the texture ID as one of the arguments. So if you replace some textures in a PVM, the replacement PVM/texture pack must have exactly the same order of textures. Texture filenames are not important, the only thing that matters is the order.
Note: If you do need to change the order of textures in your texture pack, you can do so by rearranging lines in index.txt
.
The most important part of a texture list is the number of textures. If the game attempts to set a texture ID that is higher than the number of textures in the texlist, it will crash. This is why it’s important to make sure your replacement PVM/texture pack has the same number of textures as the original PVM. If you’re only replacing existing textures without adding new ones, just matching the texture order and number of textures is enough.
Sometimes (for example when you want to replace a level) you may need to use more textures than the original PVM provides. Adding new textures to the texture pack is easy (just append a list of new texture filenames and global indices at the bottom of index.txt), but the number of textures in the texlist is pre-determined in code, so unless the texlist is resized too the game will crash. Luckily, recent versions of the Mod Loader attempt to resize texlists automatically when a higher texture number in the PVM/texture pack is detected.
Texture file formats
Original SADX textures come in PVM archives, which contain textures in the PVR format. There are also a few single textures in the system folder, which are also PVR. Thanks to the Mod Loader SADX can read a variety of texture formats in addition to PVR, such as PNG, JPG, or DDS. Let’s have a look at common texture file formats:
- PVR is the Dreamcast’s native texture format. PVR textures can be put into a container file with the PVM extension (which can also be compressed into PRS archives). While not bad for its time, PVR has limitations that make its usage problematic with custom and high resolution textures:
Pixel formats: either RGB565, ARGB1555 or ARGB4444 – all lossy.
Dimensions: must be a power of 2 (
8×8
,16×16
,128×128
etc.), maximum size1024×1024
. - GVR is a version of the Dreamcast’s PVR format adapted for the Gamecube and Wii. It has fewer limitations than original Dreamcast PVR. GVR textures can be put into GVM archives. This texture format is used by SADX on the Gamecube, but you can’t use GVR textures with SADX Mod Loader (at least not yet), so we won’t be covering them. If you need to extract textures from the Gamecube version of SADX and convert them to PNG, you can use Puyo Tools to extract GVM archives.
- PNG is a common image format meant for high quality graphics. This is the best format to use with custom textures.
- JPG is a common image format meant for storing photos. It takes less space than PNG, but it uses compression and is almost always lossy. Normally you’d want to use PNG instead of JPG, but in some cases JPG offers advantages – for example, when you have a lot of textures where slight quality loss may be acceptable, or when your textures are made from real photos. In such cases it might be a good idea to use this format.
- DDS is a file format meant for storing textures. DDS textures are the fastest to load because the GPU can load them as-is without decoding. DDS textures have many pixel formats and allow for various kinds of compression. The problem with using DDS textures is that lossless DDS textures take up a lot of space (more than PNG), and using compression can reduce the texture’s quality to PVR levels, in which case you might as well use the game’s native PVR format. You can use DDS textures with the Mod Loader when your source textures are already in this format – for example, some textures in SADX Steam are DDS.
Managing textures in SADX mods
There are two main ways to approach textures in SADX mods, which have their own pros and cons:
PVM archives in the mod’s system folder.
Pros: Fastest load times possible, support for built-in mipmaps, “native” texture format.
Cons: Quality degradation due to compression and format conversion, strict dimension limitations.
Use cases: When your textures are already in the PVR format – for example if you work with textures from the Dreamcast version of SA1, or from other games that use this texture format.
PVMX archives in the mod's textures folder.
Pros: Allows to use lossless PNG textures, easy to use with custom high resolution textures, no dimension restrictions, possible to override the original texture’s dimensions with HD textures.
Cons: Slower load times, no built-in mipmap support (although the Mod Loader’s mipmap generation feature compensates this).
Use cases: When you want to add custom textures or modify existing textures without worrying about quality loss.
Use PVM or PVMX Texture Packs with Texture Editor
The best way to extract textures from PVMs today is Texture Editor in SA Tools.
- Click "Open" and open you PVM archive
- Choose the texture you want to edit and export it
- The texture will be converted into PNG, you can edit it using the editor of your choice
- Import the texture back
- Save
If you save as PVM (quality loss), put it into MODFOLDER\system
folder.
If you save as PVMX (highest quality), put it into MODFOLDER\textures
folder.
Use the Mod Loader's Texture Pack system
Alternatively, you can click "File" then "Export Texture Pack" in Texture Editor, which will export every texture with an index. Place these files into MODFOLDER\textures\PVMNAME
and the Mod Loader will take care of the rest. Note that depending on the number of textures load times can be affected. To minimize load times, make a PVMX archive out of your PVMNAME
texture folder.
Edit PVRs directly
Extracting SADX PVMs
To extract PVR textures from PVMs without format conversion, use ArchiveTool from SA Tools. Put the PVM file you want to extract into the same folder with ArchiveTool (or add the path to ArchiveTool to your PATH environment variable), open the command prompt window in the folder and run the tool like this (here we’ll be using ADVSS00.PVM as an example):
ArchiveTool ADVSS00.PVM
If your archive is PRS compressed (for example if you got it from the Dreamcast version), you can unpack the PRS right away:
ArchiveTool ADVSS00.PRS
The tool will produce a folder named ADVSS00 with PVR textures and a texture list named ADVSS00.txt. If you only want to replace existing textures, you don’t need to edit the texture list. If you want to add new textures, open ADVSS00.txt and add a list of your new textures at the bottom. Make sure the new textures are in the PVR format!
Editing PVRs
The easiest way to edit PVR textures without format conversion is to open them in Photoshop with the PVR plugin. To install the plugin, place pvrtex.8bi
in Photoshop\Plug-ins\File Formats
and restart the program. You can now open, edit and save PVR files in Photoshop.
Rebuilding the PVM archive
Go to the folder with your textures subfolder, open the command prompt window and run ArchiveTool again:
ArchiveTool ADVSS00
The tool will produce a PVM file, which you can put into the mod’s system folder. You can confirm the contents of the PVM file by opening it in Texture Editor.
If you need to PRS compress the PVM file (for example if you want to replace textures in the Dreamcast version) you can do it with the -prs
command line switch:
ArchiveTool ADVSS00 -prs
Note: If you want to use PRS-compressed PVMs with the Mod Loader, rename the file to PVMNAME.PVM.PRS
.
Replacing single PVR textures in SADX system folder
There are several textures in SADX that aren’t inside PVMs – for example, all level objectives (“Rescue Tails” etc.) and the snowboard texture are in single PVR files in the system
folder. Replacing these textures is a bit more involved than replacing textures in PVMs. The two methods described above need some adaptations:
-
If you’re replacing PVR textures with other PVR textures, you need to put the replacement PVRs in the mod’s
system
folder. However, you must make sure the GBIX values match between the original and the replacement texture. If your texture has a different GBIX, you need to change it by resaving the texture in Photoshop with the PVR plugin. -
If you’re replacing single PVR textures with PNG/DDS/JPG textures, you need to make a special texture pack. Create
index.txt
in your mod’stextures
folder (no subfolders!) and add a list of global indices and replacement texture filenames. The global indices must match between original PVR textures and index.txt. Here are some examples:
361009,ABC_TXT.PNG
13400000,HYOJI_EMBLEM0.PNG
13400001,HYOJI_EMBLEM1.PNG
305005,ST_064S_SCORE.PNG
90000,HYOJI_BALLS_E.PNG
400999,B32ASCII.PNG
400999,B32ASCII_J.PNG
365771,STAFFROLL_TXT.PNG
10000369,T_MISTICRUIN_E.PNG,512x256
10000370,T_EGGCARRIER_E.PNG,512x256
10000371,T_STATIONSQUARE_E.PNG,512x256
You can find a list of all global indices in the game on MainMemory's site.
index.txt
Adding texture dimensions to Sometimes the game expects a texture to be a certain size, and if you replace it with a higher resolution texture it will display incorrectly ingame. This becomes a problem with GUI textures in particular, which use hardcoded layouts and are scaled in different ways. To avoid this issue, you can specify the original texture’s dimensions in index.txt
. For example, ast_hasi09 in ADVSS00 is 32×32 pixels, so we just add 32×32 after the texture filename in index.txt
:
147,ast_hasi09.png,32x32
This step isn’t always required and generally you don’t need it for level textures, but to be absolutely safe it’s better to fill in the dimensions for all textures in the PVM you’re replacing.
Optimizing PNG textures
Depending on how you edited the textures it may be possible to reduce their size without quality loss. You can do that by optimizing the PNG textures with a tool called oxipng. Run it from the textures
folder like this:
oxipng -r ADVSS00
This will optimize textures in the ADVSS00 folder without any quality loss.