Compare commits

..

No commits in common. "823b19371ccdf6dcef61f226edcd4973fa8f6222" and "d7abbb79c0235b814477f2f478f2bf83f5d031d2" have entirely different histories.

9 changed files with 25 additions and 114 deletions

View file

@ -3,7 +3,7 @@
# All object files to link together # All object files to link together
OBJ = src/JSRF/Jet2.obj src/JSRF/Core.obj src/JSRF/GameData.obj\ OBJ = src/JSRF/Jet2.obj src/JSRF/Core.obj src/JSRF/GameData.obj\
src/XDK/Xapi/xapi0.obj src/XDK/CRT/CRT0.obj
# Import library for the only thing we don't compile ourselves, the Xbox kernel # Import library for the only thing we don't compile ourselves, the Xbox kernel
LIB = lib/xboxkrnl.lib LIB = lib/xboxkrnl.lib
@ -14,7 +14,7 @@ all: $(OBJ) # For now, just compile all the object files
## Build commands ## Build commands
.SUFFIXES: .c .cpp .obj .def .lib .exe.xbe .SUFFIXES: .cpp .obj .def .lib .exe.xbe
# Convert compiled executable into a working Xbox executable # Convert compiled executable into a working Xbox executable
# (TODO: we may want to fork cxbe to add section checksums and the game ID) # (TODO: we may want to fork cxbe to add section checksums and the game ID)
@ -32,7 +32,7 @@ src/JSRF/Jet2.exe: $(OBJ) $(LIB)
# Compile object files from source # Compile object files from source
.c.obj: .c.obj:
CL.EXE /nologo /Wall /W4 /O1giy /Fo$@ /c $< CL.EXE /nologo /Wall /W4 /Ogityb0 /GfX /Fo$@ /c $<
.cpp.obj: .cpp.obj:
CL.EXE /nologo /Wall /W4 /Ogityb0 /GfX /Fo$@ /c $< CL.EXE /nologo /Wall /W4 /Ogityb0 /GfX /Fo$@ /c $<
@ -41,9 +41,9 @@ src/JSRF/Jet2.exe: $(OBJ) $(LIB)
src/JSRF/Jet2.obj: src/JSRF/Core.hpp src/XDK/CRT/stddef.h src/XDK/D3D.h\ src/JSRF/Jet2.obj: src/JSRF/Core.hpp src/XDK/CRT/stddef.h src/XDK/D3D.h\
src/XDK/Win32.h src/XDK/Win32.h
src/JSRF/Core.obj: src/JSRF/Core.hpp src/MUSASHI/MMatrix.hpp\ src/JSRF/Core.obj: src/JSRF/Core.hpp src/Smilebit/MMatrix.hpp\
src/XDK/CRT/stddef.h src/XDK/D3D.h src/XDK/Win32.h src/XDK/CRT/stddef.h src/XDK/D3D.h src/XDK/Win32.h
src/JSRF/GameData.obj: src/JSRF/GameData.hpp src/JSRF/GameData.obj: src/JSRF/GameData.hpp
src/XDK/Xapi/xapi0.obj: src/XDK/Win32.h src/XDK/CRT/CRT0.obj: src/XDK/Win32.h

View file

@ -1,8 +1,6 @@
{ {
"custom_make": "NMAKE.EXE", "custom_make": "NMAKE.EXE",
"watch_patterns": [ "watch_patterns": [
"*.c",
"*.h",
"*.cpp", "*.cpp",
"*.hpp" "*.hpp"
], ],
@ -50,7 +48,7 @@
"target_path": "target/XDK/Xapi/xapi0.obj", "target_path": "target/XDK/Xapi/xapi0.obj",
"base_path": "src/XDK/Xapi/xapi0.obj", "base_path": "src/XDK/Xapi/xapi0.obj",
"metadata": { "metadata": {
"complete": true, "complete": false,
"source_path": "src/XDK/Xapi/xapi0.c" "source_path": "src/XDK/Xapi/xapi0.c"
} }
} }

View file

