Initial commit

This commit is contained in:
KeybadeBlox 2025-12-10 22:38:12 -05:00
commit aaddf5213a
6 changed files with 258 additions and 0 deletions

4
objects.csv Normal file
View file

@ -0,0 +1,4 @@
Proposed name,.text,D3D,DSOUND,MMATRIX,XGRPH,XPP,.rdata,.data,DOLBY
Core.o,0x00011000-0x00013FF,,,,,,0x001C4390-0x001C44FF,0x00251D40-0x00251DAB (maybe),
Jet2.o,0x0006F9E0-0x0006FA6F,,,,,,,0x0022FCE0-0x0022FCE7,
MMatrix.o,,,,0x001BA8A0-0x001BBAAF,,,,0x00264BD8-0x00264C13,
1 Proposed name .text D3D DSOUND MMATRIX XGRPH XPP .rdata .data DOLBY
2 Core.o 0x00011000-0x00013FF 0x001C4390-0x001C44FF 0x00251D40-0x00251DAB (maybe)
3 Jet2.o 0x0006F9E0-0x0006FA6F 0x0022FCE0-0x0022FCE7
4 MMatrix.o 0x001BA8A0-0x001BBAAF 0x00264BD8-0x00264C13

13
readme.md Normal file
View file

@ -0,0 +1,13 @@
# Jet Set Radio Future Decompilation Notes
This is just a public holding space for anything I put together as a part of
the JSRF decompilation effort.
`objects.csv` is a table of suspected object file boundaries for delinking.
The addresses given in each section are runtime memory addresses (as one would
see in e.g. Ghidra).
The `src/` directory contains decompiled code and data. Each symbol is
annotated with its corresponding memory address in the original binary, and
functions are marked as perfectly or imperfectly matching. It's not
necessarily intended to be compilable, but more scratch space for noting down
what I've worked out.

1
src/core.cpp Normal file
View file

@ -0,0 +1 @@
#include "core.hpp"

179
src/core.hpp Normal file
View file

@ -0,0 +1,179 @@
#ifndef CORE_HPP
typedef bool32 unsigned; // Need to find a clean way of representing this
typedef Mat4 D3DVECTOR4[4]; // Should probably be defined somewhere else
struct GraphicsPerformanceCounters { // Would come from header with Graphics COM object
unsigned fps;
unsigned trianglesPerSecond;
unsigned frameTriangleCnt;
unsigned unknown0xC;
unsigned unknown0x10;
unsigned unknown0x14;
}
enum DrawMode { DRAW_YES, DRAW_WAITVBLANK, DRAW_NO };
// Base class of most objects
class GameObj {
enum GameObjFlags {
GOF_SOMETHINGLINKED_ALTLIST = 1 << 0,
GOF_SKIPDRAWCHILDREN = 1 << 16,
GOF_SKIPDRAWASCHILD = 1 << 18,
GOF_SKIPDRAWASROOT = 1 << 22,
GOF_EXCLUDEFROMSOMETHINGLINKED = 1 << 30,
GOF_DELETEAFTEREXEC = 1 << 31
} flags;
// Position in g_game->objects array
// Different indices and ranges are dedicated to different kinds of
// objecs.
enum GameObjIndex {
OBJ_NOTINDEXED = -1, // Not stored in array
OBJ_DIRECTOR = 0
// TODO
} index;
unsigned unknown0xC;
float unknown0x10;
unsigned sortKey; // Four-level key, one byte each
D3DVECTOR unknown0x18;
// Links forming a tree of objects
GameObj * parent;
GameObj * firstChild;
GameObj * prevSibling;
GameObj * nextSibling;
// Some kind of linked list walked during rendering
GameObj * somethingLinkedNext;
GameObj * * somethingLinkedPrevNext;
GameObj * * * somethingLinkedEndNextPtr;
// Another linked list sort of arrangement
GameObj * someKindOfNextObj;
public:
virtual ~GameObj();
GameObj(GameObj * parent, GameObjIndex index, GameObjFlags flags);
// Each frame, one of these trios of methods is called depending on
// which state the game is in
// Default implementation of each does nothing; inheriting objects
// override these methods to run some code during each phase of each
// frame.
virtual void execDefault();
virtual void postExecDefault();
virtual void drawDefault();
virtual void execEvent();
virtual void postExecEvent();
virtual void drawEvent();
virtual void execCoveredPause();
virtual void postExecCoveredPause();
virtual void drawCoveredPause();
virtual void execFreezeCam();
virtual void postExecFreezeCam();
virtual void drawFreezeCam();
virtual void execUncoveredPause();
virtual void postExecUncoveredPause();
virtual void drawUncoveredPause();
// TODO: non-virtual methods
};
// Top-level globally-accessible "god object" that runs the main loop and
// provides global access to most other objects and many variables
class Game {
char unknown0x4[4];
unsigned unknown0x8;
unsigned * unknown0xC;
int initState;
unsigned unknown0x14;
bool32 drawProfilingInfo;
int unknown0x1C;
bool32 logosStarted;
bool32 fatalErr;
D3DCOLOR colour;
D3DCOLOR ambientColour;
D3DCOLOR shadowColour;
D3DCOLOR bgColour;
D3DCOLOR bgColourFallback;
bool32 useFallbackBgColour;
// Game state used to select GameObj methods to call in main loop
// If multiple states are acivated, the precedence is
// coveredPause > Event > FreezeCam > UncoveredPause > Default
bool32 coveredPause; // Game paused with world not visible
bool32 event; // Events (cutscenes)
bool32 freezeCam; // Time-frozen camera shots
bool32 uncoveredPause; // Game paused with world visible, or
// automatic pause at start of mission
bool32 setCoveredPauseNextFrame;
bool32 unsetCoveredPauseNextFrame;
bool32 setEventNextFrame;
bool32 unsetEventNextFrame;
bool32 setFreezeCamNextFrame;
bool32 unsetFreezeCamNextFrame;
bool32 setUncoveredPauseNextFrame;
bool32 unsetUncoveredPauseNextFrame;
unsigned unknown0x70;
bool32 skipDraw;
int zeroedByExec;
GraphicsPerformanceCounters perfCounters;
DrawMode drawMode;
// Globally accessible objects and variables
GameObj * objects[7668];
unsigned globals[461]; // Items may be any 32-bit type, e.g. ptr
GameObj * somethingLinkedBHead;
GameObj * * somethingLinkedBEndNext;
GameObj * somethingLinkedAHead;
GameObj * * somethingLinkedAEndNext;
GameObj * sortedLinkedListHead;
GameObj * * sortedLinkedListEndNext;
GameObj * linkedListsByKeyHeads [256];
GameObj * * linkedListByKeyEndNexts[256];
unsigned unknown0x87B4;
LARGE_INTEGER execPerfCount;
LARGE_INTEGER drawPerfCount;
unsigned unknown0x87C8;
unsigned unknown0x87CC;
unsigned frameCnt1;
unsigned unknown0x87D4;
unsigned unknown0x87D8;
GameObj * rootExecObj;
int frameCnt2;
int frameCnt3;
unsigned gameObjCnt;
GameObj * rootDrawObj;
int unknown0x87F0;
int unknown0x87F4;
Mat4 unknown0x87F8;
unsigned unknown0x8838;
unsigned unknown0x883C;
public:
Game(unsigned *, unsigned);
virtual ~Game();
// TODO: methods
};
#endif

15
src/jet2.cpp Normal file
View file

@ -0,0 +1,15 @@
#include "core.hpp"
// Address: 0x0022FCE0
Game * g_game;
// Address: 0x0006F9E0
// Matching: no
void main(void) {
g_game = new Game(NULL, 0);
g_game->initExecRootObj();
g_game->mainLoop();
delete g_game;
}

46
src/mmatrix.cpp Normal file
View file

@ -0,0 +1,46 @@
// Address: 0x001BB690
// Matching: yes
HRESULT __stdcall initMatrices(unsigned const count) {
/* Initialize the matrix stack with the given number of matrices.
The requested number of matrices is rounded up to the nearest multiple of two.
The initialized matrices are accessible through g_matrices.
*/
// Allocate matrices
unsigned i = (count + 1) & 0xFFFFFFFE; // Round up
Mat4 * const mats = (Mat4 *)VirtualAlloc(
NULL,
(i + 2) * sizeof *mats,
MEM_COMMIT|MEM_RESERVE,
PAGE_READWRITE
);
if (mats != NULL) {
Mat4 * mat = mats + 2;
// Initialize each matrix to identity
if (i > 0) for (; i > 0; i--) {
float * entry = (float *)mat;
for (unsigned j = 0; j < sizeof *mat/sizeof *entry; j++) {
*entry = 0;
entry += 1;
}
(*mat)[3].w = 1;
(*mat)[2].z = 1;
(*mat)[1].y = 1;
(*mat)[0].x = 1;
mat++;
}
// Assign to g_matrices for later access
mat = mats + 2;
g_matrices[1] = mats;
g_matrices[2] = mat;
g_matrices[0] = mats;
g_matricesHead = g_matrices + 2;
return ERROR_SUCCESS;
}
return E_OUTOFMEMORY;
}