Skip to content

Reference: Unlock all characters + Nitros Oxide in character select grid#27

Open
FeatureSpitter wants to merge 1 commit into
CTR-tools:masterfrom
FeatureSpitter:feature/unlock-all-characters-oxide
Open

Reference: Unlock all characters + Nitros Oxide in character select grid#27
FeatureSpitter wants to merge 1 commit into
CTR-tools:masterfrom
FeatureSpitter:feature/unlock-all-characters-oxide

Conversation

@FeatureSpitter

Copy link
Copy Markdown

Note: This PR is not intended to be merged. It serves as a reference implementation for anyone wanting to unlock all characters and add Nitros Oxide to the character select menu natively.

Summary

All changes are gated behind #ifdef CTR_NATIVE — the original PSX codepath is completely untouched.

1. Unlock all characters on boot (MainMain.c)

Sets gameProgress.unlockFlags |= UNLOCK_CHARACTERS immediately after GAMEPROG_NewGame_OnBoot(), so all secret characters appear with their proper cyan selection borders from the start.

2. Nitros Oxide as 16th selectable character (D230.c, ovr_230.h, MM_Characters.c)

  • Expanded CharacterSelectMeta arrays from [0xF] to [0x10]
  • Expanded TransitionMeta arrays from [0x15] to [0x16]
  • Added Oxide entry at bottom-right of grid (0x160, 0xAE) with D-pad navigation:
    • Right from Fake Crash → Oxide
    • Down from Papu → Oxide
  • Bumped NUM_ICONS from 0xF to 0x10
  • Updated all layouts: csm_1P2P, csm_1P2P_limited, csm_3P, csm_4P

3. Runtime model loading for Oxide's preview (MM_Characters.c)

The main menu .lev only ships 15 character models. Oxide's hi-res racing model lives in BIGFILE at BI_RACERMODELHI + NITROS_OXIDE. On first access in MM_Characters_GetModelByName, the code:

  1. Synchronously loads and pointer-relocates the model via LOAD_DramFile(..., -1)
  2. Caches the resulting struct Model * for subsequent frames

This gives a proper 3D preview in the character select window without modifying any binary assets.

4. Asset extraction script (extract_assets.sh)

Robust script for extracting game assets from a retail NTSC-U disc image:

  • Supports both .bin/.cue and .iso input
  • Builds bchunk from source if not installed
  • Extracts XA audio as raw 2352-byte sectors (required for voices/music to work in ctr-native)
  • Validates all extracted files

Grid layout

Row 1: [Tropy] [Crash] [Cortex] [Tiny]  [Coco]      [Pinstripe]
Row 2: [Roo]   [N.Gin] [Dingo]  [Polar] [Pura]      [Papu]
Row 3:         [K.Joe] [Penta]  [Fake Crash] [N.OXIDE]

Screenshots

Oxide appears in the grid with proper icon + borders, and his 3D kart model renders in the preview window.

Test plan

  • All 16 characters visible and navigable with D-pad
  • Oxide's preview model loads correctly from BIGFILE
  • Character borders (cyan) display for all unlocked characters
  • No regressions: existing 15 characters work identically
  • Builds cleanly on Linux x86 (32-bit)

All changes are gated behind #ifdef CTR_NATIVE so the original PSX
codepath is untouched.

Summary of changes:

1. Unlock all characters on boot (MainMain.c)
   - Set gameProgress.unlockFlags |= UNLOCK_CHARACTERS after
     GAMEPROG_NewGame_OnBoot() so all secret characters appear with
     their proper cyan selection borders from the start.

2. Add Nitros Oxide as 16th character in the selection grid (D230.c,
   ovr_230.h, MM_Characters.c)
   - Expand CharacterSelectMeta arrays from [0xF] to [0x10]
   - Expand TransitionMeta arrays from [0x15] to [0x16]
   - Add Oxide entry at bottom-right of grid (0x160, 0xAE) with
     proper D-pad navigation links
   - Update Fake Crash (right→Oxide) and Papu (down→Oxide) nav
   - Bump NUM_ICONS from 0xF to 0x10

3. Load Oxide's 3D preview model at runtime (MM_Characters.c)
   - The main menu .lev only contains 15 character models; Oxide's
     model is stored separately in BIGFILE as BI_RACERMODELHI+15.
   - On first access, synchronously load and relocate his model via
     LOAD_DramFile, then cache the pointer for subsequent frames.

4. Asset extraction script (extract_assets.sh)
   - Supports .bin/.cue and .iso input
   - Extracts XA audio as raw 2352-byte sectors (required for voices)
   - Builds bchunk from source if not installed

5. Convenience run script (run.sh)
@kkv0n

kkv0n commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

well my intention is not to sound harsh or anything, but we already have mods doing what you are describing publicly on CTR-ModSDK repo, for oxide and for unlocking everything custom track mods already documented how

@FeatureSpitter

FeatureSpitter commented Jun 29, 2026

Copy link
Copy Markdown
Author

well my intention is not to sound harsh or anything, but we already have mods doing what you are describing publicly on CTR-ModSDK repo, for oxide and for unlocking everything custom track mods already documented how

Oh yeah I am quite outside of this loop. I just saw this repo (https://github.com/CTR-tools/ctr-native) on youtube as the first project fully porting CTR to PC, came here and started toying with it. I barely have context.

Do we still need that ModSDK given that ctr-native exists now?

Btw the link in the README for the ghidra folder is broken (https://github.com/CTR-tools/CTR-ModSDK/tree/main/psx-modding-toolchain/games/CrashTeamRacing/ghidra)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants