Skip to content

Commit cbac428

Browse files
committed
GolEntry of GolDP.dll takes a GolImport, and returns a GolExport object
1 parent 2dc63de commit cbac428

11 files changed

Lines changed: 518 additions & 64 deletions

CLAUDE.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ Functions in a compilation unit must be ordered by address (ascending).
6363
// header:
6464
// VTABLE: GOLDP 0x10056440
6565
// SIZE 0xc8ac8
66-
class VelvetThunder0xc8ac8 : public PixelDust0x4 {
66+
class GolDPExport : public PixelDust0x4 {
6767
public:
68-
virtual ~VelvetThunder0xc8ac8(); // vtable+0x00
68+
virtual ~GolDPExport(); // vtable+0x00
6969
virtual void VTable0x04(); // vtable+0x04
7070

7171
// SYNTHETIC: GOLDP 0x10007040
72-
// VelvetThunder0xc8ac8::`scalar deleting destructor'
72+
// GolDPExport::`scalar deleting destructor'
7373

7474
private:
7575
int m_unk0x04; // 0x04
@@ -78,7 +78,7 @@ private:
7878
};
7979

8080
// source:
81-
DECOMP_SIZE_ASSERT(VelvetThunder0xc8ac8, 0xc8ac8)
81+
DECOMP_SIZE_ASSERT(GolDPExport, 0xc8ac8)
8282
```
8383
8484
Member offset comments (`// 0xNN`) and vtable offset comments (`// vtable+0xNN`) are required.
@@ -92,7 +92,7 @@ Uses LEGO Island NCC rules (`tools/ncc/ncc.style`), enforced in CI:
9292
- Globals: `g_unk0xXXXXXXXX`
9393
- Members: `m_unk0xXX` (by offset)
9494
- Parameters: `p_unk0xXX`
95-
- Unknown classes: `RandomName0xSize` (random PascalCase name + `0x` + hex size suffix, e.g. `NeonCactus0x1d6c`, `VelvetThunder0xc8ac8`)
95+
- Unknown classes: `RandomName0xSize` (random PascalCase name + `0x` + hex size suffix, e.g. `NeonCactus0x1d6c`, `GolDPExport`)
9696
- Virtual methods: `VTable0xXX` (by vtable offset)
9797
- Enum constants: `c_` prefix
9898
- All parameters: `p_` prefix, all members: `m_` prefix, all globals: `g_` prefix

CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ add_cxx_warning(parentheses)
6464
# --- GolDP.dll target ---
6565
add_library(goldp SHARED
6666
util/decomp.cpp
67-
GolDP/src/velvetthunder0xc8ac8.cpp
67+
GolDP/src/adapter.cpp
68+
GolDP/src/goldpexport.cpp
6869
GolDP/src/main.cpp
6970
)
7071
reccmp_add_target(goldp ID GOLDP)
@@ -115,6 +116,7 @@ target_link_libraries(legoracers PRIVATE
115116
ole32
116117
winmm
117118
)
119+
add_dependencies(legoracers goldp)
118120

119121
set_property(TARGET legoracers PROPERTY OUTPUT_NAME "LEGORacers")
120122
set_property(TARGET legoracers PROPERTY SUFFIX ".exe")
@@ -145,7 +147,7 @@ if (MSVC_FOR_DECOMP)
145147
target_link_options(legoracers PRIVATE "/OPT:NOREF,ICF")
146148
endif()
147149
if (TARGET goldp)
148-
target_link_options(goldp PRIVATE "/OPT:NOREF")
150+
target_link_options(goldp PRIVATE "/OPT:NOREF,ICF")
149151
endif()
150152

151153
set_property(TARGET legoracers goldp PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")

GolDP/include/adapter.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef GOLDP_ADAPTER_H
2+
#define GOLDP_ADAPTER_H
3+
4+
#include "gol.h"
5+
6+
extern void SetGolImport(GolImport* p_import);
7+
8+
extern void LockGlobalMutex();
9+
10+
extern void ReleaseGlobalMutex();
11+
12+
extern void DetectCPU();
13+
;
14+
15+
#endif // GOLDP_ADAPTER_H

GolDP/include/gol.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#ifndef GOLDP_GOL_H
2+
#define GOLDP_GOL_H
3+
4+
#include "decomp.h"
5+
#include "types.h"
6+
7+
#include <windows.h>
8+
9+
typedef void FatalErrorCBFN(const char* p_message);
10+
typedef void GolExitCBFN();
11+
12+
struct GolImport {
13+
undefined4* m_unk0x0; // 0x00
14+
undefined4* m_unk0x4; // 0x04
15+
undefined4* m_unk0x8[4]; // 0x04
16+
LegoU32 m_unk0x18; // 0x18
17+
undefined4* m_unk0x1c; // 0x1c
18+
HANDLE m_mutex; // 0x20
19+
undefined m_unk0x24[0x28 - 0x24]; // 0x24
20+
FatalErrorCBFN* m_fatalError; // 0x28
21+
};
22+
23+
// VTABLE: GOLDP 0x100564b0
24+
// SIZE 0x4
25+
class GolExport {
26+
public:
27+
// SYNTHETIC: GOLDP 0x10007170
28+
// GolExport::`scalar deleting destructor'
29+
30+
virtual ~GolExport();
31+
virtual undefined4* VTable0x04() = 0;
32+
virtual undefined4* VTable0x08() = 0;
33+
virtual undefined4* VTable0x0c() = 0;
34+
virtual undefined4* VTable0x10() = 0;
35+
virtual undefined4* VTable0x14() = 0;
36+
virtual undefined4* VTable0x18() = 0;
37+
virtual undefined4* VTable0x1c() = 0;
38+
virtual undefined4* VTable0x20() = 0;
39+
virtual undefined4 VTable0x24() = 0;
40+
virtual undefined4* VTable0x28() = 0;
41+
virtual undefined4* VTable0x2c() = 0;
42+
virtual undefined4* VTable0x30() = 0;
43+
virtual undefined4* VTable0x34() = 0;
44+
virtual undefined4* VTable0x38() = 0;
45+
virtual void VTable0x3c(undefined4*) = 0;
46+
virtual void VTable0x40(undefined4*) = 0;
47+
virtual void VTable0x44(undefined4*) = 0;
48+
virtual void VTable0x48(undefined4*) = 0;
49+
virtual void VTable0x4c(undefined4*) = 0;
50+
virtual void VTable0x50(undefined4*) = 0;
51+
virtual void VTable0x54(undefined4*) = 0;
52+
virtual void VTable0x58(undefined4*) = 0;
53+
virtual void VTable0x5c(undefined4*) = 0;
54+
virtual void VTable0x60(undefined4*) = 0;
55+
virtual void VTable0x64(undefined4*) = 0;
56+
virtual void VTable0x68(undefined4*) = 0;
57+
virtual void VTable0x6c(undefined4*) = 0;
58+
};
59+
60+
typedef GolExport* GolEntryCBFN(GolImport*);
61+
typedef void GolExitCBFN();
62+
63+
extern GolExport* GolEntry(GolImport* p_import);
64+
65+
extern void GolExit();
66+
67+
#endif // GOLDP_GOL_H

GolDP/include/goldpexport.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef GolDPExport_H
2+
#define GolDPExport_H
3+
4+
#include "compat.h"
5+
#include "decomp.h"
6+
#include "gol.h"
7+
8+
// VTABLE: GOLDP 0x10056440
9+
// SIZE 0xc8ac8
10+
class GolDPExport : public GolExport {
11+
public:
12+
~GolDPExport() override; // vtable+0x00
13+
14+
// SYNTHETIC: GOLDP 0x10007040
15+
// GolDPExport::`scalar deleting destructor'
16+
17+
undefined4* VTable0x04() override;
18+
undefined4* VTable0x08() override;
19+
undefined4* VTable0x0c() override;
20+
undefined4* VTable0x10() override;
21+
undefined4* VTable0x14() override;
22+
undefined4* VTable0x18() override;
23+
undefined4* VTable0x1c() override;
24+
undefined4* VTable0x20() override;
25+
undefined4 VTable0x24() override;
26+
undefined4* VTable0x28() override;
27+
undefined4* VTable0x2c() override;
28+
undefined4* VTable0x30() override;
29+
undefined4* VTable0x34() override;
30+
undefined4* VTable0x38() override;
31+
void VTable0x3c(undefined4*) override;
32+
void VTable0x40(undefined4*) override;
33+
void VTable0x44(undefined4*) override;
34+
void VTable0x48(undefined4*) override;
35+
void VTable0x4c(undefined4*) override;
36+
void VTable0x50(undefined4*) override;
37+
void VTable0x54(undefined4*) override;
38+
void VTable0x58(undefined4*) override;
39+
void VTable0x5c(undefined4*) override;
40+
void VTable0x60(undefined4*) override;
41+
void VTable0x64(undefined4*) override;
42+
void VTable0x68(undefined4*) override;
43+
void VTable0x6c(undefined4*) override;
44+
45+
private:
46+
undefined m_unk0x04[0xc8ac8 - 0x4]; // 0x04
47+
};
48+
49+
#endif // GolDPExport_H

GolDP/include/velvetthunder0xc8ac8.h

Lines changed: 0 additions & 29 deletions
This file was deleted.

GolDP/library_msvc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// LIBRARY: GOLDP 0x1004b356
66
// ??3@YAXPAX@Z
77

8+
// LIBRARY: GOLDP 0x1004b7fe
9+
// __purecall
10+
811
// LIBRARY: GOLDP 0x1004c5c7
912
// __CRT_INIT@12
1013

GolDP/src/adapter.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include "gol.h"
2+
3+
#include <windows.h>
4+
5+
#if (defined(_MSC_VER) && defined(_M_X64)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64)))
6+
#include <cpuid.h>
7+
#endif
8+
9+
// #ifdef _MSC_VER
10+
// #if _MSC_VER < 1300
11+
// #define cpuid __emit 0x0f __emit 0xa2
12+
// #endif
13+
// #endif
14+
15+
// GLOBAL: GOLDP 0x10065ed4
16+
HANDLE g_globalMutex;
17+
18+
// GLOBAL: GOLDP 0x10065ed8
19+
BOOL g_CPUID_detected;
20+
21+
// GLOBAL: GOLDP 0x10065edc
22+
int g_maxCPUID;
23+
24+
// GLOBAL: GOLDP 0x10065ee0
25+
BOOL g_CPU_supports_MMX;
26+
27+
// GLOBAL: GOLDP 0x10065ee4
28+
char g_cpuManufacturer[13];
29+
30+
// STUB: GOLDP 0x10032b80
31+
void SetGolImport(GolImport* p_import)
32+
{
33+
// TODO
34+
}
35+
36+
// FUNCTION: GOLDP 0x10032bf0
37+
void LockGlobalMutex()
38+
{
39+
if (g_globalMutex != NULL) {
40+
WaitForSingleObject(g_globalMutex, INFINITE);
41+
}
42+
}
43+
44+
// FUNCTION: GOLDP 0x10032c10
45+
void ReleaseGlobalMutex()
46+
{
47+
if (g_globalMutex != NULL) {
48+
ReleaseMutex(g_globalMutex);
49+
}
50+
}
51+
52+
#if defined(_M_IX86) && defined(_M_IX86)
53+
#define NAKED __declspec(naked)
54+
#else
55+
#define NAKED
56+
#endif
57+
58+
// FUNCTION: GOLDP 0x10032c30
59+
NAKED void DetectCPU()
60+
{
61+
#ifdef _MSC_VER
62+
#ifdef _M_IX86
63+
__asm {
64+
push ebx ; Save ebx register (eax, ecx, edx are caller saved)
65+
pushfd ; Push EFLAGS register on the stack
66+
pop eax ; EAX = EFLAGS value
67+
mov edx, eax ; EDX = EAX = EFLAGS value
68+
xor eax, 0x200000 ; EDX = EFLAGS value, EAX = EFLAGS ^ 0x200000
69+
push eax ; Push modified EFLAGS value to the stack
70+
popfd ; Set the EFLAGS register to the modified value
71+
pushfd ; Push EFLAGS regsiter on the stack (again)
72+
pop eax ; EAX = current EFLAGS value; EDX = previous EFLAGS value
73+
cmp eax, edx ; Compre current and modified EFLAGS value
74+
jz no_cpuid ; If they are identical, then the CPU does not support CPUID
75+
76+
xor eax, eax ; EAX=0: Highest Function Parameter and Manufacturer ID
77+
#if _MSC_VER > 1300
78+
cpuid ; Run CPUID(0) [Highest Function Parameter and Manufacturer ID]
79+
#else
80+
__emit 0x0f
81+
__emit 0xa2
82+
#endif
83+
mov [g_maxCPUID],eax ; CPUID(0) -> EAX = Highest Function Parameter (=maximum EAX for CPUID)
84+
mov dword ptr 0[g_cpuManufacturer],ebx ; CPUID(0) -> EBX = characters [0,3] of manufacturer ID
85+
xor eax,eax ; EAX = 0
86+
mov dword ptr 4[g_cpuManufacturer],edx ; CPUID(0) -> EDX = characters [4,7] of manufacturer ID
87+
mov 12[g_cpuManufacturer], al ; Set terminating zero
88+
inc eax ; EAX = 1
89+
mov dword ptr 8[g_cpuManufacturer],ecx ; CPUID(0) -> ECX = characters [8,12] of manufacturer ID
90+
mov [g_CPUID_detected],eax ; Store we succesfully detected cpuid
91+
92+
#if _MSC_VER > 1300
93+
cpuid ; Run CPUID(1) [Processor Info and Feature Bits]
94+
#else
95+
__emit 0x0f
96+
__emit 0xa2
97+
#endif
98+
and edx,0x800000 ; Mask bit 23 of EDX: mmx feature (=64-bit SIMD)
99+
shr edx,0x17 ; Convert mmx feature bit to boolean
100+
mov dword ptr [g_CPU_supports_MMX],edx ; Store MMX feature
101+
102+
no_cpuid:
103+
pop ebx ; Restore EBX
104+
ret ; Return to caller
105+
}
106+
#elif defined(_M_IX64)
107+
int cpuinfo[4];
108+
_cpuid(cpuinfo, 0);
109+
g_maxCPUID = cpuinfo[0];
110+
memcpy(&g_cpuManufacturer[0], &cpuinfo[1], 4);
111+
memcpy(&g_cpuManufacturer[4], &cpuinfo[3], 4);
112+
memcpy(&g_cpuManufacturer[8], &cpuinfo[2], 4);
113+
g_cpuManufacturer[12] = '\0';
114+
_cpuid(cpuinfo, 1);
115+
g_CPU_supports_MMX = !!(cpuinfo[3] & 0x800000);
116+
#endif
117+
#elif defined(__i386__) || defined(x86_64)
118+
unsigned int eax;
119+
unsigned int ebx;
120+
unsigned int ecx;
121+
unsigned int edx;
122+
__get_cpuid(0, &eax, &ebx, &ecx, &edx);
123+
g_maxCPUID = eax;
124+
memcpy(&g_cpuManufacturer[0], &ebx, 4);
125+
memcpy(&g_cpuManufacturer[4], &edx, 4);
126+
memcpy(&g_cpuManufacturer[8], &ecx, 4);
127+
g_cpuManufacturer[12] = '\0';
128+
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
129+
g_CPU_supports_MMX = !!(edx & 0x800000);
130+
#endif
131+
}

0 commit comments

Comments
 (0)