Skip to content

Commit

Permalink
Overlay: add course editor window
Browse files Browse the repository at this point in the history
  • Loading branch information
emoose committed Dec 13, 2024
1 parent 9a6f795 commit 34d08ca
Show file tree
Hide file tree
Showing 9 changed files with 458 additions and 16 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ set(outrun2006tweaks_SOURCES
"src/hooks_misc.cpp"
"src/hooks_textures.cpp"
"src/hooks_uiscaling.cpp"
"src/overlay/course_editor.cpp"
"src/overlay/hooks_overlay.cpp"
"src/overlay/notifications.hpp"
"src/overlay/overlay.cpp"
Expand Down
16 changes: 16 additions & 0 deletions OutRun2006Tweaks.lods.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#
# Please post any bad objects you find to https://github.com/emoose/OutRun2006Tweaks/issues/97!

# PALM BEACH
[Stage 0]
# Bad geo when entering from left-side bunki
0x1 = 0xD

# ALPINE
[Stage 3]
# See-through mountains in distance from bunki
Expand All @@ -31,7 +36,13 @@

# MAYA
[Stage 25]
# Tree sprite on bunki transition
0x1 = 0x34
# Floating temple over entrance
0x1 = 0x34
0x2 = 0x2B8, 0x2B9, 0x2BB, 0x2BC, 0x2BE, 0x2D9, 0x2DB
0x3 = 0x2
0x4 = 0x24

# NEW YORK
[Stage 26]
Expand All @@ -44,3 +55,8 @@
[Stage 60]
# Bad polygon when entering from bunki
0x1 = 0x6

# BEACH (BR)
[Stage 65]
# Bad polygon when entering from bunki
0x1 = 0x27
147 changes: 142 additions & 5 deletions src/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,104 @@ enum GameState
STATE_SUMOREWARD = 0x24,
};

enum GameStage : int
{
STAGE_PALM_BEACH,
STAGE_DEEP_LAKE,
STAGE_INDUSTRIAL_COMPLEX,
STAGE_ALPINE,
STAGE_SNOW_MOUNTAIN,
STAGE_CLOUDY_HIGHLAND,
STAGE_CASTLE_WALL,
STAGE_GHOST_FOREST,
STAGE_CONIFEROUS_FOREST,
STAGE_DESERT,
STAGE_TULIP_GARDEN,
STAGE_METROPOLIS,
STAGE_ANCIENT_RUINS,
STAGE_CAPE_WAY,
STAGE_IMPERIAL_AVENUE,
STAGE_BEACH,
STAGE_SEQUOIA,
STAGE_NIAGARA,
STAGE_LAS_VEGAS,
STAGE_ALASKA,
STAGE_GRAND_CANYON,
STAGE_SAN_FRANCISCO,
STAGE_AMAZON,
STAGE_MACHU_PICCHU,
STAGE_YOSEMITE,
STAGE_MAYA,
STAGE_NEW_YORK,
STAGE_PRINCE_EDWARD,
STAGE_FLORIDA,
STAGE_EASTER_ISLAND,
STAGE_PALM_BEACH_R,
STAGE_DEEP_LAKE_R,
STAGE_INDUSTRIAL_COMPLEX_R,
STAGE_ALPINE_R,
STAGE_SNOW_MOUNTAIN_R,
STAGE_CLOUDY_HIGHLAND_R,
STAGE_CASTLE_WALL_R,
STAGE_GHOST_FOREST_R,
STAGE_CONIFEROUS_FOREST_R,
STAGE_DESERT_R,
STAGE_TULIP_GARDEN_R,
STAGE_METROPOLIS_R,
STAGE_ANCIENT_RUINS_R,
STAGE_CAPE_WAY_R,
STAGE_IMPERIAL_AVENUE_R,
STAGE_BEACH_R,
STAGE_SEQUOIA_R,
STAGE_NIAGARA_R,
STAGE_LAS_VEGAS_R,
STAGE_ALASKA_R,
STAGE_GRAND_CANYON_R,
STAGE_SAN_FRANCISCO_R,
STAGE_AMAZON_R,
STAGE_MACHU_PICCHU_R,
STAGE_YOSEMITE_R,
STAGE_MAYA_R,
STAGE_NEW_YORK_R,
STAGE_PRINCE_EDWARD_R,
STAGE_FLORIDA_R,
STAGE_EASTER_ISLAND_R,
STAGE_PALM_BEACH_T,
STAGE_BEACH_T,
STAGE_PALM_BEACH_BT,
STAGE_BEACH_BT,
STAGE_PALM_BEACH_BR,
STAGE_BEACH_BR
};
static_assert(sizeof(GameStage) == 4);

struct TAG_model_info
{
uint8_t todo[0x98];
};
static_assert(sizeof(TAG_model_info) == 0x98);

struct StageTable_mb
{
GameStage StageUniqueName_0;
int StageTableIdx_4;
uint32_t field_8;
uint32_t field_C;
int ExtendedTime_10;
TAG_model_info* CsInfoPtr_14;
TAG_model_info* BrInfoPtr_18;
int CsInfoId_1C;
int BrInfoId_20;
int ExitTableIdx_24[2];
int ExitIDs_2C[2];
uint8_t gap34[48];
struct tagOthcarPercentTable* OthcarPercentTablePtr_64;
void* OthcarPercentTablePtr_68;
uint32_t field_6C;
uint32_t field_70;
uint32_t field_74;
};

enum ChrSet
{
CHR_AUT01 = 0,
Expand Down Expand Up @@ -500,6 +598,8 @@ typedef struct tagEVWORK_CAR
float field_10DC;
float field_10E0;
uint8_t unk_10E4[12];

inline bool is_in_bunki() { return OnRoadPlace_5C.loadColiType_0 != 0; }
} EVWORK_CAR;
static_assert(sizeof(EVWORK_CAR) == 0x10F0);
// car0 = 0x7804B0
Expand Down Expand Up @@ -632,11 +732,48 @@ typedef struct TDrawBuffer
} DrawBuffer;
static_assert(sizeof(DrawBuffer) == 0x1C);

inline void WaitForDebugger()
struct SumoNet_MatchMakingInfo
{
#ifdef _DEBUG
while (!IsDebuggerPresent())
uint32_t SlotCount_0;
uint32_t SlotCount_4;
int SlotCount_8;
int SlotCount_C;
char unk_field_24_10;
uint8_t unk_11[3];
uint32_t MatchType_14;
uint32_t Nationality_18;
uint32_t unk_field_54_1C;
uint32_t unk_field_58_20;
uint32_t CourseType_24;
uint32_t Course_28;
uint32_t unk_field_64_2C;
uint32_t CarClass_30;
uint32_t CarType_34;
uint32_t CatchUp_38;
uint32_t unk_field_74_3C;
uint32_t Collision_40;
uint32_t unk_field_7C_44;
char LobbyName_48[16];
};
static_assert(sizeof(SumoNet_MatchMakingInfo) == 0x58);

struct SumoNet_NetDriver
{
uint32_t vftable;
uint8_t unk_4;
uint8_t is_hosting_5;
uint8_t unk_6;
uint8_t is_online_7;

inline bool is_online_driver()
{
// some other drivers seem to be for lan/online/etc
// TODO: should probably use Module::exe_ptr here, but it's not included atm..
return vftable == 0x627EB8;
}
#endif
}

inline bool is_hosting_online()
{
return is_online_driver() && is_hosting_5 && is_online_7;
}
};
8 changes: 6 additions & 2 deletions src/game_addrs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace Game
inline int* app_time = nullptr; // used by SetTweeningTable etc
inline int* sprani_num_ticks = nullptr; // number of game ticks being ran in the current frame (can be 0 if above 60FPS)

inline int* stg_stage_num = nullptr;
inline GameStage* stg_stage_num = nullptr;

inline D3DXVECTOR2* screen_scale = nullptr;

Expand Down Expand Up @@ -102,6 +102,8 @@ namespace Game
inline fn_stdcall_1arg_int Sumo_CheckRacerUnlocked = nullptr;

inline const char* SumoNet_OnlineUserName = nullptr;
inline SumoNet_MatchMakingInfo* SumoNet_LobbyInfo = nullptr;
inline SumoNet_NetDriver** SumoNet_CurNetDriver = nullptr;

// 2d sprite drawing
inline fn_1arg sprSetFontPriority = nullptr;
Expand Down Expand Up @@ -179,7 +181,7 @@ namespace Game
app_time = Module::exe_ptr<int>(0x49EDB8);
sprani_num_ticks = Module::exe_ptr<int>(0x380278);

stg_stage_num = Module::exe_ptr<int>(0x3D2E8C);
stg_stage_num = Module::exe_ptr<GameStage>(0x3D2E8C);

screen_scale = Module::exe_ptr<D3DXVECTOR2>(0x340C94);

Expand Down Expand Up @@ -228,6 +230,8 @@ namespace Game
Sumo_CheckRacerUnlocked = Module::fn_ptr<fn_stdcall_1arg_int>(0xE8410);

SumoNet_OnlineUserName = Module::exe_ptr<const char>(0x430C20);
SumoNet_LobbyInfo = Module::exe_ptr<SumoNet_MatchMakingInfo>(0x37FF90);
SumoNet_CurNetDriver = Module::exe_ptr<SumoNet_NetDriver*>(0x3D68AC);

sprSetFontPriority = Module::fn_ptr<fn_1arg>(0x2CCB0);
sprSetPrintFont = Module::fn_ptr<fn_1arg>(0x2CA60);
Expand Down
6 changes: 3 additions & 3 deletions src/hooks_drawdistance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void DrawDist_DrawOverlay()
return;
}

int cur_stage_num = *Game::stg_stage_num;
GameStage cur_stage_num = *Game::stg_stage_num;
const char* cur_stage_name = Game::GetStageUniqueName(cur_stage_num);
auto& objectExclusions = ObjectExclusionsPerStage[cur_stage_num];

Expand Down Expand Up @@ -159,7 +159,7 @@ void DrawDist_DrawOverlay()
}
}
if (!clipboard.empty())
clipboard = std::format("# {}\n[Stage {}]{}", cur_stage_name, cur_stage_num, clipboard);
clipboard = std::format("# {}\n[Stage {}]{}", cur_stage_name, int(cur_stage_num), clipboard);

HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, clipboard.length() + 1);
if (hMem)
Expand Down Expand Up @@ -390,7 +390,7 @@ class DrawDistanceIncrease : public Hook
{
// CANYON: when cur section is lower than 30 (car inside bunki), limit draw dist to ~80
// prevents some far-off stage parts drawing in the air
if (*Game::stg_stage_num == 20 /* CANYON */ && CsLengthNum < 30)
if (*Game::stg_stage_num == STAGE_GRAND_CANYON && CsLengthNum < 30)
maxDrawDistance = min(maxDrawDistance, 80);
}

Expand Down
Loading

0 comments on commit 34d08ca

Please sign in to comment.