@ -5,7 +5,7 @@ Game and GameObj classes that form the foundation of the JSRF game code.
#ifndef CORE_HPP #ifndef CORE_HPP
#define CORE_HPP #define CORE_HPP
#include "../MUSASHI/MMatrix.hpp" #include "../Smilebit/MMatrix.hpp"
#include "../XDK/CRT/stddef.h" #include "../XDK/CRT/stddef.h"
#include "../XDK/D3D.h" #include "../XDK/D3D.h"
#include "../XDK/Win32.h" #include "../XDK/Win32.h"

View file

@ -21,13 +21,10 @@ extern struct IMAGE_TLS_DIRECTORY {
DWORD SizeOfZeroFill; DWORD SizeOfZeroFill;
DWORD Characteristics; DWORD Characteristics;
} _tls_used; } _tls_used;
extern int _tls_array;
extern int _tls_index;
extern int XapiTlsSize; extern int XapiTlsSize;
DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter); DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter);
void __stdcall XapiInitProcess(void);
BOOL __stdcall CloseHandle (HANDLE hHandle ); BOOL __stdcall CloseHandle (HANDLE hHandle );
typedef DWORD (__stdcall * LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); typedef DWORD (__stdcall * LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
@ -46,106 +43,22 @@ void __stdcall XapiBootToDash(
DWORD dwParameter2 DWORD dwParameter2
); );
void __stdcall _rtinit(void);
void __stdcall _cinit (void);
// Every program is supposed to have a main(), so we can just assume its // Every program is supposed to have a main(), so we can just assume its
// existence with a declaration here. Interestingly, it's called with // existence with a declaration here
// arguments here despite being declared without any on the developer's side. int main(void);
int main(
int argc,
char * * argv,
char * * envp
);
// Address: 0x00147FB4 // Address: 0x00147FB4
// Status: matching // Status: unimplemented
__declspec(naked) DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter) { DWORD __stdcall mainXapiStartup(LPVOID lpThreadParameter) {
/* Runs some Xbox-specific initialization and then calls main() /* Runs some Xbox-specific initialization and then calls main() */
It appears to be truly impossible in Visual C++ 7.0 to access the FS register main();
without writing assembly, and also for inline assembly to write to a variable return 0;
in a register rather than on the stack. Thus, the only apparent way to make
the middle part of the function match is through writing the instructions
directly. Given that the C parts of this function are so simple that a human
and a compiler would reasonably produce the exact same code, and this function
exhibits other oddities mentioned in the body, it's likely this whole function
was originally written purely in assemblys. In the spirit of decompilation,
however, we'll lift what we can into C.
*/
XapiInitProcess();
// Honestly unsure what's being done here, as FS doesn't seem to follow
// the same structure as 32-bit Windows
__asm {
mov eax, fs:[0x20]
mov eax, [eax+0x250]
test eax, eax
je zero
mov ecx, [eax+0x24]
jmp store
/*
All this jumping around is strange, as it could easily be a
single branch, which is very plain to see if written out as C
(in fact, while MSVC's behaviour hasn't been tested, it
wouldn't take a very smart compiler to optimize this out if it
was written this way in C). It seems likely this is awkward
human-written assembly.
*/
zero:
xor ecx, ecx
store:
test ecx, ecx
je end
/*
This section is suspect because of how it preserves edi despite
it not being used anywhere else, as if it was a separately
written function. If it was a function, it must have been
inlined, but it couldn't be because it must be called from
assembly to use the value in ecx that never went on the stack
(as passing data from C to assembly has to do). Notably, this
function's calling convention does require edi to be preserved,
but if left up to the compiler, it will push and pop edi in the
prologue and epilogue, not here (which this function must be
declared as naked to avoid).
It may be that this function was originally written entirely in
assembly and declared naked, with the author deciding to
preserve edi only in this one section using it.
*/
push edi
mov eax, fs:[0x28]
mov edi, fs:[_tls_array]
mov edx, [_tls_index]
mov edx, [edi + edx*0x4]
sub edx, [eax + 0x28]
mov byte ptr [ecx], 0x1
add edx, _tls_array
mov [ecx + 0x4], edx
pop edi
end:
};
_rtinit();
_cinit();
main(0, NULL, NULL);
XapiBootToDash(XLD_LAUNCH_DASHBOARD_ERROR, XLD_ERROR_INVALID_XBE, 0);
// Return 0 to satisfy signature required for thread functions
_asm {
xor eax, eax
ret 4
};
} }
// Address: 0x00148023 // Address: 0x00148023
// Status: matching // Status: nonmatching
void mainCRTStartup(void) { void mainCRTStartup(void) {
/* The true entrypoint of the game, spawning a thread for the rest to run in /* The true entrypoint of the game, spawning a thread for the rest to run in
The linker automatically sets this function to the entrypoint. The linker automatically sets this function to the entrypoint.
@ -153,11 +66,11 @@ The linker automatically sets this function to the entrypoint.
HANDLE thread; HANDLE thread;
// Figure out available thread-local storage // Figure out available thread-local storage
XapiTlsSize = 4 + (( XapiTlsSize = (
(_tls_used.EndAddressOfRawData - _tls_used.StartAddressOfRawData) + (_tls_used.EndAddressOfRawData - _tls_used.StartAddressOfRawData) +
_tls_used.SizeOfZeroFill _tls_used.SizeOfZeroFill
) + 15 & 0xFFFFFFF0); // Round up to nearest 0x10 ) + 15 & 0xFFFFFFF0; // Round up to nearest 0x10
*_tls_used.AddressOfIndex = -1 * XapiTlsSize/4; *_tls_used.AddressOfIndex = XapiTlsSize / (-4);
// Launch program as a thread // Launch program as a thread
thread = CreateThread(NULL, 0, mainXapiStartup, NULL, 0, NULL); thread = CreateThread(NULL, 0, mainXapiStartup, NULL, 0, NULL);

View file

@ -11,7 +11,7 @@ HEADERS="
Std.hpp Std.hpp
XDK/Win32.h XDK/Win32.h
XDK/D3D.h XDK/D3D.h
MUSASHI/MMatrix.hpp Smilebit/MMatrix.hpp
JSRF/Core.hpp JSRF/Core.hpp
JSRF/GameData.hpp JSRF/GameData.hpp
" "

View file

@ -5,12 +5,12 @@ JSRF/Jet2.obj,true,0x0006F9E0-0x0006FA6F,,,0x00187710-0x00187724,,,,,,,0x001E620
ADX (need to decompose),false,0x0013A570-0x0014555F,?,?,?,?,,,,,,?,?,?, ADX (need to decompose),false,0x0013A570-0x0014555F,?,?,?,?,,,,,,?,?,?,
Xapi (need to decompose),false,0x00145560-0x0014B79F,?,?,?,?,,,,,,?,?,?, Xapi (need to decompose),false,0x00145560-0x0014B79F,?,?,?,?,,,,,,?,?,?,
XDK/Xapi/xapi0.obj,true,0x00147FB4-0x0014807C,,,,,,,,,,,,, XDK/Xapi/xapi0.obj,true,0x00147FB4-0x0014807C,,,,,,,,,,,,,
Smilebit MUSASHI libs (need to decompose),false,0x0014B7A0-0x0017BF3F,?,?,?,?,,,,,,?,?,?-0x0022ED2B, Smilebit libs (need to decompose),false,0x0014B7A0-0x0017BF3F,?,?,?,?,,,,,,?,?,?-0x0022ED2B,
C runtime (need to decompose),false,0x0017BF40-0x00182B80,?,?,?,,,,,?,?,0x0022ED2C-?,?,?, C runtime (need to decompose),false,0x0017BF40-0x00182B80,?,?,?,,,,,?,?,0x0022ED2C-?,?,?,
Unknown MS math lib,false,0x00182B81-0x0018694F,?,?,?,,,,,?,?,?,?,?, Unknown MS math lib,false,0x00182B81-0x0018694F,?,?,?,,,,,?,?,?,?,?,
Another (tiny) Smilebit math lib,false,0x00186950-0x00186B7F,?,?,?,,,,,?,?,?,?,?, Another (tiny) Smilebit math lib,false,0x00186950-0x00186B7F,?,?,?,,,,,?,?,?,?,?,
Direct3D8 (need to decompose),false,,?,,0x0018CB40-0x0019E334,,,,,?,?,?,?,?, Direct3D8 (need to decompose),false,,?,,0x0018CB40-0x0019E334,,,,,?,?,?,?,?,
DirectSound8 (need to decompose),false,,?,?,,,0x0019E340-0x001BA89B,,,,?,?,?,?,0x0027E080-0x00284E17 DirectSound8 (need to decompose),false,,?,?,,,0x0019E340-0x001BA89B,,,,?,?,?,?,0x0027E080-0x00284E17
MUSASHI/MMatrix.obj,false,,?,,,,0x001BA8A0-0x001BBAAF,,,,,?,?,0x00264BD8-0x00264C13, Smilebit/MMatrix.obj,false,,?,,,,0x001BA8A0-0x001BBAAF,,,,,?,?,0x00264BD8-0x00264C13,
Xgraphics (need to decompose),false,,?,,,,,0x001BBAC0-0x001BC7BB,,,,?,?,, Xgraphics (need to decompose),false,,?,,,,,0x001BBAC0-0x001BC7BB,,,,?,?,,
XDK Peripherals (need to decompose),false,,?,,,,,,0x001BC7C0-0x001C3F57,,,?,?,, XDK Peripherals (need to decompose),false,,?,,,,,,0x001BC7C0-0x001C3F57,,,?,?,,

1 Object Delink? .text .text$yc .text$yd .text$x D3D DSOUND MMATRIX XGRPH XPP .rdata .rdata$x .data$CRT .data DOLBY
5 ADX (need to decompose) false 0x0013A570-0x0014555F ? ? ? ? ? ? ?
6 Xapi (need to decompose) false 0x00145560-0x0014B79F ? ? ? ? ? ? ?
7 XDK/Xapi/xapi0.obj true 0x00147FB4-0x0014807C
8 Smilebit MUSASHI libs (need to decompose) Smilebit libs (need to decompose) false 0x0014B7A0-0x0017BF3F ? ? ? ? ? ? ?-0x0022ED2B
9 C runtime (need to decompose) false 0x0017BF40-0x00182B80 ? ? ? ? ? 0x0022ED2C-? ? ?
10 Unknown MS math lib false 0x00182B81-0x0018694F ? ? ? ? ? ? ? ?
11 Another (tiny) Smilebit math lib false 0x00186950-0x00186B7F ? ? ? ? ? ? ? ?
12 Direct3D8 (need to decompose) false ? 0x0018CB40-0x0019E334 ? ? ? ? ?
13 DirectSound8 (need to decompose) false ? ? 0x0019E340-0x001BA89B ? ? ? ? 0x0027E080-0x00284E17
14 MUSASHI/MMatrix.obj Smilebit/MMatrix.obj false ? 0x001BA8A0-0x001BBAAF ? ? 0x00264BD8-0x00264C13
15 Xgraphics (need to decompose) false ? 0x001BBAC0-0x001BC7BB ? ?
16 XDK Peripherals (need to decompose) false ? 0x001BC7C0-0x001C3F57 ? ?

View file

@ -3,8 +3,8 @@ A matching decompilation of the Xbox game Jet Set Radio Future.
## Progress ## Progress
- Delinking progress: 1.03% (26559 out of 2574172 bytes in XBE address space) - Delinking progress: 1.03% (26559 out of 2574172 bytes in XBE address space)
- Decompilation progress: 19.6% (33 out of the 168 functions delinked so far) - Decompilation progress: 18.5% (31 out of the 168 functions delinked so far)
- **Estimated total progress: 0.20%** (previous two multiplied together) - **Estimated total progress: 0.19%** (previous two multiplied together)
## Roadmap ## Roadmap
The approach of this decompilation is to: The approach of this decompilation is to: