RVGL Reverse Engineering

Post about the progress of your projects.
User avatar
sinaosal
Posts: 42
From: The Re-Volt Garage

RVGL Reverse Engineering

Unread post by sinaosal » Fri Feb 20, 2026 3:13 pm

RVGL Reverse Engineering

Welcome to the RVGL Reverse Engineering post! Here i will be documenting the progress on the the code for RVGL via Ghydra (A reverse engineering software), for future projects.

19 February 2026:
Yesturday i had a huge breakthrough in rvgl.exe code. I had found the main loop of the game and the setup code.
List of function i had found:
- Intro 'Made by the RVGL Team' source code.
- How the program reads the .inf track file.
- How the program reads the .txt parameters car file.
- How the program reads the frontend files.
- Single Player setup code.
- Multiplayer setup code.
- Re-Volt UI setup and main code.
- Replay code.
- How the program reads cups.
From LJP
:blender: :re-volt:
User avatar
sinaosal
Posts: 42
From: The Re-Volt Garage

Re: RVGL Reverse Engineering

Unread post by sinaosal » Mon Feb 23, 2026 2:19 am

New discoveries on 2026-02-20

Learned how most SDL2.dll functions (Mostly Analized)
SDL2.dll is for:
Window Management
Input (Keyboard, Mouse or Controller)
OpenGL Context Creation
Event Loop

SDL2.dll size: 2.13MB


libGLESv2.dll is fully analyzed
libGLESv2.dll is for:
All Rendering Calls
Context Management (TLS-Based)

libGLESv2.dll size: 6.9MB


OpenAL32.dll is mostly analized
OpenAL32.dll is for:
The Audio System

OpenAL32.dll size: 1.71MB


libenet-7.dll is mostly analyzed
libenet-7 is for:
Networking and Multiplayer

libdiscord-rpc.dll is mostly analyzed
libdiscord-rpc.dll is for:
Discord Rich Presence (Displays your RVGL activity)


- Made the Game Loop Structure, with a few functions like:
The Main Entry Point function that:
Parse command-line arguments
Init SDL subsystems
Load resources (like tracks, cars, ex.)
and Set game state function pointer.

Main game loop (while !quit):
- Discovered Function that Processes SDL events (input)

libGLESv2.dll is fully analyzed. Here are full detials:
Type: Google ANGLE (Almost Native Graphics Layer Engine)
Purpose: Translate OpenGL ES Calls

Things discovered in libGLESv2.dll:
- Global TLS Index (Purpose: Stores Windows TLS slot index for GL Contexts)
- Context Architecture

Key functions (that are mapped now):
GetCurrentContext() - Purpose: Main Context getter (called by ALL 601 functions)
TlsGetValue_Wrapper() - Purpose: Wraps Windows TlsGetValue
CreateContext() - Purpose: Allocates 32-bye handle, and calls init
ValideContext() - Purpose: Checks context_lost_flag and handles errors
InitializeHandle() - Purpose: Initializes 32-byte handle structure
IsContextLost() - Purpose: Returns info (byte) at a specific address

Core GL functions discovered:
glDrawArrays (Validation Function Discovered?: True, Implementation Function Discovered?: True)
glDrawElements (Validation Function Discovered?: True, Implementation Function Discovered?: True)
glClear (Validation Function Discovered?: True, Implementation Function Discovered?: True)
glUseProgram (Validation Function Discovered?: True, Implementation Function Discovered?: True)
glBindTexture (False to all)
glBindBuffer (False to all)

(Context Flow Diagram will be soon available.)

RVGL.exe Analysis:
- Entry Point and Initialization is Discovered
- Main Entry Function is Discovered
- Command-Line Arguments are Discovered (All commands that can be used in Launch Parameters of the RVGL Launcher)
- Game State System Discovered (w/ Game State Function Pointer)
- Event Processing Loop Discovered
- Discovered how SDL Event Types are Handled. (Funny enough, every build includes "Finger Events" for mobile.)
- Discovered Key Bindings (I think, im not sure on this one.)
- Discovered SDL Event Processing Functions:
> Main event loop (Processes all events)
> Touch Handler (Multi Touch for mobile, very unoptimized, is included in every build)
> Window Focus gain (Mouse button 0x0c handler)
> Window focus loss (Mouse button 0x0d handler)
> Update function (I haven't looked at that one yet, but its called often and has unknown purpose)
- Discovered multiple Global flags, including:
> Game Quit flag
> Game state function
> Window State
> Multiple other unknown state flags that i have to analyze)

Car system discovered:
- The car system (full code for reading parameters.txt)
- .prm (binary - not yet analyzed)
- carbox.bmp, and texture.bmp
(Thankfully found the goldmine for car parameters reading - it includes mostly all stats that can be modified, but how it impacts the game isnt fully analyzed yet
Key car loading functions mostly analyzed, including:
Load all cars, Initialize cars, Parse parameters.txt (read through and parse), Finalize car loading, Read string parameters, read byte parameters, read integer values.

Track system discovered:
File structure:
.inf is fully analyzed
.w is not yet analyzed
other file formats aren't found yet.
Track .inf structure is also fully analyzed and how it reads. (i need to analyze how it impacts the game though)
Track loading functions that i have discovered:
Load all tracks info (from main menu - main track scanning loop)
Load the track .inf file - parse single track's .inf file
Other functions include: Check directory exists, and check file exists.
Other init functions are not yet analyzed. i have to analyze those addresses...

going back to RVGL.exe main:
Multiple Game Loop functions are analyzed/discovered:
Event Proccessor - Handles SDL events (input, window, touch) - Analyzed fully
Pause Handler - Called When Window is minimized/in background - Not yet analyzed
Splash/Logo State - Initial Game State (Dev Logos) - Analyzed Fully
Racing Game Loop - Main Racing State - Not yet analyzed
Multiplayer State - Lobby/Multiplayer Mode - Almost analyzed...
Other unknown state that i need to analyze...
And the Replay state that i need to analyze.

- I still need to analyze a bit of Rendering Functions.

Memory Addresses & Data structures discovered:
Game State that are analyzed fully:
- Current Game State Function Pointer
- Game Quit
- The A and D key flags

Window & Display critical global variables that are analyzed fully:
- Window Minimized Flag
- SDL Window Pointer
- Window Width
- Window Height
- Multisample Level

Game Settings (Launch Parameters and more) that are discovered:
- No sound flag (-nosound)
- No Joystick flag (-nojoy)
- No Gamma flag (-nogamma)
- No User Profiles flag (-nouser)
- Texture Info Flag (what size of textures you pc can handle) (-texinfo)
- Large Replays Flag (-largereplays)
- Edit (window) scale? (-editscale)

Touch Inputs are discovered but are not analyzed ( almost 0 knowledge, just ideas)
Network is somewhat analyzed, but i wont put it out yet, because im not sure yet about the variables and their info)
Profile variables are somewhat analyzed, but same as network, im not sure and i have to analyze it more

I have multiple hook points i can get, starting off in libGLESv2.dll:
- Hook all GL Calls with one function, and then log, modify or inject custom data.
- Hook specific rendering, so i could intercept draw calls, count triangles and replace geometry
- I can also hook texture binding so i could replace all textures.
- i can hook shader usage and inject more custom shaders.

Here are multiple RVGL.exe hooks i can put:
- Hook game state function pointer, so i could inject custom logic after game state runs, also includes custom rendering and debug overlays.
- Hook event processing, so i could add custom input handling, shortcuts and debug commands
- Hook car loading, so i could modify car stats directly, add custom physics or add hidden cars
- Hook track loading, so i can add custom challenges

**This took me ages to write lol
** Expect some things not to be correct.
From LJP
:blender: :re-volt:
User avatar
sinaosal
Posts: 42
From: The Re-Volt Garage

Re: RVGL Reverse Engineering

Unread post by sinaosal » Sat Mar 14, 2026 11:47 pm

RVGL New Reverse Engineering Update:

Table of Contents:

Project Overview
Architecture Discovery
libGLESv2.dll - Full ANGLE Analysis (95%)
RVGL.exe Core Game Loop
Command-Line Arguments (27 Discovered)
Game State Machine
SDL Event Processing & Input System
Car System - Static Pool & Runtime Entities
Track / Level System
AI System - The 1,517-Line Brain
Waypoint & Route Navigation
Physics System
Race Session System
Ghost Car / Replay System
Rendering Pipeline - Full Discovery
Audio System - Full OpenAL Analysis
Level Editor System
Animation System
Weapon / Projectile System
Camera Entity System
Networking / Multiplayer
Miscellaneous Systems
Complete Data Structures
Complete Memory Map - All Global Variables
GL Function Pointer Table
File Formats Discovered
Complete Function Index (250+)
XMenu Mod Framework - Design & Implementation
Modding Opportunities & Hook Points
Overall Completion Status
What's Left / Priority Queue

────────────────────────────────────────

1. Project Overview

This is a deep reverse engineering effort of RVGL (Re-Volt GL), a modern Win64 rebuild of the classic 1999 RC car racing game Re-Volt. The goal is to fully understand the game engine for modding purposes - ultimately building XMenu, a powerful mod framework inspired by Geode (Geometry Dash) and ZMenu (GTA).

What is RVGL?
• A community-maintained rebuild of Re-Volt using OpenGL ES (via Google ANGLE → DirectX 11)
• ~2.95 MB executable + ~6.9 MB rendering DLL
• Supports Windows, Linux, macOS, Android, iOS
• Active community with custom cars, tracks, and online multiplayer

What did we do?
• Decompiled 222,000+ lines of Ghidra output from rvgl.exe
• Fully analyzed the libGLESv2.dll (Google ANGLE) context system
• Mapped 250+ functions, 60+ global variables, 10+ data structures
• Documented the entire game architecture from entry point to GPU draw calls
• Designed and started implementing XMenu mod framework
• Created comprehensive documentation (this file and 6+ supporting docs)

────────────────────────────────────────

2. Architecture Discovery

Runtime Component Map

Code: Select all

┌─────────────────────────────────────────────────────────────┐
│ RVGL.exe (2.95 MB)                                          │
│ - Main game logic, physics, AI, car/track loading           │
│ - 222,000+ lines of decompiled C                            │
│ - Dynamically loads GL via SDL_GL_GetProcAddress             │
└────────────┬────────────────────────────────────────────────┘
             │
             ├──→ SDL2.dll (2.13 MB)
             │    - Window management (create, resize, focus)
             │    - Input (keyboard, mouse, controller, 4-touch)
             │    - OpenGL context creation
             │    - Event loop (SDL_PollEvent)
             │    - Threading (SDL_CreateThread, mutexes, semaphores)
             │    - Performance counters (SDL_GetPerformanceCounter)
             │
             ├──→ libGLESv2.dll (6.9 MB) ⭐ 95% ANALYZED
             │    - Google ANGLE (Almost Native Graphics Layer Engine)
             │    - Translates OpenGL ES calls → DirectX 11
             │    - 601 exported GL functions
             │    - Thread-local context management via Windows TLS
             │
             ├──→ OpenAL32.dll (1.71 MB) ⭐ FULLY ANALYZED
             │    - Audio system (SFX + BGM streaming)
             │    - 128 AL sources, priority-based preemption
             │    - 38 built-in WAV sound effects
             │    - OGG/WAV music streaming (250KB buffer)
             │
             ├──→ libenet-7.dll
             │    - ENet networking library
             │    - Multiplayer (P2P, lobby, multicast, late-join)
             │
             └──→ libdiscord-rpc.dll
                  - Discord Rich Presence integration
                  - ⭐ Used as XMenu proxy DLL injection point
Memory Layout

RVGL.exe Memory Organization:

Code: Select all

  0x00400000 - 0x004FFFFF : Code (.text) - all game functions
  0x00661000 - 0x006E3FFF : Initialized data (.data) - settings, flags
  0x006FAB50 - 0x00F3FFFF : Large data arrays - cars, tracks, race tables
  0x0AE00000 - 0x0AEFFFF  : Runtime allocations - SDL state, touch, network
  0x016CF000 - 0x01815FFF : Rendering state - textures, batch buffers, cameras
libGLESv2.dll Memory Organization:

Code: Select all

  0x68000000 - 0x681FFFFF : Code (.text) - ANGLE implementation
  0x6814C000 - 0x6814FFFF : Data (.data) - TLS index, globals
  0x68200000 - 0x682FFFFF : Read-only (.rdata) - vtables, strings
────────────────────────────────────────

3. libGLESv2.dll - Full ANGLE Analysis (95%)

Overview

Google ANGLE (Almost Native Graphics Layer Engine) translates OpenGL ES API calls into DirectX 11 calls on Windows. Every GL call RVGL makes goes through this DLL.

Thread-Local Storage (TLS) Context System

Every single one of the 601 exported GL functions goes through the same pattern:

Code: Select all

void glSomeFunction(params) {
    GLContextHandle* handle = GetCurrentContext();  // 0x67c77ae0
    if (handle == NULL) return;
    RealGLContext* ctx = *(handle + 0x18);
    ctx->call_metadata = &"glSomeFunction";
    if (ctx->debug_flag != 0 || ValidationFailed(ctx, params)) {
        ExecuteFunction(ctx, params);
    }
}
TLS Index Global

Code: Select all

Address: 0x6814c020
Type: DWORD
Initial Value: 0xFFFFFFFF (-1 = uninitialized)
Purpose: Windows TLS slot index for per-thread GL contexts
GLContextHandle (32 bytes)

Code: Select all

struct GLContextHandle {
    void*    vtable;           // +0x00 → points to 0x68214410
    void*    reserved;         // +0x08 = NULL
    uint64   versionFlags;     // +0x10 = 0x30a000003000
    RealGLContext* realContext; // +0x18 → pointer to actual context
};
// Stored in TLS (one per thread)
// Retrieved via TlsGetValue(DAT_6814c020)
RealGLContext (14,833+ bytes!)

Code: Select all

struct RealGLContext {
    byte    header[136];             // +0x0000..+0x0087
    char    debugFlag;               // +0x0088 (0=normal, 1=debug)
    byte    pad[7];                  // +0x0089..+0x008F
    void*   currentFunctionName;     // +0x0090 (string ptr)
    void*   drawCallParameters;      // +0x0098
    // ... thousands of bytes of D3D11 state, shader cache, texture bindings ...
    byte    contextLostFlag;         // +0x39f1 (0=OK, 1=GPU reset/lost)
};
Context Flow

Code: Select all

Every GL call:
  ↓
GetCurrentContext (0x67c77ae0)
  ├─ Check: DAT_6814c020 == -1?
  │   └─ YES → TlsAlloc(), store in DAT_6814c020
  ├─ TlsGetValue(tlsIndex) → GLContextHandle* or NULL
  ├─ If NULL → CreateContext (malloc 32 bytes, init, TlsSetValue)
  └─ ValidateContext → check contextLostFlag at +0x39f1
       ├─ If lost → error 0x505 "Context has been lost."
       └─ Return validated context
Key Context Functions Analyzed

Code: Select all

Address      Name                        Purpose
0x67c77ae0   GetCurrentContext()         Main context getter - called by ALL 601 GL functions
0x67f20810   TlsGetValueWrapper()        Wraps Windows TlsGetValue
0x67c779b0   CreateContext()             Allocates 32-byte handle, calls init
0x67cec510   ValidateContext()           Checks context_lost_flag, handles errors
0x67cec310   InitializeContextHandle()   Initializes 32-byte handle structure
0x67c8a750   IsContextLost()             Returns byte at context+0x39f1
GL Functions Analyzed

Code: Select all

GL Function        Validation Addr   Implementation Addr
glDrawArrays       0x67d5da10        0x67c95040
glDrawElements     Similar           Similar
glClear            0x67d5d600        0x67c8bfd0
glUseProgram       0x67d5d970        0x67c8de90
glBindTexture      Analyzed          Analyzed
glTexImage2D       Analyzed          Analyzed
glTexParameteri    Analyzed          Analyzed
glGenTextures      Analyzed          Analyzed
glBindBuffer       Analyzed          Analyzed
glBufferData       Analyzed          Analyzed
glGenBuffers       Analyzed          Analyzed
glCreateShader     Analyzed          Analyzed
glCompileShader    Analyzed          Analyzed
glCreateProgram    Analyzed          Analyzed
glGetUniformLocation Analyzed        Analyzed
glFlush            Analyzed          Analyzed
────────────────────────────────────────

4. RVGL.exe Core Game Loop

Entry Point Chain

Code: Select all

0x004014c0  entry()
  └→ 0x00402ec0  MainGameLoop(argc, argv)
       ├─ Parse 27 command-line arguments
       ├─ Initialize SDL subsystems
       ├─ Load resources (tracks, cars, textures)
       ├─ Set game state function pointer → DAT_006e30a0
       │
       └─ MAIN LOOP: while (!DAT_006e30a8)
            ├─ FUN_00402980()  ← Process all SDL events (input)
            │
            ├─ if (window minimized / unfocused):
            │    FUN_00401610()  ← Frame update dispatcher
            │    SDL_Delay(10ms) ← Sleep to save CPU
            │
            └─ else:
                 (*DAT_006e30a0)()  ← Call current game state function
Frame Update Dispatcher (0x00401610)

• Calls CalcDeltaTime() (0x005250c0) every frame
• Updates delta-time accumulator DAT_0ae48dc8
• Iterates the active car linked list at DAT_0acee9e8:
- Follows +0x10 next pointers
- Adds delta to each car's +0xf90 timer
• Game mode branch: if DAT_006e34c0 & 0xFFFFFFFD == 4 → runs render pipeline

CalcDeltaTime (0x005250c0)

• Uses SDL_GetPerformanceCounter() for high-precision timing
• Stores at DAT_0065c03c (float seconds/frame)
• Caps at 100ms/frame to prevent physics explosions
• Optional slow-motion via DAT_0ae48da0 (GameSpeedPercent multiplier)
• Performance frequency cached in DAT_0ae48de0

────────────────────────────────────────

5. Command-Line Arguments (27 Discovered)

All parsed in MainGameLoop() at 0x00402ec0:

Graphics

Code: Select all

Argument         Memory Address    Type        Description
-window W H      0x006e3414,       int, int    Windowed resolution
                 0x006e3410
-multisample N   0x006e340c        int         MSAA samples (0, 2, 4, 8)
-nogamma         0x006e342d        byte        Disable gamma correction
-alpharef N      0x00662a00        float       Alpha reference value (0-255)
-cubevisi        0x00661640        int         Cube visibility / culling
Audio & Input

Code: Select all

Argument         Memory Address    Type        Description
-nosound         0x006e3434        byte        Disable all audio
-nojoy           0x006e3433        byte        Disable joystick/controller
Debug & Development

Code: Select all

Argument         Memory Address    Type        Description
-dev             (temporary flag)  -           Developer mode
-texinfo         0x006e343a        byte        Show texture debug info
-carinfo         (temporary flag)  -           Show car debug info
-noguikey        0x006e3429        byte        Disable GUI hotkeys
-editscale F     0x0065c024        float       Editor scale factor
-editoffset X Y Z 0x006e31e8/ec/f0 float×3     Editor camera offset
Multiplayer

Code: Select all

Argument         Memory Address    Type        Description
-lobby [SERVER]  0x0ae6f6a0,       int,        Join lobby server
                 0x0ae6f5a0        char[256]
-nop2p           0x0065c030        int         Disable peer-to-peer
-nomulticast     0x006625a2        byte        Disable multicast discovery
-nolatejoin      0x006625a1        byte        Disable late joining
-port N          0x0065c02c        int         Network port
-serverport N    (unknown)         int         Server port
Profiles & Other

Code: Select all

Argument         Memory Address    Type        Description
-profile NAME    0x006e3640        char[16]    Load specific profile (max 15 chars)
-nouser          0x006e3432        byte        Disable user profiles
-largereplays    0x006e3438        byte        Enable larger replay files
────────────────────────────────────────

6. Game State Machine

The game uses a function pointer dispatch system. A single global at DAT_006e30a0 points to the current game state function, called every frame.

Game States Discovered

Code: Select all

Address      State Name                  Description
0x00499b30   SplashScreenState()         Dev logos, initial splash, transitions to menu/racing
0x00499690   RacingGameLoop()            THE main racing loop - physics, AI, rendering, everything!
0x00543890   MultiplayerLobbyState()     Network game lobby / setup
0x00406b40   UnknownGameState()          Another mode (menu transition?)
0x0044c130   GameGaugeReplayState()      Loads game_gauge_replay.rpl, replay playback mode
Game Mode Codes (DAT_006e34c0)

Code: Select all

Code   Mode                Description
0x01   Normal Race         Standard single-player racing
0x02   Lobby/Custom        Custom multiplayer race
0x03   Time Trial          Solo time attack
0x04   Online Sync Wait    Waiting for MP sync
0x05   Replay              Replay playback
0x06   Online Sync Wait 2  Secondary MP wait
0x07   Exit                Cleanup and exit race
0x08   Practice 1          Free drive mode
0x09   Practice 2          Alt practice mode
0x0B   Timed Race          Timed racing mode
0x0D   Race                Standard race (alt code)
0x0F   Tournament          Championship mode
0x10   Free Race           Casual race mode
Race State Machine (DAT_016942dc)

