mirror of
https://codeberg.org/KeybadeBlox/JSRF-Decompilation.git
synced 2026-02-20 10:17:03 +03:00
Complete delink workflow; separate from decomp
We can now create a fresh Ghidra project, import the JSRF executable into it, import symbols into it, delink object files from it, and then decompile with objdiff. Just needs some documentation.
This commit is contained in:
parent
87c56f01d6
commit
1a48d4323e
17 changed files with 1178 additions and 8 deletions
1
decompile/src/Core.cpp
Normal file
1
decompile/src/Core.cpp
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include "Core.hpp"
|
||||
189
decompile/src/Core.hpp
Normal file
189
decompile/src/Core.hpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/* JSRF Decompilation: Core.hpp
|
||||
Game and GameObj classes that form the foundation of the JSRF game code.
|
||||
*/
|
||||
|
||||
#ifndef CORE_HPP
|
||||
#define CORE_HPP
|
||||
|
||||
#include "D3D.hpp"
|
||||
#include "MMatrix.hpp"
|
||||
#include "Std.hpp"
|
||||
#include "Win32.hpp"
|
||||
|
||||
|
||||
// TODO; move to header for Graphics COM object in Smilebit libraries
|
||||
struct GraphicsPerformanceCounters {
|
||||
unsigned fps;
|
||||
unsigned trianglesPerSecond;
|
||||
unsigned frameTriangleCnt;
|
||||
unsigned unknown0xC;
|
||||
unsigned unknown0x10;
|
||||
unsigned unknown0x14;
|
||||
};
|
||||
|
||||
// Base class of most objects (and everything in g_game->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 otherBitfield;
|
||||
float reverseSortKey; // Sign flipped to produced sortKey
|
||||
unsigned sortKey; // Four-level key, one byte each
|
||||
D3DVECTOR someTranslation;
|
||||
|
||||
// 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
|
||||
extern class Game {
|
||||
char unknown0x4[4];
|
||||
unsigned unknown0x8;
|
||||
unsigned * unknown0xC;
|
||||
int initState;
|
||||
unsigned unknown0x14;
|
||||
BOOL drawProfilingInfo;
|
||||
int unknown0x1C;
|
||||
BOOL logosStarted;
|
||||
BOOL fatalErr;
|
||||
|
||||
D3DCOLOR colour;
|
||||
D3DCOLOR ambientColour;
|
||||
D3DCOLOR shadowColour;
|
||||
D3DCOLOR bgColour;
|
||||
D3DCOLOR bgColourFallback;
|
||||
BOOL 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
|
||||
BOOL coveredPause; // Game paused with world not visible
|
||||
BOOL event; // Events (cutscenes)
|
||||
BOOL freezeCam; // Time-frozen camera shots
|
||||
BOOL uncoveredPause; // Game paused with world visible, or
|
||||
// automatic pause at start of mission
|
||||
|
||||
BOOL setCoveredPauseNextFrame;
|
||||
BOOL unsetCoveredPauseNextFrame;
|
||||
BOOL setEventNextFrame;
|
||||
BOOL unsetEventNextFrame;
|
||||
BOOL setFreezeCamNextFrame;
|
||||
BOOL unsetFreezeCamNextFrame;
|
||||
BOOL setUncoveredPauseNextFrame;
|
||||
BOOL unsetUncoveredPauseNextFrame;
|
||||
|
||||
unsigned unknown0x70;
|
||||
BOOL skipDraw;
|
||||
int zeroedByExec;
|
||||
GraphicsPerformanceCounters perfCounters;
|
||||
|
||||
enum DrawMode {
|
||||
DRAW_YES,
|
||||
DRAW_WAITVBLANK,
|
||||
DRAW_NO
|
||||
} 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];
|
||||
|
||||
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();
|
||||
|
||||
void initExecRootObj();
|
||||
void mainLoop();
|
||||
// TODO: other methods
|
||||
} * g_game;
|
||||
|
||||
|
||||
#endif
|
||||
16
decompile/src/D3D.hpp
Normal file
16
decompile/src/D3D.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/* JSRF Decompilation: D3D.hpp
|
||||
Direct3D8 declarations.
|
||||
*/
|
||||
|
||||
#ifndef D3D_HPP
|
||||
#define D3D_HPP
|
||||
|
||||
#include "Win32.hpp"
|
||||
|
||||
|
||||
typedef DWORD D3DCOLOR;
|
||||
|
||||
struct D3DVECTOR { float x, y, z ; };
|
||||
struct D3DVECTOR4 { float x, y, z, w; };
|
||||
|
||||
#endif
|
||||
19
decompile/src/Jet2.cpp
Normal file
19
decompile/src/Jet2.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#pragma bss_seg(".data")
|
||||
|
||||
#include "Core.hpp"
|
||||
|
||||
|
||||
// Address: 0x0022FCE0
|
||||
// Core.cpp really seems like a more natural place to put this, but it doesn't
|
||||
// appear to be with Core.cpp's other data in .data
|
||||
Game * g_game;
|
||||
|
||||
|
||||
// Address: 0x0006F9E0
|
||||
// Matching: yes
|
||||
void main(void) {
|
||||
g_game = new Game(NULL, 0);
|
||||
g_game->initExecRootObj();
|
||||
g_game->mainLoop();
|
||||
delete g_game;
|
||||
}
|
||||
56
decompile/src/MMatrix.cpp
Normal file
56
decompile/src/MMatrix.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma code_seg("MMATRIX")
|
||||
|
||||
|
||||
// Address: 0x00264C04
|
||||
Mat4 * * g_matricesHead;
|
||||
|
||||
// Address: 0x00264C08
|
||||
Mat4 * g_matrices[3];
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
14
decompile/src/MMatrix.hpp
Normal file
14
decompile/src/MMatrix.hpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* JSRF Decompilation: MMatrix.hpp
|
||||
Smilebit's stack-based matrix math library.
|
||||
*/
|
||||
|
||||
#ifndef MMATRIX_HPP
|
||||
#define MMATRIX_HPP
|
||||
|
||||
#include "D3D.hpp"
|
||||
|
||||
|
||||
// 4x4 matrix type
|
||||
typedef D3DVECTOR4 Mat4[4];
|
||||
|
||||
#endif
|
||||
12
decompile/src/Std.hpp
Normal file
12
decompile/src/Std.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/* JSRF Decompilation: Std.hpp
|
||||
C(++) standard library definitions. Implemented in the repository instead of
|
||||
linking to an outside stdlib to ensure consistency (this may not actually be
|
||||
possible to accomplish, but we'll go for it for now).
|
||||
*/
|
||||
|
||||
#ifndef STD_HPP
|
||||
#define STD_HPP
|
||||
|
||||
#define NULL 0
|
||||
|
||||
#endif
|
||||
40
decompile/src/Win32.hpp
Normal file
40
decompile/src/Win32.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/* JSRF Decompilation: Win32.hpp
|
||||
Definitions normally provided by Windows headers.
|
||||
*/
|
||||
|
||||
#ifndef WIN32_HPP
|
||||
#define WIN32_HPP
|
||||
|
||||
// The famous Win32 typedefs
|
||||
typedef unsigned char UCHAR;
|
||||
typedef char CHAR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef short SHORT;
|
||||
typedef unsigned int UINT;
|
||||
typedef int INT;
|
||||
typedef unsigned long ULONG;
|
||||
typedef long LONG;
|
||||
typedef unsigned __int64 ULONGLONG;
|
||||
typedef __int64 LONGLONG;
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
typedef int BOOL;
|
||||
typedef float FLOAT;
|
||||
|
||||
// 64-bit integer compatibility type
|
||||
union LARGE_INTEGER {
|
||||
struct {
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
};
|
||||
struct {
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
} u;
|
||||
LONGLONG QuadPart;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue