Skip to content

Commit e3e7466

Browse files
authored
More race implementation (isledecomp#489)
1 parent f554fd0 commit e3e7466

48 files changed

Lines changed: 1305 additions & 1116 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,10 @@ add_executable(legoracers WIN32
424424
LEGORacers/src/save/savegame.cpp
425425
LEGORacers/src/save/savegamefile.cpp
426426
LEGORacers/src/save/memorycardfilebase.cpp
427+
LEGORacers/src/save/memorycardfile.cpp
427428
LEGORacers/src/save/gamestate.cpp
428429
LEGORacers/src/save/savesystem.cpp
430+
LEGORacers/src/save/memorycardsavegame.cpp
429431
LEGORacers/src/model/carpartset.cpp
430432
LEGORacers/src/model/legopiecelibrary.cpp
431433
LEGORacers/src/menu/runtime/cutsceneparticle.cpp

LEGORacers/include/app/legoracers.h

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include "decomp.h"
99
#include "golname.h"
1010
#include "racer/drivercosmetics.h"
11-
#include "save/savegame.h"
11+
#include "save/persistentgamestate.h"
12+
#include "save/saverecordlist.h"
1213
#include "types.h"
1314

1415
class GolMaterialLibrary;
@@ -81,40 +82,40 @@ class LegoRacers : public GolAppEventHandler {
8182
c_raceModeTimeRace = 2,
8283
};
8384

84-
LegoBool32 m_running; // 0x00
85-
Win32GolApp* m_golApp; // 0x04
86-
SoundManager* m_soundManager; // 0x08
87-
LegoFloat m_unk0x0c; // 0x0c
88-
LegoFloat m_unk0x10; // 0x10
89-
LegoFloat m_unk0x14; // 0x14
90-
undefined4 m_unk0x18; // 0x18
91-
LegoU16 m_nextMenuId; // 0x1c
92-
LegoU8 m_unk0x1e; // 0x1e
93-
undefined m_unk0x1f; // 0x1f
94-
LegoU32 m_unk0x20; // 0x20
95-
undefined4 m_raceMode; // 0x24
96-
LegoU32 m_languageIndex; // 0x28
97-
undefined m_unk0x2c; // 0x2c
98-
GolName m_circuitName; // 0x2d
99-
undefined m_unk0x35[0x38 - 0x35]; // 0x35
100-
RaceSlot m_raceSlots[4]; // 0x38
101-
LegoU32 m_bestLapTimes[4]; // 0x98
102-
LegoU32 m_bestLapHolders[4]; // 0xa8
103-
LegoU32 m_bestRaceTimes[4]; // 0xb8
104-
LegoU32 m_bestRaceHolders[4]; // 0xc8
105-
LegoU32 m_currentRaceIndex; // 0xd8
106-
LegoChar m_gameDataDirectory[18]; // 0xdc
107-
LegoChar m_commonDataDirectory[18]; // 0xee
108-
undefined4 m_racerCount; // 0x100
109-
PlayerSetupSlot m_playerSetupSlots[c_playerSetupSlotCount]; // 0x104
110-
undefined4 m_playerCount; // 0x32c
111-
PlayerRecordState m_playerRecordStates[c_playerRecordStateCount]; // 0x330
112-
InputBindingEntry m_inputBindings[c_inputBindingEntryCount]; // 0x348
113-
undefined4 m_unk0x398; // 0x398
114-
LegoU32 m_saveRecordCount; // 0x39c
115-
SaveRecordData m_saveRecords[5]; // 0x3a0
116-
PersistentGameState m_saveState; // 0xe81
117-
undefined m_unk0x12ad[0x12b0 - 0x12ad]; // 0x12ad
85+
LegoBool32 m_running; // 0x00
86+
Win32GolApp* m_golApp; // 0x04
87+
SoundManager* m_soundManager; // 0x08
88+
LegoFloat m_unk0x0c; // 0x0c
89+
LegoFloat m_unk0x10; // 0x10
90+
LegoFloat m_unk0x14; // 0x14
91+
undefined4 m_unk0x18; // 0x18
92+
LegoU16 m_nextMenuId; // 0x1c
93+
LegoU8 m_unk0x1e; // 0x1e
94+
undefined m_unk0x1f; // 0x1f
95+
LegoU32 m_unk0x20; // 0x20
96+
undefined4 m_raceMode; // 0x24
97+
LegoU32 m_languageIndex; // 0x28
98+
undefined m_unk0x2c; // 0x2c
99+
GolName m_circuitName; // 0x2d
100+
undefined m_unk0x35[0x38 - 0x35]; // 0x35
101+
RaceSlot m_raceSlots[4]; // 0x38
102+
LegoU32 m_bestLapTimes[4]; // 0x98
103+
LegoU32 m_bestLapHolders[4]; // 0xa8
104+
LegoU32 m_bestRaceTimes[4]; // 0xb8
105+
LegoU32 m_bestRaceHolders[4]; // 0xc8
106+
LegoU32 m_currentRaceIndex; // 0xd8
107+
LegoChar m_gameDataDirectory[18]; // 0xdc
108+
LegoChar m_commonDataDirectory[18]; // 0xee
109+
undefined4 m_racerCount; // 0x100
110+
PlayerSetupSlot m_playerSetupSlots[c_playerSetupSlotCount]; // 0x104
111+
undefined4 m_playerCount; // 0x32c
112+
PlayerRecordState m_playerRecordStates[c_playerRecordStateCount]; // 0x330
113+
InputBindingState::Entry m_inputBindings[c_inputBindingEntryCount]; // 0x348
114+
undefined4 m_unk0x398; // 0x398
115+
LegoU32 m_saveRecordCount; // 0x39c
116+
SaveRecordData m_saveRecords[5]; // 0x3a0
117+
PersistentGameState m_saveState; // 0xe81
118+
undefined m_unk0x12ad[0x12b0 - 0x12ad]; // 0x12ad
118119

119120
SoundManager* GetSoundManager() { return m_soundManager; }
120121
LegoFloat GetUnk0x0c() const { return m_unk0x0c; }

LEGORacers/include/menu/screens/awardcinematicscreen.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
#include "golworldentitygroup0x38.h"
99
#include "menu/screens/menuscenescreen.h"
1010
#include "race/data/circuitdefinitionlist.h"
11-
#include "save/savegame.h"
11+
#include "save/saverecordlist.h"
1212

1313
class ChassisModelTable;
14-
class GolWorldEntity;
1514
class CarBuildModel;
15+
class GameState;
16+
class GolWorldEntity;
1617

1718
// VTABLE: LEGORACERS 0x004b2c5c
1819
// SIZE 0x7b0

LEGORacers/include/menu/screens/editcarscreen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
#include "menu/widgets/menuselector.h"
1616
#include "menu/widgets/menutextbutton.h"
1717
#include "menu/widgets/menutextlabel.h"
18-
#include "save/savegame.h"
1918

2019
class CmbModelPart0x34;
2120
class GolModelBase;
2221
class GolSceneNode;
22+
class ActiveRecordBuffer;
2323

2424
// VTABLE: LEGORACERS 0x004b3294
2525
// SIZE 0x36c4

LEGORacers/include/menu/screens/multiplayerpickscreen.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
#include "menu/screens/racermodelscreenbase.h"
88
#include "menu/widgets/menuimage.h"
99
#include "menu/widgets/menutextlabel.h"
10+
#include "save/inputbindingstate.h"
1011

1112
class InputDevice;
12-
struct InputBindingEntry;
1313

1414
// VTABLE: LEGORACERS 0x004b3774
1515
// SIZE 0x2cc4
@@ -35,17 +35,17 @@ class MultiplayerPickScreen : public RacerModelScreenBase {
3535
void FUN_00481b60(LegoS32 p_index);
3636
void FUN_00481bf0(LegoS32 p_index);
3737

38-
MenuImage m_unk0x270c; // 0x270c
39-
MenuImage m_unk0x2768[6]; // 0x2768
40-
MenuTextLabel m_unk0x2990; // 0x2990
41-
MenuTextLabel m_unk0x2a08; // 0x2a08
42-
MenuTextLabel m_unk0x2a80; // 0x2a80
43-
MenuTextLabel m_unk0x2af8; // 0x2af8
44-
InputDevice* m_unk0x2b70[2]; // 0x2b70
45-
InputBindingEntry* m_unk0x2b78; // 0x2b78
46-
GolString m_unk0x2b7c[2]; // 0x2b7c
47-
undefined2 m_unk0x2b94[2][16]; // 0x2b94
48-
MenuTextLabel m_unk0x2bd4[2]; // 0x2bd4
38+
MenuImage m_unk0x270c; // 0x270c
39+
MenuImage m_unk0x2768[6]; // 0x2768
40+
MenuTextLabel m_unk0x2990; // 0x2990
41+
MenuTextLabel m_unk0x2a08; // 0x2a08
42+
MenuTextLabel m_unk0x2a80; // 0x2a80
43+
MenuTextLabel m_unk0x2af8; // 0x2af8
44+
InputDevice* m_unk0x2b70[2]; // 0x2b70
45+
InputBindingState::Entry* m_unk0x2b78; // 0x2b78
46+
GolString m_unk0x2b7c[2]; // 0x2b7c
47+
undefined2 m_unk0x2b94[2][16]; // 0x2b94
48+
MenuTextLabel m_unk0x2bd4[2]; // 0x2bd4
4949
};
5050

5151
#endif // MULTIPLAYERPICKSCREEN_H

LEGORacers/include/menu/screens/racermodelslot.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class RacerModelSlot : public MenuSceneElement {
5050
undefined4 m_unk0x7c; // 0x7c
5151
undefined4 m_unk0x80; // 0x80
5252
undefined4 m_unk0x84; // 0x84
53-
undefined4 m_unk0x88[3]; // 0x88
53+
GolVec3 m_unk0x88; // 0x88
5454
LegoU32 m_unk0x94; // 0x94
5555
LegoU32 m_unk0x98; // 0x98
5656
LegoBool32 m_unk0x9c; // 0x9c

LEGORacers/include/menu/screens/racerunlockstate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include "compat.h"
55
#include "decomp.h"
6-
#include "save/savegame.h"
6+
#include "save/saverecordlist.h"
77
#include "types.h"
88

99
class SaveSystem;

LEGORacers/include/race/racesession.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,19 +1350,19 @@ class RaceSession : public GolAppEventHandler {
13501350
public:
13511351
// SIZE 0x38
13521352
struct Params {
1353-
GolD3DRenderDevice* m_renderer; // 0x00
1354-
GolModelBase* m_model; // 0x04
1355-
GolVec3 m_origin; // 0x08
1356-
LegoFloat m_radius; // 0x14
1357-
LegoU32 m_segmentCount; // 0x18
1358-
LegoU32 m_unk0x1c; // 0x1c
1359-
LegoU32 m_unk0x20; // 0x20
1360-
LegoU32 m_unk0x24; // 0x24
1361-
LegoU32 m_unk0x28; // 0x28
1362-
LegoU32 m_unk0x2c; // 0x2c
1363-
LegoU16 m_vertexType; // 0x30
1364-
undefined2 m_unk0x32; // 0x32
1365-
GdbModelIndexArray0xc* m_unk0x34; // 0x34
1353+
GolD3DRenderDevice* m_renderer; // 0x00
1354+
GolModelBase* m_model; // 0x04
1355+
GolVec3 m_origin; // 0x08
1356+
LegoFloat m_radius; // 0x14
1357+
LegoU32 m_segmentCount; // 0x18
1358+
LegoU32 m_hemisphere; // 0x1c
1359+
LegoU32 m_hasTopCap; // 0x20
1360+
LegoU32 m_hasBottomCap; // 0x24
1361+
LegoU32 m_reverseWinding; // 0x28
1362+
LegoU32 m_useTextureSeam; // 0x2c
1363+
LegoU16 m_vertexType; // 0x30
1364+
undefined2 m_unk0x32; // 0x32
1365+
GdbModelIndexArray0xc* m_absoluteIndexArray; // 0x34
13661366
};
13671367

13681368
void FUN_004907d0(Params* p_params);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef ACTIVERECORDBUFFER_H
2+
#define ACTIVERECORDBUFFER_H
3+
4+
#include "save/saverecordlist.h"
5+
6+
class GolString;
7+
8+
// SIZE 0x250
9+
class ActiveRecordBuffer : public SaveRecordList::Record {
10+
public:
11+
static void CopyBufferToString(GolString* p_string, const LegoU8* p_source, LegoU32 p_count);
12+
static void CopyStringToBuffer(GolString* p_string, LegoU8* p_dest, LegoU32 p_count);
13+
14+
void SetCarData(const LegoU8* p_source);
15+
void Reset() { m_selectedRecordCount = 0; }
16+
undefined4 GetSelectedRecordCount() const { return m_selectedRecordCount; }
17+
undefined2 GetSelectedRecordCountAsU16() const { return static_cast<undefined2>(m_selectedRecordCount); }
18+
SaveRecordList::Record* GetSelectedRecord() const { return m_selectedRecords[0]; }
19+
SaveRecordList::Record* GetSelectedRecord(LegoU32 p_index) const { return m_selectedRecords[p_index]; }
20+
void SetSelectedRecordCount(undefined4 p_count) { m_selectedRecordCount = p_count; }
21+
void SetSelectedRecord(SaveRecordList::Record* p_record) { m_selectedRecords[0] = p_record; }
22+
void SetSelectedRecord(LegoU32 p_index, SaveRecordList::Record* p_record) { m_selectedRecords[p_index] = p_record; }
23+
24+
private:
25+
undefined4 m_selectedRecordCount; // 0x244
26+
SaveRecordList::Record* m_selectedRecords[2]; // 0x248
27+
};
28+
29+
#endif // ACTIVERECORDBUFFER_H
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#ifndef GAMESTATE_H
2+
#define GAMESTATE_H
3+
4+
#include "save/persistentgamestate.h"
5+
#include "save/saverecordlist.h"
6+
#include "types.h"
7+
#include "util/displaydriverguid.h"
8+
9+
class GolString;
10+
class InputManager;
11+
class SaveGame;
12+
13+
// SIZE 0x438
14+
class GameState {
15+
public:
16+
GameState();
17+
~GameState();
18+
19+
void Initialize(InputManager* p_inputManager);
20+
void Reset();
21+
void InitializeInputBindings(InputManager* p_inputManager);
22+
void SelectInputBinding(LegoU32 p_playerIndex, LegoU32 p_entryIndex);
23+
void LoadFromSaveGame(SaveGame* p_saveGame, LegoU32 p_activeSaveIndex);
24+
LegoU32 GetInputEvent(LegoU32 p_playerIndex, LegoU32 p_entryIndex, LegoU32 p_eventIndex);
25+
void GetInputBindingEntry(LegoU32 p_playerIndex, LegoU32 p_entryIndex, InputBindingState::Entry* p_entry);
26+
void SetInputEvent(LegoU32 p_entryIndex, LegoU32 p_eventIndex, LegoU32 p_event);
27+
void WriteToSaveGame(SaveGame*);
28+
void SetLanguageResourcePath();
29+
void SetDisplayDriverGuid(const DisplayDriverGuid& p_guid);
30+
void GetDisplayDriverGuid(DisplayDriverGuid& p_guid);
31+
void UnlockParts(LegoU8 p_flags);
32+
void UnlockCircuits(LegoU8 p_flags);
33+
LegoU16 GetUnlockedRaces() const;
34+
LegoBool32 UnlockRace(LegoU32 p_mask);
35+
LegoBool32 AreAllRacesUnlocked() const;
36+
LegoU32 GetBestTime(LegoU32 p_raceIndex, LegoBool32 p_raceTime, GolString* p_string) const;
37+
LegoBool32 SetBestTime(LegoU32 p_raceIndex, LegoBool32 p_raceTime, LegoU32 p_time, GolString* p_string);
38+
39+
void SetDirty(LegoBool32 p_dirty) { m_dirty = p_dirty; }
40+
void SetRacerCount(LegoU32 p_racerCount)
41+
{
42+
m_dirty = 1;
43+
m_state.m_racerCount = static_cast<LegoU8>(p_racerCount);
44+
}
45+
void SetMusicVolume(LegoU8 p_musicVolume)
46+
{
47+
m_state.m_musicVolume = p_musicVolume;
48+
m_dirty = 1;
49+
}
50+
void SetSoundVolume(LegoU8 p_soundVolume)
51+
{
52+
m_state.m_soundVolume = p_soundVolume;
53+
m_dirty = 1;
54+
}
55+
void SetUnk0x21(LegoU8 p_unk0x21)
56+
{
57+
m_state.m_unk0x21 = p_unk0x21;
58+
m_dirty = 1;
59+
}
60+
void SetUnk0x23(LegoU32 p_unk0x23)
61+
{
62+
m_dirty = 1;
63+
m_state.m_unk0x23 = static_cast<LegoU8>(p_unk0x23);
64+
}
65+
void SetInputBindingPlayer0Unk0x00(undefined4 p_unk0x00)
66+
{
67+
m_state.m_inputBindings.m_players[0].m_selectedRecordId = static_cast<LegoU8>(p_unk0x00);
68+
m_dirty = 1;
69+
}
70+
void SetInputBindingPlayer0Unk0x01(undefined4 p_unk0x01)
71+
{
72+
m_state.m_inputBindings.m_players[0].m_selectedRecordSource = static_cast<LegoU8>(p_unk0x01);
73+
m_dirty = 1;
74+
}
75+
void SetInputBindingPlayer0Unk0x02(undefined4 p_unk0x02)
76+
{
77+
m_state.m_inputBindings.m_players[0].m_selectedSaveIndex = static_cast<LegoU8>(p_unk0x02);
78+
m_dirty = 1;
79+
}
80+
void SetInputBindingPlayer0RecordValues(const SaveRecordList::Record* p_record)
81+
{
82+
m_state.m_inputBindings.m_players[0].m_selectedRecordSource = static_cast<LegoU8>(p_record->m_recordSource);
83+
m_dirty = 1;
84+
m_state.m_inputBindings.m_players[0].m_selectedSaveIndex = static_cast<LegoU8>(p_record->m_saveIndex);
85+
m_dirty = 1;
86+
m_state.m_inputBindings.m_players[0].m_selectedRecordId = static_cast<LegoU8>(p_record->m_recordId);
87+
m_dirty = 1;
88+
}
89+
void SetLanguageIndex(LegoU8 p_languageIndex) { m_state.m_languageIndex = p_languageIndex; }
90+
LegoU8 GetSelectedInputBindingEntryIndex(LegoU32 p_playerIndex) const
91+
{
92+
return m_state.m_inputBindings.GetSelectedEntryIndex(p_playerIndex);
93+
}
94+
LegoBool32 IsDirty() const { return m_dirty; }
95+
undefined4 GetActiveSaveIndex() const { return m_activeSaveIndex; }
96+
PersistentGameState& GetState() { return m_state; }
97+
LegoU8 GetRacerCount() const { return m_state.m_racerCount; }
98+
LegoU8 GetMusicVolume() const { return m_state.m_musicVolume; }
99+
LegoU8 GetSoundVolume() const { return m_state.m_soundVolume; }
100+
LegoU8 GetUnk0x21() const { return m_state.m_unk0x21; }
101+
LegoU32 GetLanguageIndex() const { return m_state.m_languageIndex; }
102+
LegoU8 GetUnk0x23() const { return m_state.m_unk0x23; }
103+
LegoU8 GetPartUnlockFlags() const;
104+
LegoU8 GetUnlockedCircuits() const;
105+
106+
private:
107+
enum {
108+
c_joystickBindingCount = 2,
109+
c_keyboardBindingStart = 2,
110+
c_inputBindingEntryCount = 5,
111+
c_inputBindingEventCount = 9,
112+
c_joystickDeviceType = 4,
113+
c_axisJoystickDeviceSubType = 4,
114+
};
115+
116+
void Initialize();
117+
void SelectFallbackInputBinding(LegoU32 p_playerIndex);
118+
LegoU32 FindAvailableInputBindingEntry(LegoU32 p_playerIndex);
119+
LegoBool32 IsInputEventBound(LegoU32 p_entryIndex, LegoU32 p_event);
120+
LegoU32 GetDefaultInputEvent(LegoU32 p_entryIndex, LegoU32 p_eventIndex);
121+
LegoU32 GetRegistryLanguageIndex();
122+
123+
LegoBool32 m_dirty; // 0x00
124+
undefined4 m_activeSaveIndex; // 0x04
125+
InputManager* m_inputManager; // 0x08
126+
PersistentGameState m_state; // 0x0c
127+
};
128+
129+
#endif // GAMESTATE_H

0 commit comments

Comments
 (0)