States 0–6 control the race flow:

Code: Select all

0 → Pre-race initialization
1 → Fade-in (blend from -0.2 to 1.2, then → state 5)
3 → Fade-out (blend from +0.6 to -0.2, then → state 6)
4 → Race end detected → dispatch winner logic
5 → Paused / fully displayed
6 → Post-race cleanup / transition
Functions: SetRaceState() (0x0048a560), GetRaceState() (0x0048a5c0), UpdateRaceState() (0x0048a5d0)

────────────────────────────────────────

7. SDL Event Processing & Input System

Event Processing (0x00402980)

Called every frame to drain the SDL event queue.

SDL Event Types Handled

Code: Select all

Event Code   SDL Name              Handler
0x100        SDL_QUIT              Sets DAT_006e30a8 = 1 (quit flag)
0x200        SDL_MOUSEBUTTONDOWN   Mouse click processing
0x300        SDL_KEYDOWN           Keyboard key press
0x303        SDL_TEXTINPUT         Text input (typing)
0x403        SDL_WINDOWEVENT       Focus gain/loss, resize
0x605-0x607  Custom RVGL           Internal game events
0x700        SDL_FINGERDOWN        Touch start
0x701        SDL_FINGERUP          Touch end
0x702        SDL_FINGERMOTION      Touch drag
Key Bindings Discovered

Code: Select all

F1-F10   → Ready/action keys (CheckPlayerReady at 0x00445d20)
Keyboard System (0x00529e50)

• Double-buffered: previous state at DAT_0ae6ed00, current at DAT_0ae6ef00
• Each frame: copies current → previous, then SDL_GetKeyboardState() → current
• 0x200 bytes (512 scancodes) per buffer
• DAT_006fcec8 = "no keyboard" mode (clears both buffers)

Mouse System (0x00529f60)

• SDL_GetRelativeMouseState() → delta XY at DAT_0ae6dcb4/b8
• Accumulated in DAT_0ae6dcc8/cc
• SDL_GetMouseState() → absolute pos at DAT_0ae6dcc0
• Controller axis bindings at DAT_00f43400 (+0x28c/290 = axes, +0x28f/293 = types)
• Final output: DAT_0ae6dca0 (packed steering XY)

Controller System (0x0052a910)

• Supports up to 2 controllers simultaneously
• Controller state at DAT_00f43400 (stride 0x44), processed state at DAT_0ae6e520 (stride 500)
• Uses SDL_GameControllerGetAxis() and SDL_GameControllerGetButton()
• Dead-zone at DAT_00f436c4, sensitivity at DAT_00f436c8
• Previous state snapshot at DAT_0ae6dd40

Touch System (4 simultaneous!)

RVGL supports 4 simultaneous touch inputs - the game runs on mobile too!

Code: Select all

Touch    Address        Fields
Touch 0  0x0ae6dce0     fingerID (+0x00), active (+0x08), pressed (+0x09), pos/pressure (+0x0C)
Touch 1  0x0ae6dcf8     Same layout, +0x18 offset
Touch 2  0x0ae6dd10     Same layout, +0x18 offset
Touch 3  0x0ae6dd28     Same layout, +0x18 offset
────────────────────────────────────────

8. Car System - Static Pool & Runtime Entities

Static Car Pool

CarInfo Structure (272 bytes / 0x110)

Code: Select all

struct CarInfo {
    char   internalName[20];      // +0x00  Internal folder name
    char   displayName[19];       // +0x14  Display name (from NAME keyword)
    char   pad1[29];              // +0x27  Padding
    char   tpageFilename[64];     // +0x54  Texture page file (TPAGE)
    char   tpageNull;             // +0x93  Null terminator
    char   tcarboxFilename[64];   // +0x94  Car selection icon (TCARBOX)
    char   tcarboxNull;           // +0xD3  Null terminator
    byte   unknown1[16];          // +0xD4  Unknown
    byte   bestTimeEnabled;       // +0xE4  BESTTIME: 0/1
    byte   selectableByPlayer;    // +0xE5  SELECTABLE: 0/1
    byte   selectableByCPU;       // +0xE6  CPUSELECTABLE: 0/1
    byte   statisticsEnabled;     // +0xE7  STATISTICS: 0/1
    int32  carClass;              // +0xE8  CLASS: 0-4
    int32  starRating;            // +0xEC  RATING: star count
    int32  obtainCondition;       // +0xF0  OBTAIN: unlock method
    int32  topSpeedStat;          // +0xF4  TOPEND: top speed stat
    int32  accelerationStat;      // +0xF8  ACCELERATION: accel stat
    int32  weightValue;           // +0xFC  WEIGHT: weight in kg
    int32  transmissionType;      // +0x100 TRANS: 0=auto?
    byte   unknown2[4];           // +0x104 Unknown
    uint16 statusFlags;           // +0x108 Various flags
    byte   isInvalid;             // +0x109 1 = invalid/missing car
    byte   pad2[6];               // +0x10A Padding
};
// Total: 272 bytes (0x110) per car
Pool Details

• Base pointer: DAT_006fab50 (pointer to heap-allocated array)
• Initial count: 49 (0x31) built-in cars at DAT_006fab58
• User car loading (0x0043fac0): Scans cars/ dir via _wfindfirst64, reallocs pool beyond 49, sorts by class rating
• Selectability filter (0x0043bdf0): Mode 0=all, 1=class filter, 2=first-8 only

Car Loading Pipeline

Code: Select all

Step  Function                    Address      Description
1     LoadAllCars()               0x0043f140   Main loop: scans car directories, loads 49+ cars
2     InitializeCarStructure()    0x005bd590   Sets default values for each CarInfo
3     ParseParametersTxt()        0x0043b6c0   Parses parameters.txt (16 keywords)
4     FinalizeCarLoad()           0x0043ba50   Post-processing after car data loaded
5     LoadUserCars()              0x0043fac0   Scans custom cars, expands pool
6     PackPhysicsVectors()        0x0049c080   Packs 10 float params into physics array
7     CheckFileIntegrity()        0x004070e0   Verifies .prm files (magic 0x7830)
Runtime Car Entity (~0x6B00+ bytes)

The actual in-game car objects are much larger than the static CarInfo. They live in a doubly-linked list.

Linked List Globals

Code: Select all

Address      Name                  Description
0x0acee9e8   CarListHead           Head of active car linked list
0x0acee9e0   CarListTail           Tail of active car linked list
0x0adb69b0   FreeCarPoolHead       Head of free/pooled car entities
0x0acee7e4   TotalActiveCarCount   Count of active cars
0x0acee7e8   LocalPlayerCarPtr     THE player's car entity pointer
CarEntity Structure (key fields from ~0x6B00+ bytes)

Code: Select all

struct CarEntity {
    // ─── Identity & Control ───
    int    car_array_index;         // +0x00   Index into CarInfo array
    int    car_type;                // +0x04   1=player, 2=AI, 3=ghost, 4=reset, 9=spectator
    void*  prev_car;                // +0x08   Previous in linked list
    void*  next_car;                // +0x10   Next in linked list
    int    subtype;                 // +0x18   Behavior subtype
    int8   ai_steering;            // +0x34   -127=full left, +127=full right
    int8   ai_throttle;            // +0x36   -127=full brake, +127=full throttle
    uint16 control_flags;           // +0x38   bit4=draft, 0x4000=drift_right, 0x1000=drift_left
    void*  physics_body_ptr;        // +0x40   PhysicsBody*
    int    car_slot_index;          // +0x48   Index in CarInfo array
    void*  physics_data_ptr;        // +0xC8   Physics sub-data

    // ─── Race Progress ───
    float  race_time_accumulator;   // +0xF90  Incremented by delta each frame
    int    lap_count;               // +0x1010
    int    cooldown_timer;          // +0x104C Decremented per-frame
    float  current_speed;           // +0x53C  Current speed in game units

    // ─── AI Navigation ───
    int    current_zone_section;    // +0x67D4 Current track zone/section
    int    route_section_index;     // +0x6910 Current RouteSection
    float  track_t;                 // +0x6914 Distance progress along route
    float  norm_track_t;            // +0x6918 Normalized (0.0..1.0)
    byte   facing_route;            // +0x690C 1=facing forward on route

    // ─── AI State Machine ───
    int    ai_state_current;        // +0x68C8 See AI state codes
    int    ai_state_previous;       // +0x68CC
    float  ai_state_timer;          // +0x68D0
    float  steering_angle;          // +0x6920 -1.0=left, +1.0=right
    float  lookahead_distance;      // +0x6968 Default 600.0f
    float  max_steer_limit;         // +0x696C Default 50.0f
    float  speed_cm_s;              // +0x698C Current speed in cm/s
    int    race_position;           // +0x69C0 0-based position
    byte   reverse_state;           // +0x69D0
    float  engine_power_current;    // +0x69D8
    float  engine_power_target;     // +0x69DC Default 0.5f

    // ─── Race Finish ───
    int    finish_time_ms;          // +0x6A48 0=not finished
    int    final_race_position;     // +0x6A4C 0xFFFFFFFF=not set
    byte   invincible_flag;         // +0x6A44
    int    network_player_id;       // +0x6A84 For multiplayer sync
};
AI State Machine Constants (car+0x68C8)

Code: Select all

State   Name                    Description
0       Normal Racing           Optimal path following
1       Startup/Reset           Speed 0, resets controls
2       Normal → Avoidance      Transitions to 3 if car nearby
3       Avoidance               Core avoidance behavior
4       Rubber-band             Chase/slow behavior
6       Braking                 Active braking
7       Partial Avoidance       25% steering
8-9     Left Track Alt          Alternative path left
10-11   Left Turn Recovery      Recovery from left
12-13   Right Turn Recovery     Recovery from right
Car Entity Lifecycle

Code: Select all

