Compare commits

...

12 Commits

Author SHA1 Message Date
Guus Waals e4325de092 Fix spacing 2025-05-27 00:19:30 +08:00
Guus Waals dfe339bcd3 Simplify tool 2025-05-27 00:18:17 +08:00
Guus Waals cc7964f03e Updated 2025-05-27 00:12:40 +08:00
Guus Waals fd90916a1f Test script 2025-05-27 00:06:51 +08:00
Guus Waals 54476f89f0 CLI and list file support 2025-05-27 00:06:41 +08:00
Guus Waals 5223f1c7c1 Add CLI11 2025-05-27 00:04:32 +08:00
Guus Waals 468866b833 New tool version 2025-05-26 23:56:11 +08:00
Guus Waals 86fb5c8973 Parser tool draft 2025-05-26 23:50:57 +08:00
Guus Waals 1b2694d2e4 Tool wip 2025-05-26 23:46:44 +08:00
Guus Waals 376c86051a WIP Tooling 2025-05-26 23:21:16 +08:00
Guus Waals cf51259899 Cleanup & WIP tooling 2025-05-26 23:21:07 +08:00
Guus Waals 9e52c0147d Cleanup and move deps 2025-05-26 22:41:27 +08:00
423 changed files with 361788 additions and 3427 deletions

6
.gitmodules vendored
View File

@ -1,3 +1,9 @@
[submodule "game_re/third_party/spdlog"]
path = game_re/third_party/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "tooling2/third_party/tree-sitter"]
path = tooling2/third_party/tree-sitter
url = https://github.com/guusw/tree-sitter.git
[submodule "tooling2/third_party/tree-sitter-cpp"]
path = tooling2/third_party/tree-sitter-cpp
url = https://github.com/guusw/tree-sitter-cpp.git

View File

@ -1,8 +1,17 @@
cmake_minimum_required(VERSION 3.26.4)
project(reman3)
# Build for 32-bit compatibility, until code is binary compatible with 64-bit
option(R3_32BIT "Build for 32-bit compatibility" ON)
if(R3_32BIT)
add_compile_options(-m32)
add_link_options(-m32)
endif()
set(GAME_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/game)
add_subdirectory(third_party)
add_subdirectory(game_re)
# Use highest possible C standard

3
game_re/.gitignore vendored
View File

@ -2,4 +2,5 @@ gh_auto/*
gh_ref/*
*.bak
gh_cmake_timestamp
functions.dat
functions.dat
*.zip

View File

@ -1,9 +1,3 @@
# Build for 32-bit compatibility
add_compile_options(-m32)
add_link_options(-m32)
add_subdirectory(third_party/spdlog)
add_executable(game_re
r3/main.cpp
r3/binders/static_mem.cxx
@ -11,24 +5,19 @@ add_executable(game_re
)
target_compile_features(game_re PUBLIC cxx_std_20)
target_include_directories(game_re PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(game_re PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/third_party/bink
set_target_properties(
game_re PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
if(WIN32)
target_link_directories(game_re PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/bink)
target_include_directories(game_re PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/bink)
target_link_libraries(game_re PRIVATE binkw32)
# Copy to output dir
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/binkw32.dll
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/third_party/bink/binkw32.dll ${CMAKE_CURRENT_BINARY_DIR}
if(WIN32 AND R3_32BIT)
target_link_libraries(game_re PRIVATE
binkw32
d3d8
dinput8
)
add_custom_target(copy_binkw32 ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/binkw32.dll)
add_dependencies(game_re copy_binkw32)
endif()
target_compile_definitions(game_re PRIVATE
@ -40,15 +29,6 @@ target_compile_definitions(game_re PRIVATE
R3_DATA_SEGMENT_FILE=\"${R3_DATA_SEGMENT_FILE}\"
)
if(WIN32)
target_link_directories(game_re PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mssdk/lib)
target_include_directories(game_re SYSTEM AFTER PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mssdk/include)
target_link_libraries(game_re PRIVATE
d3d8
dinput8
)
endif()
target_compile_definitions(game_re PRIVATE
_CRT_SECURE_NO_WARNINGS=1
_CRT_NONSTDC_NO_WARNINGS=1)
@ -79,6 +59,6 @@ set_property(
PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gh_cmake_timestamp
)
target_precompile_headers(game_re PRIVATE
target_precompile_headers(game_re PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/r3/binders/auto_pch.cxx>"
)

View File

@ -1 +0,0 @@
gh_fix

View File

@ -1,28 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
// 0043e1d0
/* Allocate error manager system numbers */
byte Erm_fn_ucInitErrMsg(void)
{
byte RVar1;
tdstLastErrorInfo *pdVar2;
int iVar2;
RVar1 = g_ucErmNbOfModule;
if (g_ucErmNbOfModule == 0) {
for (size_t i = 0; i < std::size(g_stErmTheLastErrorInfo); i++) {
g_stErmTheLastErrorInfo[i].lastErr = 0;
g_stErmTheLastErrorInfo[i].ulChannelId = 0;
}
}
g_ucErmNbOfModule = g_ucErmNbOfModule + 1;
return RVar1;
}
}

View File

@ -1,53 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <spdlog/spdlog.h>
extern "C" {
void r3_noop(void *p_cTxt1, void *p_cTxt2); // 00401100 // r3_noop
tdstLastErrorInfo *Erm_fn_p_stFindstMyLastErrorInfo(
ulong ulChannelId); // 0043e2b0 // Erm_fn_p_stFindstMyLastErrorInfo
// 0043e410
/* Check CpaError.h */
void Erm_fn_v_UpdateLastError(ushort uwStartOfWarningsId, byte ucModuleId,
ulong ulChannelId, ushort uwErrNum,
long lDebugData, uchar ucOpenInfoWindow,
uchar ucStopForDebug, char *szPersonalMsg)
{
tdstLastErrorInfo *ptVar2;
ptVar2 = Erm_fn_p_stFindstMyLastErrorInfo(ulChannelId);
if (ptVar2 == (tdstLastErrorInfo *)0x0) {
throw std::runtime_error(
fmt::format("{} {}", s_Error_in_the_Erm__005bd374,
s_There_is_no_more_Channel_error_t_005bd388));
}
if (ptVar2->lastErr != 0) {
throw std::runtime_error(
fmt::format("{}", s_Strange__The_last_error_was_neve_005bd348));
}
ptVar2->lastErr = uwErrNum;
ptVar2->ucLastFailedModuleId = ucModuleId;
ptVar2->ulChannelId = ulChannelId;
if (uwErrNum < uwStartOfWarningsId) {
if (szPersonalMsg == (char *)0x0) {
throw std::runtime_error(fmt::format(
"Unkown fatal error ({}, module: {})", uwErrNum, ucModuleId));
} else {
throw std::runtime_error(
fmt::format("Unkown fatal error ({}, module: {}, {})", uwErrNum,
ucModuleId, szPersonalMsg));
}
}
if (szPersonalMsg == (char *)0x0) {
return;
} else {
SPDLOG_WARN("Erm_Warn: {}, module: {}, {}", uwErrNum, ucModuleId,
szPersonalMsg);
}
}
}

View File

@ -1,26 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
// 0043ff60
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
void FUN_0043ff60(float param_1,float param_2,float param_3)
{
longlong lVar1;
longlong lVar2;
longlong lVar3;
lVar1 = r3_ftol(param_1 * 255.0);
lVar2 = r3_ftol(param_2 * 255.0);
lVar3 = r3_ftol(param_3 * 255.0);
DAT_007a2c14 = ((int)lVar1 << 8 | (uint)lVar2) << 8 | (uint)lVar3;
return;
}
}

View File

@ -1,41 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
undefined4* FUN_0046ecc0(undefined2 param_1, undefined2 param_2); // 0046ecc0 // FUN_0046ecc0
// 0046f240
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
undefined4 FUN_0046f240(short param_1,short param_2,undefined4 *param_3)
{
uint uVar1;
undefined4 *puVar2;
uint uVar3;
int iVar4;
DAT_005e6b04 = 1;
do {
} while (DAT_005e6b00 != 0);
uVar1 = (uint)param_2;
uVar3 = uVar1 & 0x8000000f;
if ((int)uVar3 < 0) {
uVar3 = (uVar3 - 1 | 0xfffffff0) + 1;
}
puVar2 = (undefined4 *)FUN_0046ecc0((int)(uVar1 + ((int)uVar1 >> 0x1f & 0xfU)) >> 4,uVar3);
puVar2[0x19] = 0xffffffff;
puVar2[0x18] = 0;
for (iVar4 = 0x1c; iVar4 != 0; iVar4 = iVar4 + -1) {
*param_3 = *puVar2;
puVar2 = puVar2 + 1;
param_3 = param_3 + 1;
}
DAT_005e6b04 = 0;
return 1;
}
}

View File

@ -1,30 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
undefined FUN_0047c340(dword* param_1, dword* param_2, undefined4 param_3); // 0047c340 // FUN_0047c340
undefined FUN_0046f240(short param_1, short param_2, undefined4 * param_3); // 0046f240 // FUN_0046f240
undefined FUN_0046f060(short param_1, undefined4 * param_2); // 0046f060 // FUN_0046f060
// 0047c150
void FUN_0047c150(short param_1,short param_2,int param_3)
{
int iVar1;
dword local_d0 [24];
dword local_70 [28];
iVar1 = FUN_0046f060(param_1,local_d0);
if ((iVar1 != 0) && (iVar1 = FUN_0046f240(param_1,param_2,local_70), iVar1 != 0)) {
if (param_3 != 0) {
DAT_005f5e24 = param_3;
}
FUN_0047c340(local_d0,local_70,DAT_005f5e24);
}
return;
}
}

View File

@ -1,16 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <bink.h>
extern "C" {
// 00441e40
void binkInit(void) {
BinkSetSoundSystem(&BinkOpenDirectSound, 0);
BinkSetSoundOnOff(0, 0);
BinkSetIOSize(0x80000000);
return;
}
}

View File

@ -1,15 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
// 00401410
HWND getHWND(void)
{
return g_gameHWND;
}

View File

@ -1,13 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00445580
// r3_checkCmdlineLevel
extern "C" void r3_checkCmdlineLevel(void) {
// NOOP
}

View File

@ -1,24 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
// 0045d2e0
void r3_initUnusedSM(void)
{
WORD_007d9e68 = 1;
/* 0x53 */
sz_S[0] = s_S_005bf008[0];
sz_S[1] = s_S_005bf008[1];
WORD_007d9e6c = 2;
/* 0x4d */
sz_M[0] = s_M_005bf004[0];
sz_M[1] = s_M_005bf004[1];
return;
}
}

View File