Function                        Address      Description
CreateCarEntity()               0x004f03a0   Allocates from free pool, inserts into linked list
DestroyCarEntity()              0x004f0630   Returns to pool, removes from list
DestroyAllCarEntities()         0x004f06d0   Destroys all cars in list
InitCarSlotFull()               0x004ab810   572-line full initializer (copies 0xAAC template)
InitRuntimeCarStruct()          0x0043c580   Applies per-car overrides from physics table
InitReplayCarSlot()             0x005589b0   Wrapper for replay mode initialization
FindCarByNetworkID()            0x004f0850   O(n) search for multiplayer sync
FindCarIndexByName()            0x0043c160   Searches display name field
RegisterFinishTime()            0x004f0890   Insertion-sort into leaderboard (max 30)
SetAllCarsBoostState()          0x004f0af0   Boost/speed-start for all cars
RestoreAllCarsStartState()      0x004f0b50   Rollback saved physics state
SetCarInvincible()              0x004f0ba0   Sets car+0x6A44 = 1
ClearCarInvincible()            0x004f0bc0   Sets car+0x6A44 = 0
InitPlayerCar()                 0x0044cb60   Creates/reinitializes player's car
SetCarBehaviourState()          0x004efd50   Sets behavior (idle/racing/spectating/ghost/etc.)
────────────────────────────────────────

9. Track / Level System

TrackInfo Structure (120 bytes / 0x78)

Code: Select all

struct TrackInfo {
    byte   unknown1[16];             // +0x00
    char   displayName[64];          // +0x10  NAME keyword
    byte   unknown2[20];             // +0x50
    int32  difficultyRating;         // +0x64  DIFFICULTY
    int32  gameType;                 // +0x68  GAMETYPE (2=standard, 3=other)
    int32  challengeTime;            // +0x6C  CHALLENGE in milliseconds
    int32  challengeReverseTime;     // +0x70  CHALLENGEREV in milliseconds
    byte   unknown3[4];              // +0x74
};
// Array starts at s_nhood1_0065fe20
// Element size: 120 bytes (0x78)
Track Loading Functions

Code: Select all

Function                    Address      Description
LoadAllTracks()             0x00452190   Main track scanning loop
ParseTrackInf()             0x00451da0   Parses .inf file (6 keywords)
CheckDirectoryExists()      0x005370e0   Verifies levels/[name]/ exists
CheckFileExists()           0x005370a0   Verifies .inf file exists
SetupRaceTrackRandom()      0x00451ab0   Random track selection
GetRandomTrack()            0x00450600   Picks random available track
Level Loading Pipeline (0x00404c30)

• Sets up viewport for loading screen
• Loads track textures
• Spawns background loading thread
• Renders loading screen with progress bar (% from DAT_006e3968)
• Waits for thread completion (semaphore sync)
• Calls post-load initialization

File Structure

Code: Select all

levels/
└── [trackname]/
    ├── [trackname].inf       ← Track info (text, parsed by ParseTrackInf)
    ├── [trackname].w         ← World geometry (binary, not yet analyzed)
    ├── reversed/
    │   └── [trackname].inf   ← Reversed mode info
    └── [textures].bmp        ← Track textures
────────────────────────────────────────

10. AI System - The 1,517-Line Brain

CarPhysicsUpdate_AIBrain (0x00408a60)

This is the single largest analyzed function - 1,517 lines of decompiled C. It handles per-car physics AND the complete AI state machine with 13 states.

What it does every frame for every AI car:

• Reads 80+ CarEntity fields
• Runs the 13-state AI state machine
• Computes steering and throttle output (written to car+0x34 and car+0x36)
• Updates race position tracking
• Calls avoidance, rubber-band, and stuck detection sub-functions

AI Subsystem Functions

Code: Select all

Function                        Address      Lines   Description
CarPhysicsUpdate_AIBrain()      0x00408a60   1,517   THE AI brain - full state machine
AI_Avoidance()                  0x004071c0   ~150    Core steering computation from steer + lateral deviation
InitAI_State()                  0x00407400   ~50     Initialize AI on car spawn
ResetAIBehavior()               0x004074a0   ~60     Reset nav defaults (lookahead=600, max_steer=50, etc.)
UpdateRacePositions()           0x004075f0   ~100    Insertion-sort all cars by race score
AI_StuckDetection()             0x00407930   ~200    Detects stranded cars, forces avoidance state
CompareCarPassing()             0x00407cb0   ~60     Overtaking comparison between two cars
AI Default Parameters

Code: Select all

lookahead_distance  = 600.0f
max_steer_limit     = 50.0f
angle_threshold     = 100.0f
height_target       = 150.0f
ai_param5           = 50.0f
track_side_room     = 300.0f
engine_power_target = 0.5f
AI Speed Thresholds (cm/s → km/h)

Code: Select all

268.3363  ≈  9.65 km/h  (stuck/low threshold)
447.2272  ≈ 16.1  km/h
894.4543  ≈ 32.2  km/h
1341.682  ≈ 48.3  km/h
1788.909  ≈ 64.4  km/h
2236.136  ≈ 80.5  km/h
2683.363  ≈ 96.5  km/h
────────────────────────────────────────

11. Waypoint & Route Navigation

Track Waypoint Graph

AI cars navigate using a node graph overlaid on the track.

AINode Structure (0x108 bytes per node, max 0x1000 nodes)

Code: Select all

struct AINode {
    byte    type;            // +0x00  Node type code
    byte    type2;           // +0x01
    float   track_t;         // +0x04  Position along track (0.0..1.0)
    void*   back_link1;      // +0x18  Backward graph link
    void*   back_link2;      // +0x20  
    void*   fwd_link1;       // +0x28  Forward graph link 1
    void*   fwd_link2;       // +0x30  Forward graph link 2
    float   left_edge[3];    // +0x38  Left track edge XYZ
    float   right_edge[3];   // +0x48  Right track edge XYZ
    float   center[3];       // +0x60  Center of segment XYZ
    float   segment_length;  // +0xA8  Arc length of this segment
    byte    obstacle_flags;  // +0xB6  Obstacle direction bitfield
};
// Buffer at DAT_006f94a0, count at DAT_006f94aa (short)
Node Type Codes

Code: Select all

Code   Type
0x01   Normal segment
0x02   Shortcut
0x03   Hazard
0x05   Hazard alt
0x09   Turbo boost
0x0A   Lead car target
0x0B   Follow car target
0x0C   Dead-end
0x0F   Shortcut variant
RouteSection Structure (0x50 bytes)

Code: Select all

struct RouteSection {
    float   x, y, z;           // +0x00  Center position
    float   route_val;         // +0x0C  Cumulative route distance
    float*  fwd_neighbors[4];  // +0x10  Forward neighbor pointers
    float*  bwd_neighbors[4];  // +0x30  Backward neighbor pointers
};
// Array at DAT_006e3af0
Navigation Functions

Code: Select all

Function                        Address      Description
FreeWaypointTables()            0x0040fc20   Frees waypoint and zone tables
FindCarInZoneSectionOBB()       0x0040fd90   3D OBB inside-test against zone
FindCarCurrentZone()            0x0040ff20   Tests current zone ±1 (with wrap)
FindCarCurrentZoneBrute()       0x0040ffb0   Brute-force all zones (used on spawn)
UpdateCarRoutePosition()        0x0040e150   14 XREFs - per-frame route tracker
DeleteWaypointNode()            0x00410070   Editor: removes node from graph
FindNearestWaypointNode()       0x004103e0   Finds nearest node to 3D position
WaypointDijkstraRelax()         0x00410860   Dijkstra shortest-path relaxation
GetWaypointNodeClosestToRay()   0x00410680   Editor: ray-to-node distance test
WaypointLinkPromote()           0x00410020   Promotes secondary links to primary
────────────────────────────────────────

12. Physics System

Per-Frame Physics (0x004c84a0)

PerFramePhysicsWorldStep() is the main physics dispatcher:

• Calls UpdateRacePositions() - sort all cars by race score
• Decrements car+0x104C cooldown timer for each car
• Calls FUN_004f95b0 + FUN_00488ad0 - physics sub-steps
• Updates game object linked list at DAT_0ace4800

PhysicsBody Structure (at CarEntity+0x40)

Code: Select all

struct PhysicsBody {
    // Position
    float  pos_x;                    // +0x24 (also accessible via +0x10+0x14)
    float  pos_y;                    // +0x28
    float  pos_z;                    // +0x2C
    // Forward direction
    float  forward_x;               // +0x7C
    float  forward_y;               // +0x80
    float  forward_z;               // +0x84
    // Collision
    int    on_ground_flag;           // +0x210
    int    wheel_contact_count;      // +0x214
    float  collision_normals[7];     // +0x248..+0x264
    // Behavior
    void*  behavior_fn_ptr;          // +0x340
    void*  saved_behavior[3];        // +0x458..+0x464 (for rollback)
    // Back-reference
    void*  owner_car_entity;         // +0x2A0
};
Physics Solvers

Code: Select all

Function                        Address      Description
GaussianElimination()           0x00499c40   Solves AxB=C for constraints/suspension
ConjugateGradientSolver()       0x0049a3e0   Iterative SIMD solver for constraints
MeshVertexOBBCull()             0x004b35b0   OBB visibility test (vertex stride 0x58)
TransformMeshVertices()         0x004b77d0   CPU vertex transform (3×3 rotate + translate)
────────────────────────────────────────

13. Race Session System

Race Setup (0x00450700) - 765 lines

Giant switch on DAT_006e34c0 (GameMode). Builds the participant table for each race.

Participant Table

• Array at DAT_00f3eb70 (stride 0x50 = 80 bytes per entry, max 30)
• Count at _DAT_00f3eb04
• Player index at DAT_00f3eb00

RaceCarEntry Structure (0x50 bytes)

Code: Select all

struct RaceCarEntry {
    int    car_type;     // +0x00  (1=player, 3=AI, 9=spectator)
    int    spawn_type;   // +0x04  (spawn orientation)
    int    car_model;    // +0x08  (CarInfo index)
    int    spawn_quat;   // +0x0C
    int    network_id;   // +0x18
    int    is_local;     // +0x1C  (1=local human player)
    char   name[16];     // +0x40  (player/bot name)
};
Race Setup Functions

Code: Select all

Function                        Address      Description
RaceSessionSetup()              0x00450700   Main session builder (765 lines)
AddParticipantAndCount()        0x0044f1f0   Adds entry + increments count
AddParticipantNoCount()         0x0044f4f0   Adds entry without incrementing (for AI fill)
SetupAllRaceCars()              0x0044f7b0   Creates ALL race cars from entry table
CreateSinglePlayerCar()         0x0044f640   Creates the local player car
RandomizeCarPicks()             0x0044fb30   Fisher-Yates shuffle per class, avoids duplicates
AssignStartPositions()          0x0044f980   Grid positions via partial shuffle
SelectRandomCar()               0x004504e0   Picks random valid car model
GetCarColor()                   0x004505c0   Random color variant
ComputeSpawnOrientation()       0x004a71d0   Converts spawn type to rotation matrix
RaceEndManager()                0x00541f80   Post-race state machine (init→results→fadeout→cleanup)
LoadLapImages()                 0x004995f0   Loads lap-specific GFX assets
────────────────────────────────────────

14. Ghost Car / Replay System

Ghost Recording

• Per-frame recording: RecordGhostPosition() (0x0044d0c0)
• Format: Stride 0x18 (24 bytes) per frame, max 0x7FFF frames
• Data per frame: timestamp (ms), speed (encoded byte), quaternion XYZW
• SLERP optimization: Skips frame if orientation < 0.6 and distance < 1000 from previous

Ghost Buffer System

• Double-buffered: PTR_DAT_0065fca8 (current) and PTR_DAT_0065fcb0 (previous)
• Swap on lap finish: CommitGhostLapFrame() (0x0044d040)
• Transparency: UpdateCarGhostTransparency() sets alpha to 0.5f

Ghost Frame Structure

Code: Select all

struct GhostFrame {       // 24 bytes (0x18)
    uint   timestamp_ms;  // +0x00
    byte   speed_enc;     // +0x04  (speed × 5, as byte)
    byte   pad[3];        // +0x05
    float  quat_x;        // +0x08
    float  quat_y;        // +0x0C
    float  quat_z;        // +0x10
    float  quat_w;        // +0x14
};
Ghost Functions

Code: Select all

Function                        Address      Description
RecordGhostFrame()              0x0044cec0   Records position/orientation to buffer
CommitGhostLapFrame()           0x0044d040   Swaps double buffers on lap finish
RecordGhostPosition()           0x0044d0c0   Per-frame recorder with SLERP skip
CreateGhostPath()               0x004102d0   Builds replay path from 0x1C20 samples
────────────────────────────────────────

15. Rendering Pipeline - Full Discovery

Main Render Pass (0x004886b0 - RenderSceneFull)

This is THE main full-pass renderer. Sequence:

• GL_SetupNormalRenderState() - depth test, blend mode
• CommitFrameRenderWork() - VAO/VBO commit + UBO update
• SortDynamicObjects() - bucket-sort car meshes by texture
• SortTrackMeshObjects() - bucket-sort track meshes (193 buckets)
• DrawGameObjects() - render world objects
• (Optional) UpdateGhostRender() / RenderCarMeshes() / RenderSkidmarksShadows()
• FlushBatchedQuads() - flush 2D sprite batch
• Clear mesh batches

2D UI/HUD Rendering

DrawSprite2D (0x004628b0) - 62 call sites!

The core 2D sprite/quad renderer. Immediate-mode style.

Code: Select all

void DrawSprite2D(
    float x, float y,           // Screen-space position
    float width, float height,  // Size
    float u1, float v1,         // Texture UV top-left
    float u2, float v2,         // Texture UV size
    uint32 color,               // RGBA color (0xRRGGBBAA)
    int texture_id,             // Texture ID (-1 = no texture)
    int blend_mode              // 0=alpha, 1=additive, -1=no change
);
Process: Screen coords → NDC conversion → 4-vertex quad (stride 0x2C) → glDrawArrays(GL_TRIANGLE_FAN, 0, 4)

Vertex Format

Code: Select all

struct Vertex {           // 44 bytes (0x2C)
    float x, y, z, w;    // Position (4 floats)
    uint8 r, g, b, a;    // Color (4 bytes packed)
    float u, v;           // Texture coords (2 floats)
    float pad[2];         // Padding
};
Batch Rendering System

Panel Batch (UI elements)
• FlushBatchedPanelPolys() (0x00461d30) - builds VBO+EBO, groups by texture/blend
• DrawBatchedPanelPolys() (0x004621b0) - issues GL draw calls per group
• Capacity: 128 quads (DAT_00f40dc8)
• Buffer: DAT_00f40dc0 (CPU staging, 0x5C00 bytes)

Text Batch
• FlushBatchedTextPolys() (0x00491900) - same pattern for text
• DrawBatchedTextPolys() (0x00491be0) - issues draw calls
• Capacity: 4,096 quads (DAT_016cf568)
• Buffer: DAT_016cf560 (CPU staging, 0xB0000 bytes)

3D Mesh Rendering

Code: Select all

Function                                Address      Description
SortTrackMeshObjects()                  0x004b6b60   Bucket-sorts into 193 texture-slot buckets
SortDynamicObjects()                    0x00500f60   Same for car meshes
DrawGameObjects()                       0x004d4260   Binds VAO, shader, 5 attribs, per-object draw
DrawMeshObject()                        0x00480fb0   THE per-object draw - handles shadow/env/transparent/specular
RenderCarMeshes()                       0x00481320   Car-specific mesh rendering
RenderTransparentAndSortedObjects()     0x00481760   Two-pass shell-sort by depth
AddToSemiTransparentList()              0x00480cd0   Defers transparent objects
SetupMeshRenderSlot()                   0x00480e00   Allocates GL resource slot
FrustumCullSphere()                     0x004d46f0   4-plane frustum test
UpdateGhostRenderEntries()              0x0047d220   Ghost car shell-sort by depth
GPU Buffer Layer

Code: Select all

Function                        Address      Description
AllocOrResizeVBO()              0x0053a460   Thread-safe VBO+EBO allocation (GL_DYNAMIC_DRAW)
UploadVBOData()                 0x0053a800   Vertex+index upload with power-of-2 growth
GLDrawCall()                    0x0053ab80   THE final draw - glDrawElements or glDrawArrays
SetupFrameUBOs()                0x0053b020   Per-frame uniform commit (fog color/density/matrix)
FindBestGLResourceSlot()        0x0053a070   Searches 49-slot resource table
CommitFrameRenderWork()         0x0053de80   Per-frame VAO/VBO + UBO commit
SetShaderUniformBlock()         0x0053df60   16-slot uniform cache, glUniform4iv
GL State Management

Code: Select all

Function                        Address      Description
GL_SetupNormalRenderState()    0x004884d0   Depth test + alpha blend setup
SetupGLRenderState()            0x00491f60   Blend/depth for render pass (70 call sites)
SetDepthWriteMode()             0x00539fa0   glDepthMask toggle
SetFogDistances()               0x00488800   Fog near/far based on draw distance
SetFogParams()                  0x004888a0   Fog density + linear slope
Viewport & Camera (0x004a4120)

• 20 call sites - sets screen dimensions, aspect ratio, camera offsets
• Stores resolution pointer at PTR_DAT_00661850 (used by ALL rendering)
• Calculates screen center, NDC conversion factors
• Calls two setup function pointers: DAT_0aea7910 and DAT_0aea5eb0

────────────────────────────────────────

16. Audio System - Full OpenAL Analysis

Initialization (0x00527230)

• Opens OpenAL device via alcOpenDevice + alcCreateContext
• Prints vendor/version
• Sets distance model: alDistanceModel(0) (no attenuation by default)
• Generates music source: alGenSources(1, &MusicALSourceID)
• Sets FLUID_SOUNDFONT environment variable
• On failure: sets DAT_006e3434 = 1 (NoSoundFlag)

SFX System

Built-in SFX
• 38 WAV sound effects loaded from PTR_s_wavs_moto_wav_00661c40 table
• 128 AL sources allocated via alGenSources
• Buffer IDs in DAT_0ae4d240[], source handles in DAT_0ae4c640[]

Source Preemption (0x00526d70)

When all 128 sources are busy, the system steals the lowest-priority playing source:

• Scan for AL_STOPPED or AL_INITIAL sources first
• If none free, find playing source with lowest priority
• Stop it, reassign to new sound

Playback Functions

Code: Select all

Function                        Address      Description
PlaySfxSimple()                 0x00527f20   One-shot SFX: volume, pan, pitch, loop
PlaySfx3D()                     0x005280a0   3D positional SFX with attenuation
StartLoopingSfx()               0x005282d0   Persistent SFX with update handle
ChangeSfxAndStop()              0x005284b0   Swap SFX ID on playing source
StopLoopingSfx()                0x00528510   Stop looping sound
GetFreeSfxSource()              0x00526d70   Source allocation with preemption
FindSfxInstanceByID()           0x00527e50   Find oldest playing instance
LoadSfxSlot()                   0x00527520   Load WAV into AL buffer
GetSfxSlotByName()              0x00527630   Search SFX by name string
Calc3DAtten()                   0x005263c0   3D attenuation/panning calculation
Volume Formula

Code: Select all

alSourcef(source, AL_GAIN, (volume * MasterVolume) / 10000.0f);
alSource3f(source, AL_POSITION, pan / 50.0f - 1.0f, 0.0f, 0.0f);
alSourcef(source, AL_PITCH, pitch / 22050.0f);
Music/BGM System

Code: Select all

Function                        Address      Description
PlayMusic()                     0x005285b0   Starts OGG/WAV stream (250KB buffer)
UpdateMusicPlayback()           0x00526f10   Advances to next track (redbook/track%02d.*)
ScanMusicDirectory()            0x00526b60   Collects music files (max 0xFF entries)
SetMusicVolume()                0x00565aa0   alSourcef(src, AL_GAIN, vol)
PauseMusicStream()              0x00565880   Pauses streaming source
ResumeMusicStream()             0x00565990   alSourcePlay on stream
Focus Handling

• PauseAllSfx() (0x00527cf0) - on SDL_WINDOWEVENT_FOCUS_LOST: pauses all AL sources
• ResumeAllSfx() (0x00527da0) - on SDL_WINDOWEVENT_FOCUS_GAINED: resumes all AL sources

OpenAL Low-Level Wrappers

Code: Select all

Function                        Address      Description
OpenAL_Init()                   0x00561a20   alcOpenDevice + alcCreateContext
OpenAL_Shutdown()               0x00561ad0   alcDestroyContext + alcCloseDevice
OpenAL_GetError()               0x005618a0   Error string from AL context
LoadWAVToBuffer()               0x00562e90   Load WAV → alBufferData
OpenMusicStream()               0x00563f60   Open OGG/WAV as stream (250KB buf)
CloseMusicStream()              0x00563ad0   Free stream object
StartMusicPlayback()            0x005668b0   Bind stream to source, start playback
────────────────────────────────────────

17. Level Editor System

RVGL has a built-in level editor! We analyzed its dispatch and sub-modes.

Editor Functions

Code: Select all

Function                        Address      Description
EditorModeDispatch()            0x00418900   Dispatches to 10 editor sub-modes (based on DAT_006e3500)
EditModeUpdate()                0x00418a20   Main per-frame editor update
ShowStatusMessage()             0x00418d60   Display status text in editor
ScreenToWorldRay()              0x00418d90   Convert mouse coords to world-space ray
WorldPointVisible()             0x00418eb0   Frustum visibility test for world point
AINodeBoxRender()               0x00414c60   Renders AI node bounding box visualization
WireframeBoundingBoxRender()    0x004236b0   Draws wireframe bbox for selected section
TrackSectionDelete()            0x0042e8c0   Delete track section, updates DAT_006f9e6c
────────────────────────────────────────

18. Animation System

Keyframe Animation (0x004d0c70)

NPC/pedestrian animation system:

• 16 bone channels per object (loop 0..0xF, stride 0x6C per channel)
• Easing modes: linear, ease-in, ease-out, smoothstep, bounce
• Loop modes: loop, play-once, ping-pong
• Animation state struct at obj+0x338

Animation Loading (0x004d1f20)

• Zeros keyframe data tables, inits audio slot table to -1
• Loads animation definitions from files
• Max 16 animations, 16 channels each

────────────────────────────────────────

19. Weapon / Projectile System

Projectile Array

• 8 projectile slots in inline array at DAT_016f8ee0 (stride 0x140 = 320 bytes)
• Player's primary slot tracked at DAT_016f8e60 (259 XREFs!)
• 10 management globals at DAT_016f8e40–DAT_016f8e80

Functions

Code: Select all

Function                        Address      Description
ResetProjectileArray()          0x004a5500   Clears all 8 slots + management globals
InitWeaponSlot()                0x004a1290   Initializes per weapon type (type 6, 7, default)
DispatchTriggerHandlers()       0x004f1560   Iterates entity list, calls fn ptr at +0x358
LoadTriggersFromFile()          0x004f1910   Reads trigger file into DAT_0adb6cc0
────────────────────────────────────────

20. Camera Entity System

Camera Entities

• 9 camera entity pointers at DAT_016f8e40–DAT_016f8e80
• Player primary camera at DAT_016f8e60
• Camera array at DAT_016f8ee0 (9 slots × 0x140 bytes)

Functions

Code: Select all

Function                        Address      Description
CameraEntityViewportUpdate()    0x004a4910   Per-frame viewport rect writer
CameraEntityInit()              0x004a5ce0   Camera/pickup entity initializer
FindNearestPickupNode()         0x004a5b50   Spatial node lookup for camera
Split-Screen Support

• Minimap sub-viewports at 0x016f8e68/70/78
• Viewport rect table at DAT_016f9aa0 + idx*0x28
• FOV/zoom at DAT_00660800

────────────────────────────────────────

21. Networking / Multiplayer

Architecture

• Uses ENet via libenet-7.dll
• Supports: P2P, multicast discovery, late joining, lobby system
• Player IDs from DAT_0ae6f6a4 / DAT_0ae6f6ac
• Packet buffer at DAT_0ae6fc38

Functions (Partially Analyzed)

Code: Select all

Function                        Address      Lines   Status
MultiplayerPacketHandler()      0x0052f770   1,013   ⚠️ Partial (first 120 lines)
NetworkRenderStub()             0x00482e40   ~10     ✅ Complete
────────────────────────────────────────

22. Miscellaneous Systems

FPS Profiler (0x0044c820)

• Per-second FPS recording with min/max tracking
• 300-frame history array at DAT_006fcee0
• Writes profiles/fps.txt on trigger

Screenshot (0x00539bc0)

• glReadPixels → SDL_CreateRGBSurface → IMG_SavePNG_RW
• Also calls GL window/buffer operations

Credits/Scroll Text (0x004442b0)

• Scrolling text renderer with section support
• Uses PTR_s_RE_VOLT_0065cf00 section table
• Calls FUN_00492150 (DrawTextLine) for each line

Threading Model

Code: Select all

Thread 1: Main game thread (ID at DAT_006e3088)
Thread 2: Background asset loader (handle at DAT_006e3988)
  - Synchronized via semaphores (DAT_006e3978, 006e3980)
  - Stop flag at DAT_006e3974
  - Error flag at DAT_006e3976
  
Synchronization:
  - Mutex at DAT_006e3090
  - SDL_LockMutex / SDL_UnlockMutex for GL calls from background thread
Developer Strings Found

• "Developed by the RV team (c) 2010-2023"
• "For testing purposes only"
• "NOT FOR SALE"

────────────────────────────────────────

23. Complete Data Structures

Summary of All Structures Mapped

Code: Select all

Structure            Size              Location                    Purpose
CarInfo              272 bytes (0x110) DAT_006fab50 array          Static car metadata (49+ entries)
TrackInfo            120 bytes (0x78)  s_nhood1_0065fe20           Static track metadata
CarEntity            ~0x6B00+ bytes    Linked list at DAT_0acee9e8 Runtime car object
PhysicsBody          ~0x470+ bytes     CarEntity+0x40              Physics simulation data
AINode               264 bytes (0x108) DAT_006f94a0                Track waypoint graph node
TrackWaypointNode    264 bytes (0x108) Same buffer                 Track navigation node
RouteSection         80 bytes (0x50)   DAT_006e3af0                Route distance node
ZoneEntry            16 bytes (0x10)   DAT_006e3b00                Spatial zone lookup
RaceCarEntry         80 bytes (0x50)   DAT_00f3eb70                Race participant entry
RaceResult           16 bytes (0x10)   DAT_0acee800                Finish leaderboard entry
TriggerEntity        104 bytes (0x68)  DAT_0adb6cc0                World trigger entity
GameObjectEntity     ~0x360+ bytes     DAT_0ace4800 linked list    In-world object
GhostFrame           24 bytes (0x18)   Ghost buffers               Replay frame data
GLContextHandle      32 bytes (0x20)   TLS storage                 ANGLE context wrapper
RealGLContext        14,833+ bytes     Heap                        ANGLE D3D11 context
TouchState           24 bytes (0x18)   DAT_0ae6dce0 (×4)           Multi-touch input
Vertex               44 bytes (0x2C)   Rendering buffers           GPU vertex format
NetworkCarEntry      480 bytes (0x1E0) DAT_0adccb08                Network car mesh data
────────────────────────────────────────

24. Complete Memory Map - All Global Variables

Game State & Control

Code: Select all

Address      Type   Name                   Description
0x006e30a0   fn*    GameStateFunction      Current game mode function pointer
0x006e30a8   byte   GameQuitFlag           1=quit, 0=running
0x006e34c0   int    GameMode               Race mode code (1-0x10)
0x006e34c4   int    GameModeVariant        Sub-mode variant
0x016942dc   int    RaceState              Race state machine (0-6)
0x0065c03c   float  DeltaTime              Seconds per frame
0x0ae48da0   float  SlowMotionMult         Game speed multiplier
0x006635e0   int    ProfileLoadedFlag      Profile loaded
Window & Display

Code: Select all

Address      Type   Name                   Description
0x0065c021   byte   WindowFocusedFlag      0=unfocused, 1=focused
0x0ae85df0   void*  SDLWindowPointer       SDL_Window*
0x006e3414   int    WindowWidth            From -window
0x006e3410   int    WindowHeight           From -window
0x006e340c   int    MultisampleLevel       MSAA samples
0x00660800   float  PlayerCameraFOV        Camera field of view
Car System

Code: Select all

Address      Type         Name                   Description
0x006fab50   CarInfo*     CarArrayPtr            Pointer to car pool
0x006fab58   int          CarCount               Cars in pool (starts 49)
0x006fab80   byte[0xAAC]  RuntimeCarTemplate     Template for InitRuntimeCarStruct
0x0acee7e8   void*        LocalPlayerCarPtr      THE player's car entity
0x0acee9e8   void*        CarListHead            Active car linked list head
0x0acee9e0   void*        CarListTail            Active car linked list tail
0x0adb69b0   void*        FreeCarPoolHead        Free car entity pool
0x0acee7e4   int          TotalActiveCarCount    Active car count
Race Session

Code: Select all

Address      Type              Name                   Description
0x00f3eb70   RaceCarEntry[30]  ParticipantTable       Race entries (stride 0x50)
0x00f3eb04   int               ParticipantCount       Entry count (max 30)
0x00f3eb00   int               PlayerRaceIndex        Player's slot index
0x006e34cc   int               PlayerCarModelIndex    Selected car model
0x006e34d4   uint              LapsConfig             Number of laps
0x0ae8e930   int               TotalAICarsTarget      Target AI count
0x0ae8e948   char[16]          LocalPlayerName        Player name string
0x0ae6f6ac   int               LocalPlayerNetworkID   Network session ID
0x0acee800   RaceResult[30]    RaceResultTable        Finish leaderboard
0x0ae8e8c8   void*             WinnerCarPtr           Race outcome
Route / Navigation

Code: Select all

Address      Type   Name                       Description
0x006e3ae0   float  TotalRouteLength           Track lap length in route units
0x006e3ae4   int    DefaultRouteSectionIndex   Default section (car init)
0x006e3af0   void*  RouteSectionTable          RouteSection array (stride 0x50)
0x006e3b00   void*  ZoneLookupTable            Spatial zone table (stride 0x10)
0x006e3b08   void*  WaypointDataTable          Waypoint sections (stride 0x78)
0x006e3b10   int    TotalWaypointNodes         Total node count
0x006f94a0   AINode[] AINodeBuffer            0x108 bytes/node, max 0x1000
Camera & Rendering

Code: Select all

Address      Type    Name                   Description
0x016f8e60   void*   CamPlayerPrimary       Player camera entity
0x016f8ee0   byte[]  CameraEntityArray      9 slots × 0x140
0x016f9aa0   byte[]  ViewportRectTable      Viewport rects
0x00f40dc0   void*   PanelBatchBuffer       CPU staging for UI quads
0x00f40dc8   int     PanelBatchCapacity     128 quads
0x016cf560   void*   TextBatchBuffer        CPU staging for text
0x016cf568   int     TextBatchCapacity      4096 quads
Weapon / Projectile

Code: Select all

Address      Type    Name                   Description
0x016f8e60   void*   WeaponArraySlot0Ptr    259 XREFs! Player weapon slot
0x016f8ee0   byte[]  WeaponEntityArray      8 slots × 0x140
0x0ace47c0   int     ActiveItemIndex        Current active item
0x01800298   byte[]  ItemDataArray          Item data (stride 0x138)
Audio

Code: Select all

Address      Type    Name                   Description
0x0ae4d240   uint[]  SFXBufferIDs           AL buffer IDs per SFX slot
0x0ae4c640   uint[]  SFXSourceHandles       AL source handles (128 max)
0x0ae48e34   int     AudioPausedFlag        1=all audio paused
Timing

Code: Select all

Address      Type    Name                   Description
0x0ae48de0   uint64  PerformanceFrequency   QueryPerformanceFrequency result
0x0065c038   float   DeltaTimeRaw           Raw delta ratio
0x006fceb0   int     FramesThisSecond       FPS counter
0x006fcea8   int     MinFPS                 Minimum FPS recorded
0x006fcea4   int     MaxFPS                 Maximum FPS recorded
Network

Code: Select all

Address      Type      Name                   Description
0x0ae6f6a0   int       LobbyModeFlag          Lobby enabled
0x0ae6f5a0   char[256] LobbyServerAddress     Server address
0x0065c030   int       P2PEnabled             Peer-to-peer flag
0x006625a2   byte      MulticastEnabled       Multicast flag
0x006625a1   byte      LateJoinEnabled        Late join flag
0x0065c02c   int       NetworkPort            Port number
Threading

Code: Select all

Address      Type   Name                   Description
0x006e3088   int    MainThreadID           SDL thread ID
0x006e3090   void*  MutexHandle            SDL_Mutex*
0x006e3988   void*  LoadThreadHandle       Background loader
0x006e3978   void*  Semaphore2             Sync primitive
0x006e3980   void*  Semaphore1             Sync primitive
libGLESv2.dll

Code: Select all

Address      Type     Name                   Description
0x6814c020   DWORD    TLS_INDEX              Windows TLS slot (-1=uninitialized)
0x68214410   void*[]  GLContextVTable        Context virtual function table
────────────────────────────────────────

25. GL Function Pointer Table

Runtime GL function pointers loaded from libGLESv2.dll via SDL_GL_GetProcAddress:

Code: Select all

Address      GL Equivalent              XREFs   Key Callers
0x0aea23a0   glDepthMask                2       SetDepthWriteMode
0x0aea2cb8   glBindVertexArray          17      FlushBatchedQuads, DrawGameObjects
0x0aea2d20   glDisable                  213     Most render functions
0x0aea2d28   glEnable                   58      SetupGLRenderState
0x0aea2d70   glBlendFunc                43      Many render functions
0x0aea2da0   glDrawArrays               -       GLDrawCall
0x0aea2e28   glDrawElements             -       GLDrawCall (indexed)
0x0aea2f40   glEnable variant           279     Most rendering
0x0aea2138   glBindTexture              -       DrawSprite2D, DrawBatchedPanelPolys
0x0aea2288   glBlendFunc                -       SetupGLRenderState
0x0aea5eb0   GL viewport fn             1       ViewportAndCameraSetup
0x0aea6570   glBlendFuncSeparate        85      SetupGLRenderState
0x0aea7910   GL viewport fn variant     1       ViewportAndCameraSetup
0x0aea77a8   glVertexAttribPointer      -       DrawSprite2D
0x0aea26c0   glVertexAttribPointer      -       DrawSprite2D
0x0aea6540   glVertexAttribPointer      -       DrawSprite2D
0x0aea3398   glGenBuffers               -       AllocOrResizeVBO
0x0aea2308   glBufferData               -       UploadVBOData
0x0aea2348   glBufferSubData            -       UploadVBOData
0x0aea2028   glUseProgram               -       DrawBatchedPanelPolys
0x0aea6d38   glBindProgramPipeline      -       SetupFrameUBOs
0x0aea6a00   glUniform1f                -       SetupFrameUBOs (fog density)
0x0aea6ab0   glUniform3f                -       SetupFrameUBOs (fog color)
────────────────────────────────────────

26. File Formats Discovered

Car Files

Code: Select all

cars/[carname]/
├── parameters.txt  ← Text format, 16 keywords, parsed by 0x0043b6c0
├── body.prm        ← Binary 3D model (magic 0x7830, not fully analyzed)
├── carbox.bmp      ← Selection icon
└── [texture].bmp   ← Car textures (referenced by TPAGE keyword)
parameters.txt Keywords

Code: Select all

Keyword        Offset   Type    Max
NAME           +0x14    string  63 chars
TPAGE          +0x54    string  63 chars
TCARBOX        +0x94    string  63 chars
BESTTIME       +0xE4    byte    0/1
SELECTABLE     +0xE5    byte    0/1
CPUSELECTABLE  +0xE6    byte    0/1
STATISTICS     +0xE7    byte    0/1
CLASS          +0xE8    int32   0-4
RATING         +0xEC    int32   stars
OBTAIN         +0xF0    int32   unlock
TOPEND         +0xF4    int32   speed
ACCELERATION   +0xF8    int32   accel
WEIGHT         +0xFC    int32   kg
TRANS          +0x100   int32   type
Track Files

Code: Select all

levels/[trackname]/
├── [trackname].inf  ← Text format, 6 keywords, parsed by 0x00451da0
├── [trackname].w    ← Binary world geometry (not analyzed)
├── reversed/[trackname].inf  ← Reverse mode
└── [textures].bmp   ← Track textures
.inf Keywords

Code: Select all

Keyword        Offset   Type    Format
NAME           +0x10    string  63 chars
GAMETYPE       +0x68    int32   2=standard
DIFFICULTY     +0x64    int32   1-5
OBTAIN         -        int32   unlock
CHALLENGE      +0x6C    int32   MM SS MS → ms
CHALLENGEREV   +0x70    int32   MM SS MS → ms
────────────────────────────────────────

27. Complete Function Index (250+)

By Category - Status Key: ✅=Analyzed ⚠️=Partial ❌=Not Exported

Core Game Loop (8 functions)

Code: Select all

Address      Name                           Status
0x004014c0   entry()                        ✅
0x00402ec0   MainGameLoop()                 ✅
0x00402980   ProcessSDLEvents()             ✅
0x00401610   FrameUpdateDispatcher()        ✅
0x005250c0   CalcDeltaTime()                ✅
0x00525350   AccumulateDeltaTime()          ✅
0x00525470   GetPerfCounter()               ✅
0x00539bc0   ScreenshotAndFrameEnd()        ✅
Game States (5 functions)

Code: Select all

Address      Name                           Status
0x00499b30   SplashScreenState()            ✅
0x00499690   RacingGameLoop()               ⚠️ Entry only
0x00543890   MultiplayerLobbyState()        ⚠️
0x00406b40   UnknownGameState()             ⚠️
0x0044c130   GameGaugeReplayState()         ✅
Car System (18 functions)

Code: Select all

Address      Name                           Status
0x0043f140   LoadAllCars()                  ✅
0x0043b6c0   ParseParametersTxt()           ✅
0x005bd590   InitializeCarStructure()       ✅
0x0043fac0   LoadUserCars()                 ✅
0x0043c580   InitRuntimeCarStruct()         ✅
0x004ab810   InitCarSlotFull()              ✅
0x005589b0   InitReplayCarSlot()            ✅
0x0043c160   FindCarIndexByName()           ✅
0x0043bdf0   UpdateCarSelectability()       ✅
0x004070e0   CheckFileIntegrity()           ✅
0x0049c080   PackPhysicsVectors()           ✅
0x004f03a0   CreateCarEntity()              ✅
0x004f0630   DestroyCarEntity()             ✅
0x004f06d0   DestroyAllCarEntities()        ✅
0x004f0850   FindCarByNetworkID()           ✅
0x004f0890   RegisterFinishTime()           ✅
0x004f0af0   SetAllCarsBoostState()         ✅
0x004f0b50   RestoreAllCarsStartState()     ✅
AI & Physics (14 functions)

Code: Select all

Address      Name                                Status
0x00408a60   CarPhysicsUpdate_AIBrain()          ✅ (1,517 lines)
0x004071c0   AI_Avoidance()                      ✅
0x00407400   InitAI_State()                      ✅
0x004074a0   ResetAIBehavior()                   ✅
0x004075f0   UpdateRacePositions()               ✅
0x00407930   AI_StuckDetection()                 ✅
0x00407cb0   CompareCarPassing()                 ✅
0x004c84a0   PerFramePhysicsWorldStep()          ✅
0x004ce590   UpdateCarGhostTransparency()        ✅
0x004d0c70   AnimationUpdate()                   ✅
0x004d1f20   LoadAnimationData()                 ✅
0x004b35b0   MeshVertexOBBCull()                 ✅
0x00499c40   GaussianElimination()               ✅
0x0049a3e0   ConjugateGradientSolver()           ⚠️
Race Session (16 functions)

Code: Select all

Address      Name                           Status
0x00450700   RaceSessionSetup()             ✅ (765 lines)
0x0044f1f0   AddParticipantAndCount()       ✅
0x0044f4f0   AddParticipantNoCount()        ✅
0x0044f7b0   SetupAllRaceCars()             ✅
0x0044f640   CreateSinglePlayerCar()        ✅
0x0044fb30   RandomizeCarPicks()            ✅
0x0044f980   AssignStartPositions()         ✅
0x004504e0   SelectRandomCar()              ✅
0x004505c0   GetCarColor()                  ✅
0x00450600   GetRandomTrack()               ✅
0x0044cb60   InitPlayerCar()                ✅
0x0044ce10   ResetPlayerCarBuffer()         ✅
0x004efd50   SetCarBehaviourState()         ✅
0x0048a560   SetRaceState()                 ✅
0x0048a5c0   GetRaceState()                 ✅
0x00541f80   RaceEndManager()               ✅
Waypoint / Navigation (12 functions)

Code: Select all

Address      Name                                Status
0x0040fc20   FreeWaypointTables()                ✅
0x0040fd90   FindCarInZoneSectionOBB()           ✅
0x0040ff20   FindCarCurrentZone()                ✅
0x0040ffb0   FindCarCurrentZoneBrute()           ✅
0x0040e150   UpdateCarRoutePosition()            ✅ (14 XREFs)
0x00410070   DeleteWaypointNode()                ✅
0x00410260   ShowErrorDialog()                   ✅
0x00410500   WaypointNodeLinkPatch()             ✅
0x00410680   GetWaypointNodeClosestToRay()       ✅
0x00410860   WaypointDijkstraRelax()             ✅
0x004103e0   FindNearestWaypointNode()           ✅
0x00410020   WaypointLinkPromote()               ✅
Rendering (30+ functions)

Code: Select all

Address      Name                                       Status
0x004628b0   DrawSprite2D()                             ✅ (62 call sites)
0x00491f60   SetupGLRenderState()                       ✅ (70 call sites)
0x00492150   DrawTexturedQuad()                         ⚠️ (510 call sites, 661 lines)
0x004962d0   LoadTextureByName()                        ✅
0x00539fa0   SetDepthWriteMode()                        ✅
0x004a4120   ViewportAndCameraSetup()                   ✅ (20 call sites)
0x004884d0   GL_SetupNormalRenderState()                ✅
0x004827e0   FlushBatchedQuads()                        ✅
0x004886b0   RenderSceneFull()                          ✅
0x00488750   RenderSceneLightBatch()                    ✅
0x00461d30   FlushBatchedPanelPolys()                   ✅
0x004621b0   DrawBatchedPanelPolys()                    ✅
0x00491900   FlushBatchedTextPolys()                    ✅
0x00491be0   DrawBatchedTextPolys()                     ✅
0x004b6b60   SortTrackMeshObjects()                     ✅
0x00500f60   SortDynamicObjects()                       ✅
0x004d4260   DrawGameObjects()                          ✅
0x00480fb0   DrawMeshObject()                           ✅
0x00481320   RenderCarMeshes()                          ✅
0x00481760   RenderTransparentAndSortedObjects()        ✅
0x0047d220   UpdateGhostRenderEntries()                 ✅
0x0053a070   FindBestGLResourceSlot()                   ✅
0x0053a460   AllocOrResizeVBO()                         ✅
0x0053a800   UploadVBOData()                            ✅
0x0053ab80   GLDrawCall()                               ✅
0x0053b020   SetupFrameUBOs()                           ✅
0x0053de80   CommitFrameRenderWork()                    ✅
0x004d46f0   FrustumCullSphere()                        ✅
0x00488800   SetFogDistances()                          ✅
0x004888a0   SetFogParams()                             ✅
Audio (25+ functions)

Code: Select all

Address      Name                           Status
0x00527230   AudioInit()                    ✅
0x00527400   AudioShutdown()                ✅
0x005277d0   LoadAllSfx()                   ✅
0x00527a20   FreeAllSfx()                   ✅
0x00527ba0   StopAllSfx()                   ✅
0x00526d70   GetFreeSfxSource()             ✅
0x00527520   LoadSfxSlot()                  ✅
0x00527630   GetSfxSlotByName()             ✅
0x00527f20   PlaySfxSimple()                ✅
0x005280a0   PlaySfx3D()                    ✅
0x005282d0   StartLoopingSfx()              ✅
0x005285b0   PlayMusic()                    ✅
0x00526f10   UpdateMusicPlayback()          ✅
0x00526b60   ScanMusicDirectory()           ✅
0x00527cf0   PauseAllSfx()                  ✅
0x00527da0   ResumeAllSfx()                 ✅
0x00561a20   OpenAL_Init()                  ✅
0x00561ad0   OpenAL_Shutdown()              ✅
0x00562e90   LoadWAVToBuffer()              ✅
0x00563f60   OpenMusicStream()              ✅
0x005668b0   StartMusicPlayback()           ✅
0x005263c0   Calc3DAtten()                  ✅
Input (5 functions)

Code: Select all

Address      Name                           Status
0x00529e50   KeyboardStateSnapshot()        ✅
0x00529f60   MouseInputUpdater()            ✅
0x0052a910   ControllerStateUpdater()       ✅
0x00445d20   CheckPlayerReady()             ✅
0x00495a90   FreeTextureSlot()              ✅
Editor (8 functions)

Code: Select all

Address      Name                              Status
0x00418900   EditorModeDispatch()              ✅
0x00418a20   EditModeUpdate()                  ✅
0x00418d60   ShowStatusMessage()               ✅
0x00418d90   ScreenToWorldRay()                ✅
0x00418eb0   WorldPointVisible()               ✅
0x00414c60   AINodeBoxRender()                 ✅
0x004236b0   WireframeBoundingBoxRender()      ✅
0x0042e8c0   TrackSectionDelete()              ✅
Weapon / Camera / Misc (15+ functions)

Code: Select all

Address      Name                           Status
0x004a5500   ResetProjectileArray()         ✅
0x004a1290   InitWeaponSlot()               ✅
0x004a4910   CameraEntityViewportUpdate()   ✅
0x004a5ce0   CameraEntityInit()             ✅
0x004a5b50   FindNearestPickupNode()        ✅
0x004f1560   DispatchTriggerHandlers()      ✅
0x004f1910   LoadTriggersFromFile()         ✅
0x0044c820   GameGaugeFPSRecorder()         ✅
0x004442b0   RenderScrollingText()          ✅
0x00404c30   LevelLoad()                    ✅
0x0044cec0   RecordGhostFrame()             ✅
0x0044d040   CommitGhostLapFrame()          ✅
0x0044d0c0   RecordGhostPosition()          ✅
0x004102d0   CreateGhostPath()              ✅
0x00451ab0   SetupRaceTrackRandom()         ✅
libGLESv2.dll (25+ functions)

Code: Select all

Address      Name                           Status
0x67c77ae0   GetCurrentContext()            ✅
0x67f20810   TlsGetValueWrapper()           ✅
0x67c779b0   CreateContext()                ✅
0x67cec510   ValidateContext()              ✅
0x67cec310   InitializeContextHandle()      ✅
0x67c8a750   IsContextLost()                ✅
0x67c95040   glDrawArrays_Impl()            ✅
0x67d5da10   glDrawArrays_Validate()        ✅
0x67c8bfd0   glClear_Impl()                 ✅
0x67c8de90   glUseProgram_Impl()            ✅
+ 15 more    Texture/Buffer/Shader funcs    ✅
────────────────────────────────────────

28. XMenu Mod Framework - Design & Implementation

What is XMenu?

A modular, extensible mod framework for RVGL combining:

• ZMenu's power - deep memory manipulation, chaos mod, 512 opponents
• Geode's elegance - clean UI, plugin architecture, community mod loading
• New ideas - Quake movement, GTA cameras, gravity fields, Twitch voting, Lua scripting

Architecture

Code: Select all

rvgl.exe loads → libdiscord-rpc.dll [PROXY] → xmenu_core.dll
  ├─ Hook Manager (IAT patching, detours)
  ├─ Memory Patcher (safe read/write, pattern scanning)
  ├─ Module Registry (load/enable/disable feature modules)
  ├─ UI Renderer (Dear ImGui via SDL_GL_SwapWindow hook)
  ├─ Config Manager (JSON profiles per module)
  ├─ Lua VM (5.4, for community plugins)
  └─ Event Bus (inter-module communication)
Implementation Status - 18 Critical Hook Points

Code: Select all

Hook Target                     Address      Purpose
SDL_GL_SwapWindow               IAT          Render XMenu overlay
SDL_PollEvent                   IAT          Intercept menu input
RacingGameLoop                  0x00499690   Per-frame game tick
FrameUpdateDispatcher           0x00401610   Delta time manipulation
InitCarSlotFull                 0x004ab810   Intercept car creation
RaceSessionSetup                0x00450700   Modify participant table
AddParticipantAndCount          0x0044f1f0   Inject custom participants
CalcDeltaTime                   0x005250c0   Time manipulation
KeyboardStateSnapshot           0x00529e50   Custom keybinds
MouseInputUpdater               0x00529f60   Mouse camera rotation
CameraEntityViewportUpdate      0x004a4910   Camera overrides
CameraEntityInit                0x004a5ce0   Camera type injection
SetCarBehaviourState            0x004efd50   AI/player swap
DrawSprite2D                    0x004628b0   HUD modification
SetupGLRenderState              0x00491f60   Visual effects
RaceEndManager                  0x00541f80   Race outcome manipulation
SetDepthWriteMode               0x00539fa0   Rendering overrides
UpdateFadeTransition            0x0048a5d0   Race state transitions
────────────────────────────────────────

29. Modding Opportunities & Hook Points

libGLESv2.dll Hooks

Code: Select all

// Hook ALL GL calls with one function:
GLContext* Hook_GetCurrentContext() {
    GLContext* ctx = Original_0x67c77ae0();
    // Log, modify, inject custom data
    return ctx;
}

// Hook rendering:
void Hook_glDrawArrays(mode, first, count) { /* count tris, replace geometry */ }
void Hook_glBindTexture(target, texture) { /* replace textures */ }
void Hook_glUseProgram(program) { /* inject custom shaders */ }
RVGL.exe Hooks

Code: Select all

// Game state injection:
void Hook_GameState() { (*Original_DAT_006e30a0)(); /* inject custom logic */ }

// Car manipulation:
*(DAT_0acee7e8 + 0x6A44) = 1;  // Make player invincible
*(DAT_0acee7e8 + 0x04) = 9;    // Set car to spectator
*(DAT_0acee7e8 + 0x698C) = 5000.0f;  // Set speed

// Race manipulation:
*(_DAT_00f3eb04) = 30;  // Max participants
*(DAT_006e34d4) = 999;  // 999 laps
*(DAT_016942dc) = 5;    // Force race state
────────────────────────────────────────

30. Overall Completion Status

Code: Select all

Component              Completion   Functions   Key Achievement
libGLESv2.dll          95%          25+         Full TLS/context system, all GL patterns
Core Game Loop         ~75%         8           Entry, states, events, frame dispatch
Car System             ~90%         18          Static pool, runtime entity, full lifecycle
Track System           ~80%         6           Loading, parsing, zone lookup
AI System              ~85%         14          1,517-line brain, 13 states, navigation
Rendering              ~75%         30+         Full 2D pipeline, 3D sort/draw, batch, GPU layer
Audio                  ~90%         25+         Complete SFX + music lifecycle
Input                  ~85%         5           Keyboard, mouse, controller, touch
Race Session           ~85%         16          Full setup, participant table, end manager
Waypoints              ~80%         12          Node graph, Dijkstra, zone lookup
Physics                ~40%         4           World step, solvers, partial body struct
Ghost/Replay           ~80%         4           Full recording/playback pipeline
Editor                 ~60%         8           Dispatch, sub-modes, ray picking
Animation              ~70%         2           16-bone keyframe system
Weapons                ~60%         4           Projectile array, slot init
Camera                 ~70%         3           Entity system, viewports, split-screen
Networking             ~15%         2           Packet handler identified, partial
Grand Totals

• 250+ functions documented
• 60+ global variables mapped
• 10+ data structures fully defined
• 18+ data structures partially defined
• 27 command-line arguments discovered
• 11+ game modes identified
• 13 AI states mapped
• 601 GL functions pattern-analyzed
• 38 SFX catalogued

────────────────────────────────────────

Search Patterns found in code

• "parameters.txt" → Car loader
• ".inf" → Track loader
• ".prm" → Model loader
• ".w" → World loader
• "SDL_" → SDL calls
• "glDraw" → Rendering
• "malloc" → Allocations

This document represents the complete knowledge base of the RVGL reverse engineering project as of March 14, 2026.
From LJP
:blender: :re-volt:
Post Reply