@ -1,425 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <r3/config/static.hpp>
extern "C" {
undefined FUN_00470db0(void); // 00470db0 // FUN_00470db0
undefined r3_checkDisc(void); // 004464f0 // r3_checkDisc
undefined FUN_00503710(void); // 00503710 // FUN_00503710
undefined r3_initAllModules(void); // 00401000 // r3_initAllModules
undefined FUN_00472150(void); // 00472150 // FUN_00472150
undefined r3_wait_for_dvd(char *param_1, char *param_2,
undefined4 param_3); // 0043e540 // r3_wait_for_dvd
undefined FUN_004725a0(void); // 004725a0 // FUN_004725a0
int r3_get_gli_width1(void); // 0047baf0 // r3_get_gli_width1
undefined gfx_init2(void); // 00470be0 // gfx_init2
void g_setInitVar0(void); // 00401310 // g_setInitVar0
int r3_get_gli_height1(void); // 0047bb00 // r3_get_gli_height1
undefined FUN_004010b0(void); // 004010b0 // FUN_004010b0
undefined FUN_00401320(void); // 00401320 // FUN_00401320
void r3_noop(void *p_cTxt1, void *p_cTxt2); // 00401100 // r3_noop
undefined r3_initEngine(void); // 00401220 // r3_initEngine
undefined FUN_005038e0(void); // 005038e0 // FUN_005038e0
undefined FUN_004fb300(void); // 004fb300 // FUN_004fb300
undefined spawnThread(void); // 004477d0 // spawnThread
undefined
r3_setupWindow(HINSTANCE hInstance, undefined4 param_2,
undefined4 maximizeWindow); // 00402140 // r3_setupWindow
// 00401630
int r3_main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR *cmdline,
int showCmd)
{
undefined4 uVar1;
undefined2 uVar3;
LPSTR pCVar3;
char *pcVar4;
FILE *pFVar5;
LONG LVar6;
HMODULE hLibModule;
DWORD DVar7;
HANDLE hTargetProcessHandle;
HANDLE hSourceHandle;
HANDLE hSourceProcessHandle;
LPSTR *ppCVar8;
uint32_t uVar9;
HWND hWnd;
int iVar10;
int iVar11;
int iVar12;
int iVar13;
uint uVar14;
void *unaff_ESI;
undefined4 *puVar15;
void *unaff_EDI;
undefined4 *puVar16;
char *pcVar17;
undefined4 uStack_83c;
HKEY pHStack_838;
HANDLE pvStack_834;
UINT UStack_830;
BYTE aBStack_82c[4];
DWORD DStack_828;
DWORD DStack_824;
tagRECT tStack_820;
char acStack_810[260];
CHAR languageStr[256];
CHAR pathToUbi_ini[260];
char acStack_508[260];
CHAR windowsDir[260];
char acStack_300[256];
char acStack_200[256];
char acStack_100[256];
BOOL BVar18;
char cVar1;
undefined4 chars;
DWORD dwOptions;
tagRECT *lpRect;
HANDLE *lpTargetHandle;
undefined2 uVar2;
undefined4 uVar22;
pCVar3 = GetCommandLineA();
R3Config &gameConfig = getDefaultConfig();
// Store and change to game directory
chdir(gameConfig.gameRootDir.c_str());
strcpy(r3_main_data_005d28b6.gameDataDir, gameConfig.gameRootDir.c_str());
strcpy(languageStr, gameConfig.language.c_str());
sprintf(g_mutexName_Rayman3, s_percents, lpAppName_005b68f0);
sprintf(g_windowTitle, s_percents, s_windowTitle);
/* Setup localized quiting/restoring strings */
iVar13 = strcmpi(languageStr, s_French_005b6828);
if (iVar13 == 0) {
sprintf(s_windowTitleRestoring, s_Restauration_fmt, s_windowTitle);
chars = s_QUITTER + Field<4, 4>();
puVar15 = (undefined4 *)s_ou_appuyez_sur_Echap_pour_quitte_005b67d0;
puVar16 = (undefined4 *)s_quitting1;
for (iVar13 = 0xb; uVar22 = s_QUITTER + Field<4, 4>(), iVar13 != 0;
iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
s_wndStrQuiting[0] = s_QUITTER[0];
s_wndStrQuiting[1] = s_QUITTER[1];
s_wndStrQuiting[2] = s_QUITTER[2];
s_wndStrQuiting[3] = s_QUITTER[3];
/* Wrong decompilation? */
s_QUITTER[4] = (char)chars;
s_QUITTER[5] = SUB41(chars, 1);
s_QUITTER[6] = SUB41(chars, 2);
s_QUITTER[7] = SUB41(chars, 3);
s_wndStrQuiting[4] = s_QUITTER[4];
s_wndStrQuiting[5] = s_QUITTER[5];
s_wndStrQuiting[6] = s_QUITTER[6];
s_wndStrQuiting[7] = s_QUITTER[7];
s_QUITTER + Field<4, 4>() = uVar22;
sprintf(lpString_0077d2c0, s__s___Pause_005b67c4, s_windowTitle);
puVar15 = (undefined4 *)s_Restauration;
puVar16 = (undefined4 *)s_wndStrRestoring;
for (iVar13 = 7; iVar13 != 0; iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
} else {
iVar13 = strcmpi(languageStr, s_Spanish_005b67a0);
if (iVar13 == 0) {
sprintf(s_windowTitleRestoring, s__s___Restablecer_datos____005b6784,
s_windowTitle);
uVar2 = s_SALIR_005b675c + Field<4, 2>();
puVar15 = (undefined4 *)s_Pulsa_ESC_para_salir_Rayman_3__005b6764;
puVar16 = (undefined4 *)s_quitting1;
for (iVar13 = 7; chars = s_SALIR_005b675c + Field<0, 4>(), iVar13 != 0;
iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
*(undefined2 *)puVar16 = *(undefined2 *)puVar15;
*(undefined *)((int)puVar16 + 2) = *(undefined *)((int)puVar15 + 2);
uVar3 = s_SALIR_005b675c + Field<4, 2>();
uVar22 = s_SALIR_005b675c + Field<0, 4>();
s_SALIR_005b675c[0] = (char)chars;
s_SALIR_005b675c[1] = SUB41(chars, 1);
s_SALIR_005b675c[2] = SUB41(chars, 2);
s_SALIR_005b675c[3] = SUB41(chars, 3);
s_wndStrQuiting[0] = s_SALIR_005b675c[0];
s_wndStrQuiting[1] = s_SALIR_005b675c[1];
s_wndStrQuiting[2] = s_SALIR_005b675c[2];
s_wndStrQuiting[3] = s_SALIR_005b675c[3];
s_SALIR_005b675c[4] = (char)uVar2;
s_SALIR_005b675c[5] = SUB21(uVar2, 1);
s_wndStrQuiting[4] = s_SALIR_005b675c[4];
s_wndStrQuiting[5] = s_SALIR_005b675c[5];
s_SALIR_005b675c + Field<0, 4>() = uVar22;
s_SALIR_005b675c + Field<4, 2>() = uVar3;
sprintf(lpString_0077d2c0, s__s___Rotura_005b6750, s_windowTitle);
puVar15 = (undefined4 *)s_Restablecer_datos____005b6738;
puVar16 = (undefined4 *)s_wndStrRestoring;
for (iVar13 = 5; iVar13 != 0; iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
*(undefined *)puVar16 = *(undefined *)puVar15;
} else {
iVar13 = strcmpi(languageStr, s_Italian_005b6730);
if (iVar13 == 0) {
sprintf(s_windowTitleRestoring, s__s___Ripristino_dati____005b6718,
s_windowTitle);
uVar2 = s_USCIRE_005b66ec + Field<4, 2>();
puVar15 = (undefined4 *)s_Premi_ESC_per_uscire_da_Rayman_3_005b66f4;
puVar16 = (undefined4 *)s_quitting1;
for (iVar13 = 8; cVar1 = s_USCIRE_005b66ec[6], iVar13 != 0;
iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
s_wndStrQuiting[0] = s_USCIRE_005b66ec[0];
s_wndStrQuiting[1] = s_USCIRE_005b66ec[1];
s_wndStrQuiting[2] = s_USCIRE_005b66ec[2];
s_wndStrQuiting[3] = s_USCIRE_005b66ec[3];
*(undefined2 *)puVar16 = *(undefined2 *)puVar15;
s_wndStrQuiting + Field<4, 3>() = CONCAT12(cVar1, uVar2);
sprintf(lpString_0077d2c0, s__s___Pausa_005b66e0, s_windowTitle);
s_wndStrRestoring[0] = s_Ripristino_dati____005b66cc[0];
s_wndStrRestoring[1] = s_Ripristino_dati____005b66cc[1];
s_wndStrRestoring[2] = s_Ripristino_dati____005b66cc[2];
s_wndStrRestoring[3] = s_Ripristino_dati____005b66cc[3];
s_wndStrRestoring[4] = s_Ripristino_dati____005b66cc[4];
s_wndStrRestoring[5] = s_Ripristino_dati____005b66cc[5];
s_wndStrRestoring[6] = s_Ripristino_dati____005b66cc[6];
s_wndStrRestoring[7] = s_Ripristino_dati____005b66cc[7];
s_wndStrRestoring[8] = s_Ripristino_dati____005b66cc[8];
s_wndStrRestoring[9] = s_Ripristino_dati____005b66cc[9];
s_wndStrRestoring[10] = s_Ripristino_dati____005b66cc[10];
s_wndStrRestoring[0xb] = s_Ripristino_dati____005b66cc[0xb];
s_wndStrRestoring + Field<12, 4>() =
s_Ripristino_dati____005b66cc + Field<12, 4>();
s_wndStrRestoring + Field<16, 2>() =
s_Ripristino_dati____005b66cc + Field<16, 2>();
s_wndStrRestoring[0x12] = s_Ripristino_dati____005b66cc[0x12];
} else {
iVar13 = strcmpi(languageStr, s_German_005b66c4);
if (iVar13 == 0) {
sprintf(s_windowTitleRestoring, s__s___Daten_Reparatur____005b66ac,
s_windowTitle);
chars = s_BEENDIGEN_005b6678 + Field<0, 4>();
puVar15 = (undefined4 *)&CHAR_E_005b6684;
puVar16 = (undefined4 *)s_quitting1;
for (iVar13 = 9; uVar2 = s_BEENDIGEN_005b6678 + Field<8, 2>(),
uVar22 = s_BEENDIGEN_005b6678 + Field<4, 4>(), iVar13 != 0;
iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
*(undefined2 *)puVar16 = *(undefined2 *)puVar15;
uVar1 = s_BEENDIGEN_005b6678 + Field<0, 4>();
s_BEENDIGEN_005b6678[0] = (char)chars;
s_BEENDIGEN_005b6678[1] = SUB41(chars, 1);
s_BEENDIGEN_005b6678[2] = SUB41(chars, 2);
s_BEENDIGEN_005b6678[3] = SUB41(chars, 3);
s_wndStrQuiting[0] = s_BEENDIGEN_005b6678[0];
s_wndStrQuiting[1] = s_BEENDIGEN_005b6678[1];
s_wndStrQuiting[2] = s_BEENDIGEN_005b6678[2];
s_wndStrQuiting[3] = s_BEENDIGEN_005b6678[3];
s_BEENDIGEN_005b6678 + Field<0, 4>() = uVar1;
*(undefined *)((int)puVar16 + 2) = *(undefined *)((int)puVar15 + 2);
uVar3 = s_BEENDIGEN_005b6678 + Field<8, 2>();
chars = s_BEENDIGEN_005b6678 + Field<4, 4>();
s_BEENDIGEN_005b6678[4] = (char)uVar22;
s_BEENDIGEN_005b6678[5] = SUB41(uVar22, 1);
s_BEENDIGEN_005b6678[6] = SUB41(uVar22, 2);
s_BEENDIGEN_005b6678[7] = SUB41(uVar22, 3);
s_wndStrQuiting[4] = s_BEENDIGEN_005b6678[4];
s_wndStrQuiting[5] = s_BEENDIGEN_005b6678[5];
s_wndStrQuiting[6] = s_BEENDIGEN_005b6678[6];
s_wndStrQuiting[7] = s_BEENDIGEN_005b6678[7];
s_BEENDIGEN_005b6678[8] = (char)uVar2;
s_BEENDIGEN_005b6678[9] = SUB21(uVar2, 1);
s_wndStrQuiting[8] = s_BEENDIGEN_005b6678[8];
s_wndStrQuiting[9] = s_BEENDIGEN_005b6678[9];
s_BEENDIGEN_005b6678 + Field<4, 4>() = chars;
s_BEENDIGEN_005b6678 + Field<8, 2>() = uVar3;
sprintf(lpString_0077d2c0, s__s___Pause_005b67c4, s_windowTitle);
s_wndStrRestoring[0] = s_Daten_Reparatur____005b6664[0];
s_wndStrRestoring[1] = s_Daten_Reparatur____005b6664[1];
s_wndStrRestoring[2] = s_Daten_Reparatur____005b6664[2];
s_wndStrRestoring[3] = s_Daten_Reparatur____005b6664[3];
s_wndStrRestoring[4] = s_Daten_Reparatur____005b6664[4];
s_wndStrRestoring[5] = s_Daten_Reparatur____005b6664[5];
s_wndStrRestoring[6] = s_Daten_Reparatur____005b6664[6];
s_wndStrRestoring[7] = s_Daten_Reparatur____005b6664[7];
s_wndStrRestoring[8] = s_Daten_Reparatur____005b6664[8];
s_wndStrRestoring[9] = s_Daten_Reparatur____005b6664[9];
s_wndStrRestoring[10] = s_Daten_Reparatur____005b6664[10];
s_wndStrRestoring[0xb] = s_Daten_Reparatur____005b6664[0xb];
s_wndStrRestoring[0xc] = s_Daten_Reparatur____005b6664[0xc];
s_wndStrRestoring[0xd] = s_Daten_Reparatur____005b6664[0xd];
s_wndStrRestoring[0xe] = s_Daten_Reparatur____005b6664[0xe];
s_wndStrRestoring[0xf] = s_Daten_Reparatur____005b6664[0xf];
s_wndStrRestoring[0x10] = s_Daten_Reparatur____005b6664[0x10];
s_wndStrRestoring[0x11] = s_Daten_Reparatur____005b6664[0x11];
s_wndStrRestoring[0x12] = s_Daten_Reparatur____005b6664[0x12];
} else {
sprintf(s_windowTitleRestoring, s__s___Restoring_data____005b664c,
s_windowTitle);
chars = s_QUIT + Field<0, 4>();
puVar15 = (undefined4 *)s_or_press_ESC_to_quit_Rayman_3__005b662c;
puVar16 = (undefined4 *)s_quitting1;
for (iVar13 = 7; cVar1 = s_QUIT[4], iVar13 != 0;
iVar13 = iVar13 + -1) {
*puVar16 = *puVar15;
puVar15 = puVar15 + 1;
puVar16 = puVar16 + 1;
}
*(undefined2 *)puVar16 = *(undefined2 *)puVar15;
*(undefined *)((int)puVar16 + 2) = *(undefined *)((int)puVar15 + 2);
uVar22 = s_QUIT + Field<0, 4>();
s_QUIT[0] = (char)chars;
s_QUIT[1] = SUB41(chars, 1);
s_QUIT[2] = SUB41(chars, 2);
s_QUIT[3] = SUB41(chars, 3);
s_wndStrQuiting[0] = s_QUIT[0];
s_wndStrQuiting[1] = s_QUIT[1];
s_wndStrQuiting[2] = s_QUIT[2];
s_wndStrQuiting[3] = s_QUIT[3];
s_wndStrQuiting[4] = cVar1;
s_QUIT + Field<0, 4>() = uVar22;
sprintf(lpString_0077d2c0, s__s___Pause_005b67c4, s_windowTitle);
s_wndStrRestoring[0] = s_Restoring_data_____005b6610[0];
s_wndStrRestoring[1] = s_Restoring_data_____005b6610[1];
s_wndStrRestoring[2] = s_Restoring_data_____005b6610[2];
s_wndStrRestoring[3] = s_Restoring_data_____005b6610[3];
s_wndStrRestoring[4] = s_Restoring_data_____005b6610[4];
s_wndStrRestoring[5] = s_Restoring_data_____005b6610[5];
s_wndStrRestoring[6] = s_Restoring_data_____005b6610[6];
s_wndStrRestoring[7] = s_Restoring_data_____005b6610[7];
s_wndStrRestoring[8] = s_Restoring_data_____005b6610[8];
s_wndStrRestoring[9] = s_Restoring_data_____005b6610[9];
s_wndStrRestoring[10] = s_Restoring_data_____005b6610[10];
s_wndStrRestoring[0xb] = s_Restoring_data_____005b6610[0xb];
s_wndStrRestoring + Field<12, 4>() =
s_Restoring_data_____005b6610 + Field<12, 4>();
s_wndStrRestoring + Field<16, 2>() =
s_Restoring_data_____005b6610 + Field<16, 2>();
s_wndStrRestoring[0x12] = s_Restoring_data_____005b6610[0x12];
}
}
}
}
/* Create draw semaphore
Initial count = 1
Maximum count = 1 */
g_drawSemaphore =
CreateSemaphoreA((LPSECURITY_ATTRIBUTES)0x0, 1, 1, s_DRAWSEM_005b6608);
if (hPrevInstance != (HINSTANCE)0x0) {
return -1;
}
/* Load DirectPlay probably unused */
// hLibModule = LoadLibraryA(s_dpnhpast_dll_005b65f8);
// if (hLibModule == (HMODULE)0x0) {
// iVar13 = strcmpi(languageStr, s_French_005b6828);
// if (iVar13 == 0) {
// MessageBoxA((HWND)0x0, lpText_005b6598, s_Erreur_Rayman_3_005b65e4,
// 0x10); return -1;
// }
// iVar13 = strcmpi(languageStr, s_Spanish_005b67a0);
// if (iVar13 == 0) {
// MessageBoxA((HWND)0x0, lpText_005b6540, s_Rayman_3_005b6588, 0x10);
// return -1;
// }
// iVar13 = strcmpi(languageStr, s_Italian_005b6730);
// if (iVar13 == 0) {
// MessageBoxA((HWND)0x0, lpText_005b64f0, s_Rayman_3_005b6588, 0x10);
// return -1;
// }
// iVar13 = strcmpi(languageStr, s_German_005b66c4);
// if (iVar13 != 0) {
// MessageBoxA((HWND)0x0, s_Check_your_version_of_DirectX__V_005b6430,
// s_Rayman_3_Error_005b68bc, 0x10);
// return -1;
// }
// MessageBoxA((HWND)0x0, lpText_005b6478, s_Rayman_3_005b6588, 0x10);
// return -1;
// }
// FreeLibrary(hLibModule);
/* For GLIMode
1 = maximize
0 = windowed */
g_runMaximized = (int)(acStack_200[0] != '0');
// r3_checkDisc();
dwOptions = 0;
BVar18 = 0;
lpTargetHandle = &pvStack_834;
DVar7 = 0x1f03ff;
g_hinstance = hInstance;
hTargetProcessHandle = GetCurrentProcess();
hSourceHandle = GetCurrentThread();
hSourceProcessHandle = GetCurrentProcess();
DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
lpTargetHandle, DVar7, BVar18, dwOptions);
g_mainThreadHandle = pvStack_834;
/* Copy cmdline */
strcpy(g_appCmdLine, GetCommandLineA());
// SetErrorMode(1);
r3_initAllModules();
iVar13 = r3_setupWindow(hInstance, showCmd, g_runMaximized);
if (iVar13 == 0) {
return -1;
}
g_setInitVar0();
FUN_00401320();
spawnThread();
gfx_init2();
lpRect = &tStack_820;
hWnd = GetDesktopWindow();
GetWindowRect(hWnd, lpRect);
BVar18 = 1;
iVar13 = r3_get_gli_height1();
iVar13 = iVar13 + 0x20;
iVar10 = r3_get_gli_width1();
iVar10 = iVar10 + 0xc;
iVar11 = r3_get_gli_height1();
iVar11 = (tStack_820.bottom - iVar11) / 2;
iVar12 = r3_get_gli_width1();
MoveWindow(g_gameHWND, (tStack_820.right - iVar12) / 2, iVar11, iVar10,
iVar13, BVar18);
FUN_004010b0();
SystemParametersInfoA(0x10, 0, &UStack_830, 0);
SystemParametersInfoA(0x11, 0, (PVOID)0x0, 0);
ShowCursor(0);
uStack_83c = 0;
SystemParametersInfoA(0x61, 1, &uStack_83c, 0);
g_engineRunning = 1;
r3_initEngine();
FUN_004725a0();
FUN_005038e0();
FUN_00503710();
FUN_004fb300();
FUN_00472150();
FUN_00470db0();
uStack_83c = 0;
SystemParametersInfoA(0x61, 0, &uStack_83c, 0);
ShowCursor(1);
SystemParametersInfoA(0x11, UStack_830, (PVOID)0x0, 0);
CloseHandle(pvStack_834);
return 0;
}
}

View File

@ -1,24 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
void Erm_fn_v_UpdateLastError(ushort uwStartOfWarningsId, byte ucModuleId, ulong ulChannelId, ushort uwErrNum, long lDebugData, uchar ucOpenInfoWindow, uchar ucStopForDebug, char * szPersonalMsg); // 0043e410 // Erm_fn_v_UpdateLastError
byte Erm_fn_ucInitErrMsg(void); // 0043e1d0 // Erm_fn_ucInitErrMsg
// 00504ef0
void r3_module10_init(void)
{
/* 0x104ef0 95 IPT_fn_vFirstInitInput */
if (g_errMod10 == 0xff) {
g_errMod10 = Erm_fn_ucInitErrMsg();
return;
}
Erm_fn_v_UpdateLastError(3,g_errMod0,0,4,-1,0xff,0xff,(char *)0x0);
return;
}
}

View File

@ -1,27 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
// 00401100
/* Sometimes: Erm_fn_v_PrintErrMsg
Also used as noop function */
void r3_noop(void *p_cTxt1,void *p_cTxt2)
{
/* 0x1100 145 SND_PrintUsedStaticMemory
0x1100 205 SND_fn_vChangeVolumeSound
0x1100 210 SND_fn_vFadeOut
0x1100 215 SND_fn_vInitStereoSound
0x1100 230 SND_fn_vSetDopplerFactorSound
0x1100 231 SND_fn_vSetFadeOutTicks
0x1100 233 SND_fn_vSetMusicFadeOut
0x1100 237 SND_fn_vSetReverseStereoSound
0x1100 239 SND_fn_vSetStereoSound */
return;
}

View File

@ -1,65 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <r3/config/static.hpp>
extern "C" {
undefined r3_config_setIdentifier(
const char *param_1); // 00470570 // r3_config_setIdentifier
void r3_config_setTexturesMem(
const char *param_1); // 00470f30 // r3_config_setTexturesMem
void r3_noop(void *p_cTxt1, void *p_cTxt2); // 00401100 // r3_noop
undefined
r3_read_game_config_udp_port(void); // 00446040 // r3_read_game_config_udp_port
undefined
r3_config_setGLIMode(const char *param_1); // 004704e0 // r3_config_setGLIMode
undefined r3_set_GameDataBinPath(
const char *param_1); // 0055a8d0 // r3_set_GameDataBinPath
undefined r3_read_game_config_modem_quality(
void); // 00445fc0 // r3_read_game_config_modem_quality
// 004460c0
void r3_read_gli_config(void) {
R3Config &config = getDefaultConfig();
r3_config_setGLIMode(config.gfxGliMode.c_str());
r3_config_setIdentifier(config.gfxIdentifier.c_str());
r3_config_setTexturesMem(config.gfxTexturesMem.c_str());
g_GLI_adapter = config.gfxAdapter;
r3_config_setIdentifier(config.gfxIdentifier.c_str());
g_config_tex_compressed = config.gfxTexturesCompressed;
g_GLI_tnl = config.gfxTnl;
g_GLI_trilinear = config.gfxTrilinear;
r3_config_setTexturesMem(config.gfxTexturesMem.c_str());
g_config_unused0 = 0;
g_config_camera_hor_axis = config.cameraHorizontalAxis;
g_config_camera_ver_axis = config.cameraVerticalAxis;
r3_set_GameDataBinPath(config.gameDataBinPath.c_str());
// GetPrivateProfileStringA
// (sectionName,s_SingleProcessor_005be308,&lpDefault_005be318,stringBuffer,0x104,local_204
// );
// /* Set single processor mode */
// iVar4 = strcmpi(stringBuffer,(char *)&s_Yes);
// if (iVar4 == 0) {
// sectionName[4] = '\x01';
// sectionName[5] = '\0';
// sectionName[6] = '\0';
// sectionName[7] = '\0';
// sectionName[0] = -0x1a;
// sectionName[1] = 'c';
// sectionName[2] = 'D';
// sectionName[3] = '\0';
// sectionName + Field<0, 4>() = GetCurrentProcess();
// SetProcessAffinityMask((HANDLE)sectionName + Field<0, 4>(),sectionName +
// Field<4, 4>());
// }
// sectionName[4] = -0xe;
// sectionName[5] = 'c';
// sectionName[6] = 'D';
// sectionName[7] = '\0';
// r3_read_game_config_modem_quality();
// r3_read_game_config_udp_port();
return;
}
}

View File

@ -1,155 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
undefined4 get_one(void); // 00485bd0 // get_one
void set_unk(HWND wnd); // 0043e620 // set_unk
int r3_get_gli_width0(void); // 004012c0 // r3_get_gli_width0
int r3_get_gli_height0(void); // 004012d0 // r3_get_gli_height0
undefined4 FUN_0046ed70(char * param_1, short * param_2); // 0046ed70 // FUN_0046ed70
undefined FUN_0046f640(undefined param_1, short param_2, undefined4 * param_3); // 0046f640 // FUN_0046f640
void FUN_0047c150(short param_1, short param_2, int param_3); // 0047c150 // FUN_0047c150
long r3_windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // 004025e0 // r3_windowProc
int r3_get_gli_width1(void); // 0047baf0 // r3_get_gli_width1
void r3_load_splash_bitmap(HWND unused); // 00402450 // r3_load_splash_bitmap
int r3_get_gli_height1(void); // 0047bb00 // r3_get_gli_height1
undefined4 FUN_0046f0b0(short param_1, undefined4 * param_2, short * param_3); // 0046f0b0 // FUN_0046f0b0
void r3_set_window_wh(undefined4 param_1, undefined4 param_2); // 004012a0 // r3_set_window_wh
// 00402140
undefined4 r3_setupWindow(HINSTANCE hInstance,undefined4 param_2,int maximizeWindow)
{
ATOM AVar1;
int iVar2;
HWND hWnd;
HWND pHVar3;
bool bVar4;
char acStack_e0 [28];
int iStack_c4;
int iStack_c0;
undefined4 uStack_bc;
HWND pHStack_b8;
HWND pHStack_b4;
undefined4 uStack_b0;
undefined4 uStack_ac;
undefined4 auStack_80 [5];
undefined4 uStack_6c;
DWORD dwStyle;
int iVar5;
int iVar6;
undefined local_28 [28];
HBRUSH pHStack_c;
LPCSTR pCStack_8;
char *pcStack_4;
INT_0077d0a4 = 1;
/* WindowClassA (overlaps usage below) */
local_28 + Field<0, 4>() = 0x3003;
local_28 + Field<4, 4>() = r3_windowProc;
local_28 + Field<8, 4>() = 0;
local_28 + Field<12, 4>() = 0;
local_28 + Field<16, 4>() = hInstance;
local_28 + Field<20, 4>() = LoadIconA(hInstance,(LPCSTR)0x65);
local_28 + Field<24, 4>() = LoadCursorA((HINSTANCE)0x0,(LPCSTR)0x7f00);
pHStack_c = (HBRUSH)0x6;
pCStack_8 = (LPCSTR)0x0;
pcStack_4 = g_windowTitle;
AVar1 = RegisterClassA((WNDCLASSA *)local_28);
if (AVar1 != 0) {
bVar4 = maximizeWindow == 0;
if (bVar4) {
iVar5 = GetSystemMetrics(0x20);
iVar5 = iVar5 * 2 + 0x140;
iVar6 = GetSystemMetrics(0x21);
iVar2 = GetSystemMetrics(4);
iVar6 = iVar2 + 0xf0 + iVar6 * 2;
dwStyle = 0x90cf0000;
}
else {
iVar6 = 0xf0;
iVar5 = 0x140;
dwStyle = 0x91000000;
}
uStack_6c = 0x40221d;
hWnd = CreateWindowExA(0,g_windowTitle,g_windowTitle,dwStyle,(uint)bVar4,(uint)bVar4,iVar5,iVar6
,(HWND)0x0,(HMENU)0x0,hInstance,(LPVOID)0x0);
g_gameHWND1 = hWnd;
if (hWnd != (HWND)0x0) {
g_gameHWND = hWnd;
SetWindowTextA(hWnd,s_windowTitle);
if (maximizeWindow == 0) {
/* SW_NORMAL */
iVar5 = 1;
}
else {
/* SW_MAXIMIZE */
iVar5 = 3;
}
ShowWindow(hWnd,iVar5);
SetWindowPos(hWnd,(HWND)0x0,0,0,0,0,0x43);
EnableWindow(hWnd,1);
SetFocus(hWnd);
UpdateWindow(hWnd);
SetForegroundWindow(hWnd);
pHVar3 = GetFocus();
while (pHVar3 != hWnd) {
SetWindowPos(hWnd,(HWND)0x0,0,0,0,0,0x43);
EnableWindow(hWnd,1);
SetFocus(hWnd);
UpdateWindow(hWnd);
SetForegroundWindow(hWnd);
pHVar3 = GetFocus();
}
set_unk(hWnd);
r3_load_splash_bitmap(hWnd);
INT_0077d0a4 = 1;
iVar5 = get_one();
/* always taken */
if (iVar5 != 0) {
iVar5 = get_one();
/* never taken */
if (iVar5 == 0) {
/* WARNING: Subroutine does not return */
exit(-1);
}
iVar5 = r3_get_gli_height1();
iVar6 = r3_get_gli_width1();
r3_set_window_wh(iVar6,iVar5);
GetClientRect(g_gameHWND,(LPRECT)(local_28 + 0x18));
uStack_b0 = 1;
iStack_c4 = r3_get_gli_width0();
iStack_c0 = r3_get_gli_height0();
uStack_bc = 0x10;
pHStack_b8 = g_gameHWND;
pHStack_b4 = g_gameHWND;
uStack_ac = 10;
iVar5 = FUN_0046ed70(acStack_e0,(short *)&WORD_0077d4d4);
if (iVar5 != 0) {
local_28 + Field<0, 4>() = 0;
local_28 + Field<4, 4>() = (WNDPROC)0x0;
iVar5 = FUN_0046f0b0(WORD_0077d4d4,auStack_80,(short *)&WORD_0077d4d6);
if ((iVar5 != 0) &&
(iVar5 = FUN_0046f640((char)WORD_0077d4d4,WORD_0077d4d6,&DWORD_0077d4d8), iVar5 != 0))
{
if (DWORD_0077d4d8 != 0) {
FUN_0047c150(WORD_0077d4d4,WORD_0077d4d6,DWORD_0077d4d8);
}
return 1;
}
}
/* Failed */
return 0;
}
/* WARNING: Subroutine does not return */
exit(-1);
}
}
/* Failed */
return 0;
}
}

View File

@ -1,29 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
// 00442090
void r3_validateBinkVideoQuality(byte videoBpp, byte wantedVideoQuality)
{
byte bVar1;
bVar1 = wantedVideoQuality;
if (4 < wantedVideoQuality) {
bVar1 = 4;
}
g_bink_realVideoQuality = g_bink_wantedVideoQuality;
if ((g_bink_wantedVideoQuality <= bVar1) &&
(g_bink_realVideoQuality = 4, wantedVideoQuality < 5)) {
g_bink_realVideoQuality = wantedVideoQuality;
}
wantedVideoQuality = (uint)g_bink_realVideoQuality;
g_bink_videoBpp = videoBpp;
g_bink_wantedVideoQualityPlus1 = wantedVideoQuality + 1;
DAT_007a2e0c = -(uint)(wantedVideoQuality != 0) & 0x80000000;
return;
}
}

View File

@ -1,63 +0,0 @@
// AUTO-GENERATED FILE, MOVE TO 'gh_fix' FOLDER PREVENT OVERWRITING!!!!!
#include <r3/binders/auto.h>
#include <gh_global.h>
extern "C" {
undefined FUN_004013a0(void); // 004013a0 // FUN_004013a0
undefined FUN_00401320(void); // 00401320 // FUN_00401320
// 004025e0
long r3_windowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
long lVar1;
if (uMsg < WM_SETCURSOR + 1) {
if (uMsg == WM_SETCURSOR) {
if (((g_engineShouldRun != 0) && (g_engineRunning != 0)) && (g_runMaximized != 0)) {
FUN_00401320();
return 1;
}
}
else {
if (uMsg == WM_CLOSE) {
FUN_004013a0();
DAT_0077d0b8 = 1;
if (g_drawSemaphore != (HANDLE)0x0) {
CloseHandle(g_drawSemaphore);
}
g_drawSemaphore = (HANDLE)0x0;
PostQuitMessage(0);
return 0;
}
if (uMsg == WM_ACTIVATEAPP) {
g_engineShouldRun = wParam;
}
}
}
else {
if (uMsg != WM_NCHITTEST) {
if (uMsg != WM_SYSCOMMAND) goto LAB_004026ab;
/* handle SYSCOMMAND */
if (wParam < SC_MAXIMIZE + 1) {
if ((wParam != SC_MAXIMIZE) && ((wParam != SC_SIZE && (wParam != SC_MOVE))))
goto LAB_004026ab;
}
else if ((wParam != SC_KEYMENU) && (wParam != SC_MONITORPOWER)) goto LAB_004026ab;
}
/* WM_NCHITTEST
*/
if (g_runMaximized != 0) {
return 1;
}
}
LAB_004026ab:
/* WARNING: Could not recover jumptable at 0x004026b3. Too many branches */
/* WARNING: Treating indirect jump as call */
lVar1 = DefWindowProcA(hwnd,uMsg,wParam,lParam);
return lVar1;
}
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 004010b0
// FUN_004010b0
extern "C" undefined FUN_004010b0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_004010b0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 004011e0
// FUN_004011e0
extern "C" undefined FUN_004011e0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_004011e0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401320
// FUN_00401320
extern "C" undefined FUN_00401320(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_00401320");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0043e4f0
// FUN_0043e4f0
extern "C" undefined FUN_0043e4f0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_0043e4f0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00441d70
// FUN_00441d70
extern "C" undefined FUN_00441d70(undefined4 param_1, undefined4 param_2, undefined4 param_3, undefined4 param_4, undefined4 param_5) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_00441d70");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0046f060
// FUN_0046f060
extern "C" BOOL FUN_0046f060(short param_1, undefined4 * param_2) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_0046f060");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0046fe20
// FUN_0046fe20
extern "C" undefined FUN_0046fe20(undefined4 param_1, undefined4 param_2, undefined4 param_3) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_0046fe20");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00470db0
// FUN_00470db0
extern "C" undefined FUN_00470db0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_00470db0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00472150
// FUN_00472150
extern "C" undefined FUN_00472150(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_00472150");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 004725a0
// FUN_004725a0
extern "C" undefined FUN_004725a0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_004725a0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 004fb300
// FUN_004fb300
extern "C" undefined FUN_004fb300(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_004fb300");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00503710
// FUN_00503710
extern "C" undefined FUN_00503710(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_00503710");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 005038e0
// FUN_005038e0
extern "C" undefined FUN_005038e0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: FUN_005038e0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0047c340
// GLI_xAdjustCameraToViewport
extern "C" void GLI_xAdjustCameraToViewport(GLD_tdstDeviceAttributes_ * p_stDev, GLD_tdstViewportAttributes * p_stVpt, GLI_tdstCamera * camera) {
// TODO: Implement this function
throw GHStubException("Function not implemented: GLI_xAdjustCameraToViewport");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00505fe0
// IPT_fn_vReadInput
extern "C" void IPT_fn_vReadInput(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: IPT_fn_vReadInput");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401110
// fn_vChooseTheGoodInit
extern "C" undefined fn_vChooseTheGoodInit(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: fn_vChooseTheGoodInit");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401310
// g_setInitVar0
extern "C" void g_setInitVar0(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: g_setInitVar0");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00470be0
// gfx_init2
extern "C" undefined gfx_init2(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: gfx_init2");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 004464f0
// r3_checkDisc
extern "C" undefined r3_checkDisc(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_checkDisc");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401130
// r3_checkEngineTermination
extern "C" int r3_checkEngineTermination(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_checkEngineTermination");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401150
// r3_engine_init_phase_adv2_is_2_6_8
extern "C" undefined r3_engine_init_phase_adv2_is_2_6_8(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_engine_init_phase_adv2_is_2_6_8");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0047bb00
// r3_get_gli_height1
extern "C" int r3_get_gli_height1(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_get_gli_height1");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0047baf0
// r3_get_gli_width1
extern "C" int r3_get_gli_width1(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_get_gli_width1");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 0046fed0
// r3_gfxFrame?
extern "C" undefined r3_gfxFrame?(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_gfxFrame?");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401000
// r3_initAllModules
extern "C" undefined r3_initAllModules(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_initAllModules");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 004013a0
// r3_windowUnlockCursor
extern "C" undefined r3_windowUnlockCursor(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: r3_windowUnlockCursor");
}

View File

@ -1,14 +0,0 @@
// AUTO-GENERATED FILE!!!!
// This function has yet to be decompiled using 'Dump Current Function' in ghidra
// with possible manualy fixes
#include <r3/binders/auto.h>
#include <gh_global.h>
#include <stdexcept>
// 00401120
// thunk_FUN_00444a80
extern "C" undefined thunk_FUN_00444a80(void) {
// TODO: Implement this function
throw GHStubException("Function not implemented: thunk_FUN_00444a80");
}

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
Subproject commit bdd1dff3788ebfe520f48f9ad216c60da6dd8f00

View File

@ -1,2 +0,0 @@
.class
target/

View File

@ -1,52 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cparser</groupId>
<artifactId>cparser</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- JUnit for testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- Specify the custom test source directory -->
<testSourceDirectory>./src/test/java</testSourceDirectory>
<plugins>
<!-- Compiler Plugin to specify Java version -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- Surefire Plugin to run JUnit tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<includes>
<include>**/ParserTests.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,124 +0,0 @@
package cparser;
import java.util.List;
public class AST {
public static class Error {
public final Span span;
public final String message;
public Error(Span span, String message) {
this.span = span;
this.message = message;
}
}
public static class Span {
public final int startOffset;
public final int endOffset;
public Span(int startOffset, int endOffset) {
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public Span() {
this.startOffset = -1;
this.endOffset = -1;
}
public boolean isValid() {
return endOffset > startOffset;
}
}
public static class PreprocessorExpression {
public final Span span;
public PreprocessorExpression(Span span) {
this.span = span;
}
}
public static class Type {
// The entire type definition, e.g. "byte**"
public final Span span;
// the base type name, e.g. byte in "byte* (&value)[20]"
public final Span baseSpan;
public Type(Span span, Span baseSpan) {
this.span = span;
this.baseSpan = baseSpan;
}
}
public static class Identifier {
public final Span span;
public Identifier(Span span) {
this.span = span;
}
}
public static class ArgumentList {
public final List<Object> arguments;
public ArgumentList(List<Object> arguments) {
this.arguments = arguments;
}
}
private static class Expr {
public final Span span;
public Expr(Span span) {
this.span = span;
}
};
public static class VariableDeclaration {
public final String type;
public final String identifier;
public final boolean isPointer;
public final boolean isReference;
public final boolean isArray;
public final int arraySize;
public final boolean isFunction;
public final Span span;
public VariableDeclaration(String type, String identifier, boolean isPointer, boolean isReference,
boolean isArray, int arraySize, boolean isFunction, Span span) {
this.type = type;
this.identifier = identifier;
this.isPointer = isPointer;
this.isReference = isReference;
this.isArray = isArray;
this.arraySize = arraySize;
this.isFunction = isFunction;
this.span = span;
}
}
public static class FunctionDecl {
public final Identifier name;
public final Type returnValue;
public final ArgumentList args;
public FunctionDecl(Identifier name, Type returnValue, ArgumentList args) {
this.name = name;
this.returnValue = returnValue;
this.args = args;
}
}
public static class FunctionCall {
public final Identifier name;
public final ArgumentList args;
public FunctionCall(Identifier name, ArgumentList args) {
this.name = name;
this.args = args;
}
}
}

View File

@ -1,5 +0,0 @@
package cparser;
public interface Log {
public void log(String msg);
}

View File

@ -1,358 +0,0 @@
package cparser;
import java.util.*;
import cparser.Tokenizer.Token;
import cparser.Log;
import cparser.AST.VariableDeclaration;
public class Parser {
private Tokenizer.TokenSet tokenSet;
private Log log;
private Tokenizer.Token[] tokens;
private List<Object> statements = new ArrayList<>();
private List<VariableDeclaration> variableDeclarations = new ArrayList<>();
private List<AST.Span> commentStack = new ArrayList<>();
private List<AST.Error> errors = new ArrayList<>();
public Parser(Tokenizer.TokenSet tokenSet, Log log) {
this.tokenSet = tokenSet;
this.statements = new ArrayList<>();
this.tokens = tokenSet.getTokens();
}
void log(String msg) {
if (log != null) {
log.log(msg);
}
}
int index = 0;
public List<VariableDeclaration> getVariableDeclarations() {
return variableDeclarations;
}
private static class Result<T> {
public final T value;
public final AST.Span span;
public Result(T value, AST.Span span) {
this.value = value;
this.span = span;
}
public Result() {
this.value = null;
this.span = new AST.Span();
}
public boolean isValid() {
return span.isValid();
}
public static <T> Result<T> none() {
return new Result<T>();
}
public Result<Object> toGeneric() {
return new Result<Object>(value, span);
}
}
boolean applyResult(Result<?> result) {
if (result.span.isValid()) {
index = result.span.endOffset + 1;
if (result.value instanceof VariableDeclaration) {
variableDeclarations.add((VariableDeclaration) result.value);
}
return true;
}
return false;
}
private void addError(AST.Span span, String message) {
errors.add(new AST.Error(span, message));
}
private void addError(Tokenizer.Token token, String message) {
addError(token.getSpan(), message);
}
public void parse() {
for (index = 0; index < tokens.length;) {
Tokenizer.Token token = tokens[index];
if (token.type == Tokenizer.TokenType.BLOCK_COMMENT || token.type == Tokenizer.TokenType.COMMENT) {
commentStack.add(token.getSpan());
index++;
continue;
} else if (token.type == Tokenizer.TokenType.HASH) {
Result<AST.PreprocessorExpression> result = parsePreprocessorExpression();
if (result.span.isValid()) {
index = result.span.endOffset + 1;
} else {
addError(token, "Invalid preprocessor expression");
index++;
}
} else {
Result<?> stmt = parseStmt();
if (applyResult(stmt))
continue;
addError(token, "Invalid statement");
index++;
}
}
}
private Result<VariableDeclaration> parseVarDecl() {
int startIndex = index;
StringBuilder type = new StringBuilder();
String identifier = null;
boolean isPointer = false;
boolean isReference = false;
boolean isArray = false;
boolean isFunction = false;
int arraySize = -1;
boolean haveTypeIdentifier = false;
boolean haveIdentifier = false;
int parenDepth = 0;
int idxStart = 0;
int idxDepth = 0;
// Parse type
while (index < tokens.length) {
Token token = tokens[index];
if (token.type == Tokenizer.TokenType.IDENTIFIER || token.type == Tokenizer.TokenType.OTHER) {
// Already have a type identifier, so this is most likely a variable name
if (!haveTypeIdentifier) {
type.append(tokenSet.getTextNoNewlines(token));
haveTypeIdentifier = true;
} else if (!haveIdentifier) {
identifier = tokenSet.getTextNoNewlines(token);
haveIdentifier = true;
if (parenDepth == 0)
break;
} else {
// Unknown
addError(token, "Unknown token after identifier");
}
index++;
} else if (token.type == Tokenizer.TokenType.STAR) {
isPointer = true;
type.append("*");
index++;
} else if (token.type == Tokenizer.TokenType.AMPERSAND) {
isReference = true;
type.append("&");
index++;
} else if (token.type == Tokenizer.TokenType.L_PAREN) {
parenDepth++;
index++;
} else if (token.type == Tokenizer.TokenType.R_PAREN) {
parenDepth--;
index++;
} else if (token.type == Tokenizer.TokenType.L_IDX) {
idxDepth++;
idxStart = token.ofs + 1;
if (haveIdentifier) {
// Parse function parameters?
}
break;
} else if (token.type == Tokenizer.TokenType.R_IDX) {
idxDepth--;
if (idxDepth == 0) {
String idxVal = tokenSet.getTextNoNewlines(idxStart, (token.ofs - 1) - idxStart);
type.append("[" + idxVal + "]");
}
break;
} else {
break;
}
}
AST.Span span = new AST.Span(tokens[startIndex].ofs, tokens[index].getEnd());
VariableDeclaration varDecl = new VariableDeclaration(
type.toString().trim(),
identifier,
isPointer,
isReference,
isArray,
arraySize,
isFunction,
span);
return new Result<>(varDecl, span);
}
private Result<?> parseStmt() {
int startIndex = index;
for (int i = startIndex; i < tokens.length; i++) {
Tokenizer.Token token = tokens[i];
Result<VariableDeclaration> varDeclResult = parseVarDecl();
if (varDeclResult.isValid())
return varDeclResult;
// if (token.type == Tokenizer.TokenType.L_PAREN && idStack.size() > 0) {
// // Function call?
// } else if (token.type == Tokenizer.TokenType.SEMICOLON) {
// boolean isVarAssign = false;
// for (int j = startIndex; j < i; j++) {
// if (tokens[j].type == Tokenizer.TokenType.EQUALS) {
// isVarAssign = true;
// }
// }
// } else if (token.type == Tokenizer.TokenType.L_BRACE) {
// boolean isVarAssign = false;
// for (int j = startIndex; j < i; j++) {
// if (tokens[j].type == Tokenizer.TokenType.L_PAREN) {
// int endIndex = findClosingParenthesis(j);
// if (endIndex != -1) {
// index = endIndex;
// }
// }
// }
// }
}
return Result.none();
// if (index + 1 < tokens.length && tokens[index + 1].type ==
// Tokenizer.TokenType.L_PAREN) {
// // Function call or declaration/definition
// if (index > 0 && (tokens[index - 1].type == Tokenizer.TokenType.IDENTIFIER ||
// tokens[index - 1].type == Tokenizer.TokenType.OTHER)) {
// // Function declaration or definition
// index = parseFunctionDeclaration();
// } else {
// // Function call
// index = parseFunctionCall();
// }
// } else {
// // Variable reference
// index = parseVariableReference();
// }
}
private int parseVarDecl(int startIndex, int endIndex) {
if (tokens[startIndex].type == Tokenizer.TokenType.R_PAREN) {
return startIndex;
}
return startIndex + 1;
}
// Try to parse prep expression
private Result<AST.PreprocessorExpression> parsePreprocessorExpression() {
int startIndex = index;
int index = startIndex;
if (tokenSet.tokens[index].type == Tokenizer.TokenType.HASH) {
int startLine = tokenSet.getLine(index);
while (index < tokenSet.tokens.length) {
if (tokenSet.getLine(index) > startLine) {
break;
}
index++;
}
// Find first next line token
index--;
}
AST.Span span = new AST.Span(startIndex, index);
return new Result(new AST.PreprocessorExpression(span), span);
}
// private ArgumentList parseArgumentList(int startIndex, int endIndex) {
// List<Object> arguments = new ArrayList<>();
// for (int i = startIndex; i < endIndex; i++) {
// if (tokens[i].type == Tokenizer.TokenType.COMMA) {
// }
// }
// return new ArgumentList(arguments);
// }
// // Try to parse function declaration and return the ending token index
// private int parseFunctionDeclaration() {
// Tokenizer.Token[] tokens = tokenSet.getTokens();
// String name = tokenSet.getTextNoNewlines(tokens[index]);
// int endIndex = findClosingParenthesis(index + 1);
// if (endIndex == -1)
// return index;
// boolean isDefinition = false;
// if (endIndex + 1 < tokens.length && tokens[endIndex + 1].type ==
// Tokenizer.TokenType.L_BRACE) {
// isDefinition = true;
// endIndex = findClosingBrace(endIndex + 1);
// }
// if (endIndex == -1)
// return index;
// Function function = new Function(name, tokens[index].ofs,
// tokens[endIndex].ofs + tokens[endIndex].len,
// isDefinition);
// functions.add(function);
// return endIndex - 1;
// }
// // Try to parse function call and return the ending token index
// private int parseFunctionCall() {
// Tokenizer.Token[] tokens = tokenSet.getTokens();
// String name = tokenSet.getTextNoNewlines(tokens[index]);
// int endIndex = findClosingParenthesis(index + 1);
// if (endIndex == -1)
// return index;
// FunctionCall functionCall = new FunctionCall(name, tokens[index].ofs,
// tokens[endIndex].ofs + tokens[endIndex].len);
// functionCalls.add(functionCall);
// return endIndex - 1;
// }
// // Try to parse variable reference and add it to the list
// private int parseVariableReference() {
// Tokenizer.Token token = tokenSet.getTokens()[index];
// String name = tokenSet.getTextNoNewlines(token);
// Variable variable = new Variable(name, token.ofs, token.ofs + token.len);
// variables.add(variable);
// return index + 1;
// }
private int findClosingParenthesis(int startIndex) {
Tokenizer.Token[] tokens = tokenSet.getTokens();
int parenCount = 1;
for (int i = startIndex + 1; i < tokens.length; i++) {
if (tokens[i].type == Tokenizer.TokenType.L_PAREN) {
parenCount++;
} else if (tokens[i].type == Tokenizer.TokenType.R_PAREN) {
parenCount--;
if (parenCount == 0) {
return i;
}
}
}
return -1;
}
private int findClosingBrace(int startIndex) {
Tokenizer.Token[] tokens = tokenSet.getTokens();
int braceCount = 1;
for (int i = startIndex + 1; i < tokens.length; i++) {
if (tokens[i].type == Tokenizer.TokenType.L_BRACE) {
braceCount++;
} else if (tokens[i].type == Tokenizer.TokenType.R_BRACE) {
braceCount--;
if (braceCount == 0) {
return i;
}
}
}
return -1;
}
}

View File

@ -1,392 +0,0 @@
package cparser;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Tokenizer {
public enum TokenType {
UNDEFINED,
HASH,
L_PAREN,
R_PAREN,
L_BRACE,
R_BRACE,
L_IDX,
R_IDX,
SEMICOLON,
EQUALS,
ARROW,
STAR,
AMPERSAND,
COMMA,
COMMENT,
BLOCK_COMMENT,
IDENTIFIER,
STRING_LITERAL,
NUMERIC_LITERAL,
NUMERIC_LITERAL_HEX,
OTHER,
KEYWORD,
}
public class Token {
public int ofs;
public int len;
public TokenType type;
public AST.Span getSpan() {
return new AST.Span(ofs, getEnd());
}
public int getEnd() {
return ofs + len;
}
}
public static class TokenSet {
public final Token[] tokens;
public final String text;
private final TreeMap<Integer, Integer> lineNumberTable;
TokenSet(Token[] tokens, String text, TreeMap<Integer, Integer> lineNumberTable) {
this.tokens = tokens;
this.text = text;
this.lineNumberTable = lineNumberTable;
}
public Token[] getTokens() {
return this.tokens;
}
public int getLine(int offset) {
Map.Entry<Integer, Integer> entry = lineNumberTable.floorEntry(offset);
return entry != null ? entry.getValue() : -1;
}
public String getText(Token token) {
return getText(token.ofs, token.len);
}
public String getText(int ofs, int len) {
return text.substring(ofs, ofs + len); // Fixed recursion issue
}
public String getTextNoNewlines(Token token) {
String text = getText(token);
return text.replace("\n", "");
}
public String getTextNoNewlines(int ofs, int len) {
String text = getText(ofs, len);
return text.replace("\n", "");
}
};
private final String text;
private TreeMap<Integer, Integer> lineNumberTable;
private Log log;
public Tokenizer(String text) {
this.text = text;
}
public Tokenizer(String text, Log log) {
this.text = text;
this.log = log;
}
void log(String msg) {
if (log != null) {
log.log(msg);
}
}
String getText(Token token) {
return getText(token.ofs, token.len);
}
String getText(int ofs, int len) {
return text.substring(ofs, ofs + len); // Fixed recursion issue
}
TokenType lastTokenType = TokenType.UNDEFINED;
/**
* Inserts a new token into the tokens list.
*
* @param tokens The list of tokens.
* @param tokenStart The starting index of the token.
* @param tokenEnd The current index in the text.
* @param currentType The type of the current token.
*/
private void insertToken(List<Token> tokens, int tokenStart, int tokenEnd, TokenType currentType) {
if (currentType != TokenType.UNDEFINED && tokenStart < tokenEnd) {
// Strip whitespace
for (int i = tokenStart; i < tokenEnd; i++) {
if (Character.isWhitespace(text.charAt(i))) {
tokenStart = i + 1;
} else {
break;
}
}
// Strip whitespace from end
for (int i = tokenEnd - 1; i >= tokenStart; i--) {
if (Character.isWhitespace(text.charAt(i))) {
tokenEnd = i;
} else {
break;
}
}
if (tokenEnd - tokenStart > 0) {
Token token = new Token();
token.ofs = tokenStart;
token.len = tokenEnd - tokenStart;
token.type = currentType;
if (currentType == TokenType.IDENTIFIER && isKeyword(getText(token))) {
token.type = TokenType.KEYWORD;
}
tokens.add(token);
}
// Consume the token
currentType = TokenType.UNDEFINED;
}
}
/**
* Handles the insertion of the last token after parsing is complete.
*
* @param tokens The list of tokens.
* @param tokenStart The starting index of the last token.
* @param currentType The type of the last token.
*/
private void handleLastToken(List<Token> tokens, int tokenStart, TokenType currentType) {
insertToken(tokens, tokenStart, text.length(), currentType);
}
void buildLineNumberTable() {
this.lineNumberTable = new TreeMap<>();
int lineNumber = 1;
lineNumberTable.put(0, 1);
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '\n') {
lineNumber++;
lineNumberTable.put(i + 1, lineNumber);
}
}
}
List<Token> tokens = new ArrayList<>();
// Initialize tokenization state
int tokenStart = 0;
TokenType currentType = TokenType.UNDEFINED;
boolean inComment = false;
boolean inBlockComment = false;
boolean inString = false;
class ScanRange {
int start;
int end;
TokenType type;
ScanRange(int start, int end, TokenType type) {
this.start = start;
this.end = end;
this.type = type;
}
// Invalid constructor
ScanRange() {
this.type = TokenType.UNDEFINED;
}
boolean isValid() {
return this.type != TokenType.UNDEFINED;
}
};
// Add the following method to handle hexadecimal literals
private ScanRange tryParseHexadecimal(int currentIndex) {
if (text.charAt(currentIndex) == '0' && currentIndex + 1 < text.length()) {
char nextChar = text.charAt(currentIndex + 1);
if (nextChar == 'x' || nextChar == 'X') {
int tempIndex = currentIndex + 2;
while (tempIndex < text.length()) {
char c = text.charAt(tempIndex);
if (Character.digit(c, 16) == -1) {
break;
}
tempIndex++;
}
if (tempIndex > currentIndex + 2) {
return new ScanRange(currentIndex, tempIndex, TokenType.NUMERIC_LITERAL_HEX);
}
}
}
return new ScanRange();
}
// Identifier that starts with a letter or underscore, and can contain letters,
// digits, and underscores
private ScanRange tryParseIdentifier(int currentIndex) {
if (Character.isLetter(text.charAt(currentIndex)) || text.charAt(currentIndex) == '_') {
int tempIndex = currentIndex + 1;
while (tempIndex < text.length()) {
char c = text.charAt(tempIndex);
if (!(Character.isLetter(c) || Character.isDigit(c) || c == '_')) {
break;
}
tempIndex++;
}
return new ScanRange(currentIndex, tempIndex, TokenType.IDENTIFIER);
}
return new ScanRange();
}
private ScanRange tryParseWithLookahead(int currentIndex) {
ScanRange sr = tryParseHexadecimal(currentIndex);
if (!sr.isValid()) {
sr = tryParseIdentifier(currentIndex);
}
return sr;
}
public boolean isKeyword(String text) {
return text.equals("while") || text.equals("for") || text.equals("if") || text.equals("else") ||
text.equals("return") || text.equals("struct") || text.equals("typedef") ||
text.equals("enum") || text.equals("union") || text.equals("const") || text.equals("static");
}
public TokenSet parse() {
this.buildLineNumberTable();
int index = 0;
while (index < text.length()) {
char currentChar = text.charAt(index);
TokenType newType = TokenType.OTHER;
// Handle comments
if (inBlockComment) {
newType = TokenType.BLOCK_COMMENT;
if (currentChar == '*') {
if (index + 1 < text.length() && text.charAt(index + 1) == '/') {
inBlockComment = false;
index++;
}
}
} else if (inComment) {
newType = TokenType.COMMENT;
if (currentChar == '\n') {
inComment = false;
}
}
// Handle string literals
else if (inString) {
if (currentChar == '"') {
inString = false;
newType = TokenType.STRING_LITERAL;
} else {
newType = TokenType.STRING_LITERAL;
}
}
// Detect start of comments
else if (currentChar == '/' && index + 1 < text.length() && text.charAt(index + 1) == '*') {
inBlockComment = true;
newType = TokenType.BLOCK_COMMENT;
} else if (currentChar == '/' && index + 1 < text.length() && text.charAt(index + 1) == '/') {
inComment = true;
newType = TokenType.COMMENT;
}
// Detect start of string literals
else if (currentChar == '"') {
inString = true;
newType = TokenType.STRING_LITERAL;
} else {
ScanRange range = tryParseWithLookahead(index);
if (range.isValid()) {
// Insert the current token first
// script.println("Inserting current token: " + currentType + ", start: " +
// tokenStart + ", end: " + range.start);
insertToken(tokens, tokenStart, range.start, currentType);
// Insert a ranged token
// script.println("Inserting ranged token: " + range.type + " start: " +
// range.start + ", end: " + range.end);
insertToken(tokens, range.start, range.end, range.type);
// New start
currentType = TokenType.UNDEFINED;
tokenStart = range.end;
index = range.end;
}
// Detect numeric literals
else if (Character.isDigit(currentChar)) {
newType = TokenType.NUMERIC_LITERAL;
}
// Detect identifiers
else if (Character.isLetter(currentChar) || currentChar == '_') {
newType = TokenType.IDENTIFIER;
}
// Detect parentheses
else if (currentChar == '(') {
newType = TokenType.L_PAREN;
} else if (currentChar == ')') {
newType = TokenType.R_PAREN;
}
// Detect braces
else if (currentChar == '{') {
newType = TokenType.L_BRACE;
} else if (currentChar == '}') {
newType = TokenType.R_BRACE;
}
// Detect semicolon
else if (currentChar == ';') {
newType = TokenType.SEMICOLON;
}
// Detect comma
else if (currentChar == ',') {
newType = TokenType.COMMA;
} else if (currentChar == '#') {
newType = TokenType.HASH;
} else if (currentChar == '&') {
newType = TokenType.AMPERSAND;
} else if (currentChar == '[') {
newType = TokenType.L_IDX;
} else if (currentChar == ']') {
newType = TokenType.R_IDX;
} else if (currentChar == '=') {
newType = TokenType.EQUALS;
} else if (currentChar == '>' && index > 0 && text.charAt(index - 1) == '-') {
newType = TokenType.ARROW;
currentType = TokenType.ARROW;
tokenStart = index - 1;
} else if (currentChar == '*') {
newType = TokenType.STAR;
}
// Handle other characters
else {
newType = TokenType.OTHER;
}
}
// Insert a new token if the type changes
if (newType != currentType) {
insertToken(tokens, tokenStart, index, currentType);
tokenStart = index;
currentType = newType;
}
index++;
}
// Handle the last token
handleLastToken(tokens, tokenStart, currentType);
return new TokenSet(tokens.toArray(new Token[0]), text, lineNumberTable);
}
}

View File

@ -1,150 +0,0 @@
package cparser_tests;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import java.lang.String;
import cparser.Parser;
import cparser.Tokenizer;
import cparser.AST;
import cparser.Log;
import java.util.List;
public class ParserTests {
private Parser parser;
private Tokenizer.TokenSet tokenSet;
private Log testLog;
@Before
public void setUp() {
testLog = new Log() {
@Override
public void log(String msg) {
System.out.println(msg);
}
};
}
@Test
public void testParseVariableDecl() {
String[] testCases = {
"byte RVar1;",
"tdstLastErrorInfo *pdVar2;",
"undefined4 *puVar2;",
"CHAR pathToUbi_ini[260];",
"undefined& DAT_005a9ed4;",
"char(&s_Identifier_005b6420)[16];",
"void (*fnType)(int j, char, bool);",
"void** (*fnType)(int j, char, bool);"
};
for (String code : testCases) {
tokenSet = new Tokenizer(code).parse();
parser = new Parser(tokenSet, testLog);
parser.parse();
List<AST.VariableDeclaration> declarations = parser.getVariableDeclarations();
assertEquals("Failed for case: " + code, 1, declarations.size());
AST.VariableDeclaration decl = declarations.get(0);
assertNotNull(decl);
System.out.println("Parsed: " + code);
System.out.println(" Type: " + decl.type);
System.out.println(" Identifier: " + decl.identifier);
System.out.println(" Is Pointer: " + decl.isPointer);
System.out.println(" Is Reference: " + decl.isReference);
System.out.println(" Is Array: " + decl.isArray);
System.out.println(" Array Size: " + decl.arraySize);
System.out.println(" Is Function: " + decl.isFunction);
System.out.println();
}
}
/*
* @Test
* public void testParseFunctionDeclaration() {
* String code = "void foo(int a, int b);";
* tokenSet = new Tokenizer(code).parse();
* parser = new Parser(tokenSet, testLog);
* parser.parse();
*
* List<Parser.Function> functions = parser.getFunctions();
* assertEquals(1, functions.size());
* assertEquals("foo", functions.get(0).name);
* assertFalse(functions.get(0).isDefinition);
* }
*
* @Test
* public void testParseFunctionDefinition() {
* String code = "int bar(int x) { return x + 1; }";
* tokenSet = new Tokenizer(code).parse();
* parser = new Parser(tokenSet, testLog);
* parser.parse();
*
* List<Parser.Function> functions = parser.getFunctions();
* assertEquals(1, functions.size());
* assertEquals("bar", functions.get(0).name);
* assertTrue(functions.get(0).isDefinition);
* }
*
* @Test
* public void testParseFunctionCall() {
* String code = "result = calculate(5, 10);";
* tokenSet = new Tokenizer(code).parse();
* parser = new Parser(tokenSet, testLog);
* parser.parse();
*
* List<Parser.FunctionCall> functionCalls = parser.getFunctionCalls();
* assertEquals(1, functionCalls.size());
* assertEquals("calculate", functionCalls.get(0).name);
* }
*
* @Test
* public void testParsePreprocessorDirective() {
* String code = "#include <stdio.h>\nint main() { return 0; }";
* tokenSet = new Tokenizer(code).parse();
* parser = new Parser(tokenSet, testLog);
* parser.parse();
*
* List<Parser.Function> functions = parser.getFunctions();
* assertEquals(1, functions.size());
* assertEquals("main", functions.get(0).name);
* }
*
* @Test
* public void testParseComplexCode() {
* String code =
* "#include <stdio.h>\n" +
* "int globalVar = 10;\n" +
* "void helper(int x);\n" +
* "int main() {\n" +
* " int localVar = 5;\n" +
* " helper(localVar);\n" +
* " return 0;\n" +
* "}\n" +
* "void helper(int x) {\n" +
* " printf(\"%d\", x);\n" +
* "}";
*
* tokenSet = new Tokenizer(code).parse();
* parser = new Parser(tokenSet, testLog);
* parser.parse();
*
* List<Parser.Variable> variables = parser.getVariables();
* List<Parser.Function> functions = parser.getFunctions();
* List<Parser.FunctionCall> functionCalls = parser.getFunctionCalls();
*
* assertEquals(2, variables.size());
* assertEquals(2, functions.size());
* assertEquals(2, functionCalls.size());
*
* assertTrue(variables.stream().anyMatch(v -> v.name.equals("globalVar")));
* assertTrue(variables.stream().anyMatch(v -> v.name.equals("localVar")));
* assertTrue(functions.stream().anyMatch(f -> f.name.equals("main")));
* assertTrue(functions.stream().anyMatch(f -> f.name.equals("helper")));
* assertTrue(functionCalls.stream().anyMatch(fc -> fc.name.equals("helper")));
* assertTrue(functionCalls.stream().anyMatch(fc -> fc.name.equals("printf")));
* }
*/
}

View File

@ -1,148 +0,0 @@
// @category _Reman3
// @menupath Reman3.Rebuild Function Database
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.StandAloneDataTypeManager;
import re3lib.FunctionDatabase;
import re3lib.RecompileConfig;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cparser.Parser;
import cparser.Tokenizer;
public class RebuildFunctionDatabase extends GhidraScript {
// Will rebuild all functions
public boolean rebuildAllGlobals = true;
FunctionDatabase functionDB;
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
functionDB = new FunctionDatabase(this);
scanFile(new File(RecompileConfig.INSTANCE.outputDir, "gh_auto/r3_engineLoop.cxx"), FunctionDatabase.Type.Auto);
// scanDirectory(RecompileConfig.INSTANCE.dirDecompAuto, FunctionDatabase.Type.Auto);
// scanDirectory(RecompileConfig.INSTANCE.dirDecompFix, FunctionDatabase.Type.Fix);
// scanDirectory(RecompileConfig.INSTANCE.dirDecompStub, FunctionDatabase.Type.Stub);
println("Applying default filters...");
functionDB.applyDefaultFilters(rebuildAllGlobals);
println("Saving function database...");
functionDB.save();
println("Function database rebuilt successfully.");
// for (FunctionDatabase.Entry entry : functionDB.entries) {
// println(entry.address + " " + entry.name + " " + entry.file.getName());
// for (FunctionDatabase.Dependency dependency : entry.dependencies) {
// println(" " + dependency.address + " " + dependency.name);
// }
// }
}
private void scanDirectory(File directory, FunctionDatabase.Type type) throws Exception {
File[] files = directory.listFiles((dir, name) -> name.endsWith(".cxx"));
if (files == null)
return;
for (File file : files) {
scanFile(file, type);
}
}
private void parseOld(BufferedReader reader, File file, FunctionDatabase.Type type) throws Exception {
String line;
Pattern dependencyPattern = Pattern.compile("(\\w+)\\s+(\\w+)\\(.*\\);\\s*//\\s*([0-9A-Fa-f]{8})\\s*//\\s*(.*)");
Pattern addressPattern = Pattern.compile("//\\s*([0-9A-Fa-f]{8})");
Pattern functionNamePattern = Pattern.compile("(\\S+)\\s+(\\S+)\\s*\\(");
List<FunctionDatabase.Dependency> dependencies = new ArrayList<>();
String address = null;
String functionName = null;
while ((line = reader.readLine()) != null) {
Matcher dependencyMatcher = dependencyPattern.matcher(line);
if (dependencyMatcher.find()) {
// println("Found dependency: " + dependencyMatcher.group(3));
Address depAddress = currentProgram.getAddressFactory().getAddress(dependencyMatcher.group(3));
String name = dependencyMatcher.group(2);
FunctionDatabase.Dependency dependency = functionDB.new Dependency(depAddress, name);
dependencies.add(dependency);
continue;
}
Matcher addressMatcher = addressPattern.matcher(line);
if (addressMatcher.find()) {
// println("Found address: " + addressMatcher.group(1));
address = addressMatcher.group(1);
// Skip any comments or newlines between address and function definition
while ((line = reader.readLine()) != null) {
line = line.trim();
// println("Line: " + line);
if (!line.isEmpty()) {
Matcher functionNameMatcher = functionNamePattern.matcher(line);
if (functionNameMatcher.find()) {
functionName = functionNameMatcher.group(2).trim();
break;
}
}
}
if (functionName != null) {
break;
}
}
}
if (address != null && functionName != null) {
Address functionAddress = currentProgram.getAddressFactory().getAddress(address);
FunctionDatabase.Entry entry = functionDB.new Entry();
entry.address = functionAddress;
entry.name = functionName;
entry.file = file;
entry.type = type;
entry.dependencies = dependencies;
functionDB.entries.add(entry);
} else {
// throw new Exception("Failed to parse function at " + file.getName());
println("Failed to parse function at " + file.getName());
}
}
private void scanFile(File file, FunctionDatabase.Type type) throws Exception {
println("Scanning " + file);
String text = new String(Files.readAllBytes(file.toPath()));
Tokenizer.TokenSet tokens = new Tokenizer(text).parse();
Parser parser = new Parser(tokens);
parser.parse();
// for (CTokenizer.Token token : tokens.getTokens()) {
// int line = tokens.getLine(token.ofs);
// println("Line " + line + ": " + token.ofs + " " + token.len + " " + token.type + " - "
// + tokens.getTextNoNewlines(token));
// }
for (Parser.Function function : parser.getFunctions()) {
println("Function: " + function.name + " " + function.startOffset + " " + function.endOffset);
}
for (Parser.FunctionCall functionCall : parser.getFunctionCalls()) {
println("FunctionCall: " + functionCall.name + " " + functionCall.startOffset + " " + functionCall.endOffset);
}
for (Parser.Variable variable : parser.getVariables()) {
println("Variable: " + variable.name + " " + variable.startOffset + " " + variable.endOffset);
}
}
}

93
java/ghidra/Test.java Normal file
View File

@ -0,0 +1,93 @@
// @category _Reman3
// @menupath Reman3.Test
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.StandAloneDataTypeManager;
import re3lib.RecompileConfig;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// SQLite imports
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Test extends GhidraScript {
// Will rebuild all functions
public boolean rebuildAllGlobals = true;
FunctionDatabase functionDB;
@Override
public void run() throws Exception {
RecompileConfig.INSTANCE = new RecompileConfig(this);
// Example SQLite usage
testSQLite();
}
private void testSQLite() throws Exception {
String dbPath = "jdbc:sqlite:" + RecompileConfig.INSTANCE.outputDir + "/functions.db";
try (Connection conn = DriverManager.getConnection(dbPath)) {
println("Connected to SQLite database: " + dbPath);
// Create a simple table
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE IF NOT EXISTS functions (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"address TEXT NOT NULL, " +
"name TEXT NOT NULL, " +
"file_path TEXT)");
println("Functions table created/verified");
}
// Insert example data
String insertSQL = "INSERT INTO functions (address, name, file_path) VALUES (?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {
pstmt.setString(1, "0x00401000");
pstmt.setString(2, "main");
pstmt.setString(3, "/path/to/main.cxx");
pstmt.executeUpdate();
println("Inserted example function");
}
// Query data
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM functions")) {
while (rs.next()) {
println("Function: " + rs.getString("name") +
" at " + rs.getString("address") +
" in " + rs.getString("file_path"));
}
}
} catch (SQLException e) {
println("SQLite error: " + e.getMessage());
throw e;
}
}
private void scanDirectory(File directory, FunctionDatabase.Type type) throws Exception {
File[] files = directory.listFiles((dir, name) -> name.endsWith(".cxx"));
if (files == null)
return;
for (File file : files) {
scanFile(file, type);
}
}
}

View File

@ -56,7 +56,7 @@ public class RecompileConfig {
this.script = script;
rootDir = new File(script.getSourceFile().getAbsolutePath()).getParentFile().getParentFile().toString();
rootDir = new File(script.getSourceFile().getAbsolutePath()).getParentFile().getParentFile().getParentFile().toString();
outputDir = new File(rootDir, RECOMPILE_PREFIX).toString();
script.println("Output path: " + outputDir);

Binary file not shown.

38
third_party/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,38 @@
add_subdirectory(spdlog)
if(WIN32)
add_library(binkw32 SHARED IMPORTED)
set_target_properties(binkw32 PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/bink/binkw32.lib
)
# Copy to output dir
set(BINK_DST ${CMAKE_CURRENT_BINARY_DIR}/bin/binkw32.dll)
add_custom_command(
OUTPUT ${BINK_DST}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/third_party/bink/binkw32.dll ${BINK_DST}
)
add_custom_target(copy_binkw32 ALL DEPENDS ${BINK_DST})
add_dependencies(binkw32 copy_binkw32)
set(SDK_LIB ${CMAKE_CURRENT_LIST_DIR}/mssdk/lib)
add_library(d3d8_import SHARED IMPORTED)
set_target_properties(d3d8_import PROPERTIES
IMPORTED_IMPLIB ${SDK_LIB}/d3d8.lib
)
add_library(dinput8_import SHARED IMPORTED)
set_target_properties(dinput8_import PROPERTIES
IMPORTED_IMPLIB ${SDK_LIB}/dinput8.lib
)
set(SDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/mssdk/include)
add_library(d3d8 INTERFACE)
target_include_directories(d3d8 INTERFACE ${SDK_INCLUDE})
target_link_libraries(d3d8 INTERFACE d3d8_import)
add_library(dinput8 INTERFACE)
target_include_directories(dinput8 INTERFACE ${SDK_INCLUDE})
target_link_libraries(dinput8 INTERFACE dinput8_import)
endif()

Some files were not shown because too many files have changed in this diff Show More