From 672021b7be4406145772adf6153e38d97be80692 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 12:24:22 +0200 Subject: [PATCH 01/35] Implement ClearMatertrialSetFromStorageSpace --- src/carma2/newcommon/28-world3.c | 29 ++++++++++++++++++++++++++--- src/carma2/newcommon/28-world3.h | 2 +- src/carma2/newcommon/50-fog.c | 5 ++++- src/carma2/newcommon/50-fog.h | 3 ++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index 743639cf5c..1e81c31362 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -1,10 +1,13 @@ #include "28-world3.h" #include "41-utility.h" +#include "50-fog.h" #include "52-errors.h" #include "63-loading3.h" #include "69-sound.h" #include "70-packfile.h" +#include "globvars.h" +#include "globvrpb.h" #include "rec2_macros.h" #include @@ -103,9 +106,29 @@ void C2_HOOK_FASTCALL InitialiseStorageSpace(int pUnknown, tBrender_storage* pSt // DisposeStorageSpace -// STUB: CARMA2_HW 0x00500e60 -void C2_HOOK_FASTCALL ClearMatertrialSetFromStorageSpace(tBrender_storage* pStorage_space, int pOld_count, int pNew_count) { - NOT_IMPLEMENTED(); +// FUNCTION: CARMA2_HW 0x00500e60 +void C2_HOOK_FASTCALL ClearMatertrialSetFromStorageSpace(tBrender_storage* pStorage_space, int pStart, int pEnd) { + int i; + int move_to; + + for (i = pStart; i < pEnd && i < pStorage_space->materials_count; i++) { + BrMaterialRemove(pStorage_space->materials[i]); + BrMaterialFree(pStorage_space->materials[i]); + RemoveMaterialFromFogification(pStorage_space->materials[i]); + } + for (move_to = pStart, i = pEnd; i < pStorage_space->materials_count; ) { + pStorage_space->materials[move_to++] = pStorage_space->materials[i++]; + } + pStorage_space->materials_count = move_to; + if (pStorage_space == &gNet_cars_storage_space) { + for (i = 0; i < gNumber_of_net_players; i++) { + tCar_spec* car = gNet_players[i].car; + if (car != NULL && car->old_material_count >= pEnd) { + car->old_material_count += pStart - pEnd; + car->new_material_count += pStart - pEnd; + } + } + } } // FUNCTION: CARMA2_HW 0x00500f30 diff --git a/src/carma2/newcommon/28-world3.h b/src/carma2/newcommon/28-world3.h index 9265531165..05c71f8bb4 100644 --- a/src/carma2/newcommon/28-world3.h +++ b/src/carma2/newcommon/28-world3.h @@ -56,7 +56,7 @@ extern void C2_HOOK_FASTCALL InitialiseStorageSpace(int pUnknown, tBrender_stora // DisposeStorageSpace -extern void C2_HOOK_FASTCALL ClearMatertrialSetFromStorageSpace(tBrender_storage* pStorage_space, int pOld_count, int pNew_count); +extern void C2_HOOK_FASTCALL ClearMatertrialSetFromStorageSpace(tBrender_storage* pStorage_space, int pStart, int pEnd); extern void C2_HOOK_FASTCALL ClearOutStorageSpace(tBrender_storage* pStorage_space); diff --git a/src/carma2/newcommon/50-fog.c b/src/carma2/newcommon/50-fog.c index d8e42f18f9..b79e51988b 100644 --- a/src/carma2/newcommon/50-fog.c +++ b/src/carma2/newcommon/50-fog.c @@ -22,5 +22,8 @@ void C2_HOOK_FASTCALL DisableAutoFogification(void) { NOT_IMPLEMENTED(); } -// RemoveMaterialFromFogification +// STUB: CARMA2_HW 0x004ea860 +void C2_HOOK_FASTCALL RemoveMaterialFromFogification(br_material* pMaterial) { + NOT_IMPLEMENTED(); +} diff --git a/src/carma2/newcommon/50-fog.h b/src/carma2/newcommon/50-fog.h index ba954d79ee..fbcaaba5ea 100644 --- a/src/carma2/newcommon/50-fog.h +++ b/src/carma2/newcommon/50-fog.h @@ -2,6 +2,7 @@ #define GUARD_50_FOG_H #include "c2_hooks.h" +#include extern void C2_HOOK_FASTCALL InitFogificateMaterials(void); @@ -15,6 +16,6 @@ extern void C2_HOOK_FASTCALL InitFogificateMaterials(void); extern void C2_HOOK_FASTCALL DisableAutoFogification(void); -// RemoveMaterialFromFogification +extern void C2_HOOK_FASTCALL RemoveMaterialFromFogification(br_material* pMaterial); #endif // GUARD_50_FOG_H From b4152d028b7e54b8c2ca38ef79830698ce016857 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 12:27:50 +0200 Subject: [PATCH 02/35] Match InitTreeSurgery --- src/carma2/newcommon/28-world3.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index 1e81c31362..dc1526731f 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -1,5 +1,6 @@ #include "28-world3.h" +#include "08-loading1.h" #include "41-utility.h" #include "50-fog.h" #include "52-errors.h" @@ -43,9 +44,31 @@ tRendererShadingType gMaterial_shading_for_callback = kRendererShadingType_Undef // PeriodicCloaking -// STUB: CARMA2_HW 0x00504b30 +// FUNCTION: CARMA2_HW 0x00504b30 void C2_HOOK_FASTCALL InitTreeSurgery(void) { - NOT_IMPLEMENTED(); + tPath_name the_path; + FILE* file; + int i; + + PathCat(the_path, gApplication_path, "TreeSurgery.TXT"); + file = PFfopen(the_path, "rt"); + if (file != NULL) { + gTree_surgery_pass1_count = GetAnInt(file); + for (i = 0; i < gTree_surgery_pass1_count; i++) { + GetAString(file, gTree_surgery_pass1[i].name); + } + gTree_surgery_pass2_count = GetAnInt(file); + for (i = 0; i < gTree_surgery_pass2_count; i++) { + GetAString(file, gTree_surgery_pass2[i].original); + GetAString(file, gTree_surgery_pass2[i].replacement); + } +#ifdef REC2_FIX_BUGS + PFfclose(file); +#endif + } else { + gTree_surgery_pass1_count = 0; + gTree_surgery_pass2_count = 0; + } } // ModelIsATree From ed808a63338f92e9879a6258e0284074a541e9ad Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 12:29:36 +0200 Subject: [PATCH 03/35] Match DisposeStorageSpace --- src/carma2/newcommon/28-world3.c | 11 ++++++++++- src/carma2/newcommon/28-world3.h | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index dc1526731f..2d6cf86bfb 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -127,7 +127,16 @@ void C2_HOOK_FASTCALL InitialiseStorageSpace(int pUnknown, tBrender_storage* pSt pStorage_space->materialProps = BrMemCalloc(pMax_materials, sizeof(br_material*), kMem_stor_space_table); } -// DisposeStorageSpace +// FUNCTION: CARMA2_HW 0x00500e10 +void C2_HOOK_FASTCALL DisposeStorageSpace(tBrender_storage* pStorage) { + + BrMemFree(pStorage->pixelmaps); + BrMemFree(pStorage->shade_tables); + BrMemFree(pStorage->materials); + BrMemFree(pStorage->models); + BrMemFree(pStorage->sounds); + BrMemFree(pStorage->materialProps); +} // FUNCTION: CARMA2_HW 0x00500e60 void C2_HOOK_FASTCALL ClearMatertrialSetFromStorageSpace(tBrender_storage* pStorage_space, int pStart, int pEnd) { diff --git a/src/carma2/newcommon/28-world3.h b/src/carma2/newcommon/28-world3.h index 05c71f8bb4..571cd8e3cc 100644 --- a/src/carma2/newcommon/28-world3.h +++ b/src/carma2/newcommon/28-world3.h @@ -54,7 +54,7 @@ extern void C2_HOOK_FASTCALL InitTreeSurgery(void); extern void C2_HOOK_FASTCALL InitialiseStorageSpace(int pUnknown, tBrender_storage* pStorage_space, int pMax_pixelmaps, int pMax_shade_tables, int pMax_materials, int pMax_models, int pMax_sounds); -// DisposeStorageSpace +extern void C2_HOOK_FASTCALL DisposeStorageSpace(tBrender_storage* pStorage); extern void C2_HOOK_FASTCALL ClearMatertrialSetFromStorageSpace(tBrender_storage* pStorage_space, int pStart, int pEnd); From 0e6e6d3b5e0ecbb8cb64aec4590397b6d2837249 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 12:32:33 +0200 Subject: [PATCH 04/35] Match LoadAllStuffInDirectory --- src/carma2/newcommon/28-world3.c | 11 ++++++++++- src/carma2/newcommon/28-world3.h | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index 2d6cf86bfb..ced930da97 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -687,11 +687,20 @@ void C2_HOOK_FASTCALL LoadAllShadeTablesInDirectory(tBrender_storage* pStorage, PFForEveryFile(pPath, LoadIfItsAShadeTable); } -// LoadAllStuffInDirectory +// FUNCTION: CARMA2_HW 0x00502cf0 +void C2_HOOK_FASTCALL LoadAllStuffInDirectory(tBrender_storage* pStorage, const char* pPath, tRendererShadingType pShading) { + + LoadAllShadeTablesInDirectory(pStorage, pPath); + LoadAllPixelmapsInDirectory(pStorage, pPath); + LoadAllImagesInDirectory(pStorage, pPath); + LoadAllMaterialsInDirectory(pStorage, pPath, pShading); + LoadAllModelsInDirectory(pStorage, pPath); +} // FUNCTION: CARMA2_HW 0x00502d60 void C2_HOOK_FASTCALL DisallowDuplicates(void) { + // empty } // FUNCTION: CARMA2_HW 0x00502d70 diff --git a/src/carma2/newcommon/28-world3.h b/src/carma2/newcommon/28-world3.h index 571cd8e3cc..575d0fbf06 100644 --- a/src/carma2/newcommon/28-world3.h +++ b/src/carma2/newcommon/28-world3.h @@ -106,11 +106,11 @@ extern void C2_HOOK_FASTCALL LoadIfItsAModel(const char* pPath); extern void C2_HOOK_FASTCALL LoadAllModelsInDirectory(tBrender_storage *pStorage, const char* pPath); -// LoadIfItsAShadeTable +extern void C2_HOOK_FASTCALL LoadIfItsAShadeTable(const char* pPath); extern void C2_HOOK_FASTCALL LoadAllShadeTablesInDirectory(tBrender_storage* pStorage, const char* pPath); -extern void C2_HOOK_FASTCALL LoadIfItsAShadeTable(const char* pPath); +extern void C2_HOOK_FASTCALL LoadAllStuffInDirectory(tBrender_storage* pStorage, const char* pPath, tRendererShadingType pShading); extern void C2_HOOK_FASTCALL DisallowDuplicates(void); From 3c49c82658e8bb9855932e394dd6a1bf32ca7b49 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 12:35:52 +0200 Subject: [PATCH 05/35] Match LoadSinglePixelmap --- src/carma2/newcommon/28-world3.c | 29 ++++++++++++++++++++++++++++- src/carma2/newcommon/28-world3.h | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index ced930da97..f983e9d148 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -349,7 +349,34 @@ int C2_HOOK_FASTCALL AddPixelmaps(tBrender_storage* pStorage_space, const char* return total; } -// LoadSinglePixelmap +// FUNCTION: CARMA2_HW 0x00501560 +br_pixelmap* C2_HOOK_FASTCALL LoadSinglePixelmap(tBrender_storage* pStorage, const char* pName) { + br_pixelmap* map; + tAdd_to_storage_result addResult; + + map = LoadPixelmap(pName); + if (map == NULL) { + return BrMapFind(pName); + } + + addResult = AddPixelmapToStorage(pStorage, map); + switch (addResult) { + case eStorage_allocated: + BrMapAdd(map); + return map; + case eStorage_duplicate: + if (gDisallow_duplicates) { + FatalError(kFatalError_DuplicatePixelmap_S, map->identifier); + } else { + BrPixelmapFree(map); + } + return gDuplicate_pixelmap; + case eStorage_not_enough_room: + FatalError(kFatalError_InsufficientPixelmapSlots); + break; + } + return NULL; +} // FUNCTION: CARMA2_HW 0x005016a0 br_pixelmap* C2_HOOK_FASTCALL LoadSingleShadeTable(tBrender_storage* pStorage_space, const char* pName) { diff --git a/src/carma2/newcommon/28-world3.h b/src/carma2/newcommon/28-world3.h index 575d0fbf06..039c61847a 100644 --- a/src/carma2/newcommon/28-world3.h +++ b/src/carma2/newcommon/28-world3.h @@ -72,7 +72,7 @@ extern tAdd_to_storage_result C2_HOOK_FASTCALL AddSoundToStorage(tBrender_storag extern int C2_HOOK_FASTCALL AddPixelmaps(tBrender_storage* pStorage_space, const char* path); -// LoadSinglePixelmap +extern br_pixelmap* C2_HOOK_FASTCALL LoadSinglePixelmap(tBrender_storage* pStorage, const char* pName); extern br_pixelmap* C2_HOOK_FASTCALL LoadSingleShadeTable(tBrender_storage* pStorage_space, const char* pName); From 37e3414e28bfb0eb6c4c020114b473e21c5a7f8f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 13:00:46 +0200 Subject: [PATCH 06/35] Implement LoadSingleMaterial --- src/carma2/newcommon/28-world3.c | 27 ++++++++++++++++++++++++++- src/carma2/newcommon/28-world3.h | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index f983e9d148..7a96c275a4 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -406,7 +406,32 @@ br_pixelmap* C2_HOOK_FASTCALL LoadSingleShadeTable(tBrender_storage* pStorage_sp return NULL; } -// LoadSingleMaterial +// FUNCTION: CARMA2_HW 0x005017e0 +br_material* C2_HOOK_FASTCALL LoadSingleMaterial(tBrender_storage* pStorage_space, const char* pName) { + br_material* material; + + material = LoadMaterial(pName); + if (material == NULL) { + return BrMaterialFind(pName); + } + + switch (AddMaterialToStorage(pStorage_space, material)) { + case eStorage_allocated: + BrMaterialAdd(material); + return material; + case eStorage_duplicate: + if (gDisallow_duplicates) { + FatalError(kFatalError_DuplicateMaterial_S, material->identifier); + } else { + BrMaterialFree(material); + } + return gDuplicate_material; + case eStorage_not_enough_room: + FatalError(kFatalError_InsufficientMaterialSlots); + return NULL; + } + +} // FUNCTION: CARMA2_HW 0x00501930 tAdd_to_storage_result C2_HOOK_FASTCALL LoadSingleSound(tBrender_storage* pStorage_space, int pSound_id) { diff --git a/src/carma2/newcommon/28-world3.h b/src/carma2/newcommon/28-world3.h index 039c61847a..08cea62e90 100644 --- a/src/carma2/newcommon/28-world3.h +++ b/src/carma2/newcommon/28-world3.h @@ -76,7 +76,7 @@ extern br_pixelmap* C2_HOOK_FASTCALL LoadSinglePixelmap(tBrender_storage* pStora extern br_pixelmap* C2_HOOK_FASTCALL LoadSingleShadeTable(tBrender_storage* pStorage_space, const char* pName); -// LoadSingleMaterial +extern br_material* C2_HOOK_FASTCALL LoadSingleMaterial(tBrender_storage* pStorage_space, const char* pName); extern tAdd_to_storage_result C2_HOOK_FASTCALL LoadSingleSound(tBrender_storage* pStorage_space, int pSound_id); From 991867729fc8c598da6567a5b86680f5b534fbb2 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 13:13:03 +0200 Subject: [PATCH 07/35] Match TurnOnCloaking and IsCarCloaked --- src/carma2/newcommon/27-powerup.c | 42 +++++++++++++++++++++++++++++++ src/carma2/newcommon/27-powerup.h | 10 ++++++++ src/carma2/newcommon/28-world3.c | 10 -------- src/carma2/newcommon/28-world3.h | 10 -------- src/carma2/newcommon/32-spark.c | 10 ++++++-- src/carma2/newcommon/32-spark.h | 5 ++-- 6 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/carma2/newcommon/27-powerup.c b/src/carma2/newcommon/27-powerup.c index 7e5dda80a8..3f05c83ba5 100644 --- a/src/carma2/newcommon/27-powerup.c +++ b/src/carma2/newcommon/27-powerup.c @@ -1,5 +1,8 @@ #include "27-powerup.h" +#include "32-spark.h" +#include "globvrpb.h" + // GLOBAL: CARMA2_HW 0x006a0ad4 const char* gPowerup_txt_path; @@ -39,6 +42,15 @@ float gMass_mutant_tail_ball; // GLOBAL: CARMA2_HW 0x0065ebbc float gMass_mine = 1.0f; +// GLOBAL: CARMA2_HW 0x006a0454 +int gCount_cloaked_cars; + +// GLOBAL: CARMA2_HW 0x006a0910 +tCar_spec* gCloaked_cars[12]; + +// GLOBAL: CARMA2_HW 0x006a0a54 +tPowerup* gPowerup_array; + // GetNextGoodyTime // DoPowerupTextHeadup @@ -433,3 +445,33 @@ void C2_HOOK_FASTCALL SetDefaultPowerupFilename(void) { gPowerup_txt_path = "POWERUP.TXT"; } +// FUNCTION: CARMA2_HW 0x004e0c40 +int C2_HOOK_FASTCALL TurnOnCloaking(tPowerup* pPowerup, tCar_spec* pCar) { + + if (gNet_mode != eNet_mode_none && !IsCarCloaked(pCar)) { + BlendifyCar(pCar); + MasterDisableCarFunks(pCar); + gCloaked_cars[gCount_cloaked_cars++] = pCar; + } + return pPowerup - gPowerup_array; +} + +// RemoveFromCloakingList + +// FUNCTION: CARMA2_HW 0x004e0d10 +int C2_HOOK_FASTCALL IsCarCloaked(tCar_spec* pCar) { + int i; + + if (gNet_mode != eNet_mode_none) { + for (i = 0; i < gCount_cloaked_cars; i++) { + if (gCloaked_cars[i] == pCar) { + return 1; + } + } + } + return 0; +} + +// TurnOffCloaking + +// PeriodicCloaking diff --git a/src/carma2/newcommon/27-powerup.h b/src/carma2/newcommon/27-powerup.h index 8c3886ce7a..b859f8558f 100644 --- a/src/carma2/newcommon/27-powerup.h +++ b/src/carma2/newcommon/27-powerup.h @@ -395,4 +395,14 @@ extern void C2_HOOK_FASTCALL RemoveTail(void); extern void C2_HOOK_FASTCALL SetDefaultPowerupFilename(void); +extern int C2_HOOK_FASTCALL TurnOnCloaking(tPowerup* pPowerup, tCar_spec* pCar); + +// RemoveFromCloakingList + +extern int C2_HOOK_FASTCALL IsCarCloaked(tCar_spec* pCar); + +// TurnOffCloaking + +// PeriodicCloaking + #endif // GUARD_27_POWERUP_H diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index 7a96c275a4..e7bdf26311 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -34,16 +34,6 @@ br_model* gDuplicate_model; // GLOBAL: CARMA2_HW 0x00660cb8 tRendererShadingType gMaterial_shading_for_callback = kRendererShadingType_Undefined; -// TurnOnCloaking - -// RemoveFromCloakingList - -// IsCarCloaked - -// TurnOffCloaking - -// PeriodicCloaking - // FUNCTION: CARMA2_HW 0x00504b30 void C2_HOOK_FASTCALL InitTreeSurgery(void) { tPath_name the_path; diff --git a/src/carma2/newcommon/28-world3.h b/src/carma2/newcommon/28-world3.h index 08cea62e90..b5f1eb4f60 100644 --- a/src/carma2/newcommon/28-world3.h +++ b/src/carma2/newcommon/28-world3.h @@ -6,16 +6,6 @@ extern br_actor* gAdditional_actors; -// TurnOnCloaking - -// RemoveFromCloakingList - -// IsCarCloaked - -// TurnOffCloaking - -// PeriodicCloaking - extern void C2_HOOK_FASTCALL InitTreeSurgery(void); // ModelIsATree diff --git a/src/carma2/newcommon/32-spark.c b/src/carma2/newcommon/32-spark.c index c650043e70..564a694017 100644 --- a/src/carma2/newcommon/32-spark.c +++ b/src/carma2/newcommon/32-spark.c @@ -53,7 +53,10 @@ int gSmoke_on = 1; // ActorFunks -// MasterDisableCarFunks +// STUB: CARMA2_HW 0x004f8ca0 +void C2_HOOK_FASTCALL MasterDisableCarFunks(tCar_spec* pCar) { + NOT_IMPLEMENTED(); +} // MasterEnableCarFunks @@ -211,7 +214,10 @@ int C2_HOOK_FASTCALL GetSmokeOn(void) { // BlendifyMaterialCB -// BlendifyCar +// STUB: CARMA2_HW 0x004fecf0 +void C2_HOOK_FASTCALL BlendifyCar(tCar_spec* pCar) { + NOT_IMPLEMENTED(); +} // UnBlendifyMaterialCB diff --git a/src/carma2/newcommon/32-spark.h b/src/carma2/newcommon/32-spark.h index 0a0e8b8781..62b9939bb1 100644 --- a/src/carma2/newcommon/32-spark.h +++ b/src/carma2/newcommon/32-spark.h @@ -2,6 +2,7 @@ #define GUARD_32_SPARK_H #include "c2_hooks.h" +#include "rec2_types.h" // DrawDot @@ -53,7 +54,7 @@ // ActorFunks -// MasterDisableCarFunks +extern void C2_HOOK_FASTCALL MasterDisableCarFunks(tCar_spec* pCar); // MasterEnableCarFunks @@ -197,7 +198,7 @@ extern int C2_HOOK_FASTCALL GetSmokeOn(void); // BlendifyMaterialCB -// BlendifyCar +extern void C2_HOOK_FASTCALL BlendifyCar(tCar_spec* pCar); // UnBlendifyMaterialCB From fb3d9a6148968fe70dd12aeb60191b289e6a3fa9 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 13:28:45 +0200 Subject: [PATCH 08/35] Match RemoveFromCloakingList and RemoveFromCloakingList --- src/carma2/newcommon/27-powerup.c | 34 +++++++++++++++++++++++++++++-- src/carma2/newcommon/27-powerup.h | 4 ++-- src/carma2/newcommon/32-spark.c | 15 +++++++++++--- src/carma2/newcommon/32-spark.h | 6 +++--- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/carma2/newcommon/27-powerup.c b/src/carma2/newcommon/27-powerup.c index 3f05c83ba5..f19fd2d604 100644 --- a/src/carma2/newcommon/27-powerup.c +++ b/src/carma2/newcommon/27-powerup.c @@ -2,6 +2,9 @@ #include "32-spark.h" #include "globvrpb.h" +#include "rec2_macros.h" + +#include "c2_string.h" // GLOBAL: CARMA2_HW 0x006a0ad4 const char* gPowerup_txt_path; @@ -456,7 +459,25 @@ int C2_HOOK_FASTCALL TurnOnCloaking(tPowerup* pPowerup, tCar_spec* pCar) { return pPowerup - gPowerup_array; } -// RemoveFromCloakingList +// FUNCTION: CARMA2_HW 0x004e0cb0 +void C2_HOOK_FASTCALL RemoveFromCloakingList(tCar_spec* pCar) { + int i; + + if (gNet_mode != eNet_mode_none) { + for (i = 0; i < gCount_cloaked_cars; i++) { + + if (gCloaked_cars[i] == pCar) { +#ifdef REC2_FIX_BUGS + memmove(&gCloaked_cars[i], &gCloaked_cars[i + 1], (gCount_cloaked_cars - i - 1) * sizeof(tCar_spec*)); +#else + memcpy(&gCloaked_cars[i], &gCloaked_cars[i + 1], (REC2_ASIZE(gCloaked_cars) - i - 1) * sizeof(tCar_spec*)); +#endif + gCount_cloaked_cars -= 1; + break; + } + } + } +} // FUNCTION: CARMA2_HW 0x004e0d10 int C2_HOOK_FASTCALL IsCarCloaked(tCar_spec* pCar) { @@ -472,6 +493,15 @@ int C2_HOOK_FASTCALL IsCarCloaked(tCar_spec* pCar) { return 0; } -// TurnOffCloaking +// FUNCTION: CARMA2_HW 0x004e0d50 +void C2_HOOK_FASTCALL TurnOffCloaking(tPowerup* pPowerup, tCar_spec* pCar) { + + if (gNet_mode != eNet_mode_none) { + UnBlendifyCar(pCar); + RemoveFromCloakingList(pCar); + MasterEnableCarFunks(pCar); + RestoreCarPixelmaps(pCar); + } +} // PeriodicCloaking diff --git a/src/carma2/newcommon/27-powerup.h b/src/carma2/newcommon/27-powerup.h index b859f8558f..782179200f 100644 --- a/src/carma2/newcommon/27-powerup.h +++ b/src/carma2/newcommon/27-powerup.h @@ -397,11 +397,11 @@ extern void C2_HOOK_FASTCALL SetDefaultPowerupFilename(void); extern int C2_HOOK_FASTCALL TurnOnCloaking(tPowerup* pPowerup, tCar_spec* pCar); -// RemoveFromCloakingList +extern void C2_HOOK_FASTCALL RemoveFromCloakingList(tCar_spec* pCar); extern int C2_HOOK_FASTCALL IsCarCloaked(tCar_spec* pCar); -// TurnOffCloaking +extern void C2_HOOK_FASTCALL TurnOffCloaking(tPowerup* pPowerup, tCar_spec* pCar); // PeriodicCloaking diff --git a/src/carma2/newcommon/32-spark.c b/src/carma2/newcommon/32-spark.c index 564a694017..5b462adcf2 100644 --- a/src/carma2/newcommon/32-spark.c +++ b/src/carma2/newcommon/32-spark.c @@ -58,7 +58,10 @@ void C2_HOOK_FASTCALL MasterDisableCarFunks(tCar_spec* pCar) { NOT_IMPLEMENTED(); } -// MasterEnableCarFunks +// STUB: CARMA2_HW 0x004f8e10 +void C2_HOOK_FASTCALL MasterEnableCarFunks(tCar_spec* pCar) { + NOT_IMPLEMENTED(); +} // SetPixelmap @@ -82,7 +85,10 @@ void C2_HOOK_FASTCALL MasterDisableCarFunks(tCar_spec* pCar) { // RestorePixelmap -// RestoreCarPixelmaps +// STUB: CARMA2_HW 0x004f9620 +void C2_HOOK_FASTCALL RestoreCarPixelmaps(tCar_spec* pCar_spec) { + NOT_IMPLEMENTED(); +} // MungeShrapnel @@ -221,7 +227,10 @@ void C2_HOOK_FASTCALL BlendifyCar(tCar_spec* pCar) { // UnBlendifyMaterialCB -// UnBlendifyCar +// STUB: CARMA2_HW 0x004fed40 +void C2_HOOK_FASTCALL UnBlendifyCar(tCar_spec* pCar_spec) { + NOT_IMPLEMENTED(); +} // IsCarSmoking diff --git a/src/carma2/newcommon/32-spark.h b/src/carma2/newcommon/32-spark.h index 62b9939bb1..c801d88498 100644 --- a/src/carma2/newcommon/32-spark.h +++ b/src/carma2/newcommon/32-spark.h @@ -56,7 +56,7 @@ extern void C2_HOOK_FASTCALL MasterDisableCarFunks(tCar_spec* pCar); -// MasterEnableCarFunks +extern void C2_HOOK_FASTCALL MasterEnableCarFunks(tCar_spec* pCar_spec); // SetPixelmap @@ -80,7 +80,7 @@ extern void C2_HOOK_FASTCALL MasterDisableCarFunks(tCar_spec* pCar); // RestorePixelmap -// RestoreCarPixelmaps +extern void C2_HOOK_FASTCALL RestoreCarPixelmaps(tCar_spec* pCar); // MungeShrapnel @@ -202,7 +202,7 @@ extern void C2_HOOK_FASTCALL BlendifyCar(tCar_spec* pCar); // UnBlendifyMaterialCB -// UnBlendifyCar +extern void C2_HOOK_FASTCALL UnBlendifyCar(tCar_spec* pCar); // IsCarSmoking From daf74ea51a3ab963fba217d8c79847d8a155cd29 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 13:33:56 +0200 Subject: [PATCH 09/35] Match PeriodicCloaking --- src/carma2/newcommon/27-powerup.c | 12 +++++++++++- src/carma2/newcommon/32-spark.c | 5 ++++- src/carma2/newcommon/32-spark.h | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/carma2/newcommon/27-powerup.c b/src/carma2/newcommon/27-powerup.c index f19fd2d604..7d7dbd6e04 100644 --- a/src/carma2/newcommon/27-powerup.c +++ b/src/carma2/newcommon/27-powerup.c @@ -504,4 +504,14 @@ void C2_HOOK_FASTCALL TurnOffCloaking(tPowerup* pPowerup, tCar_spec* pCar) { } } -// PeriodicCloaking +// FUNCTION: CARMA2_HW 0x004e0de0 +void C2_HOOK_FASTCALL PeriodicCloaking(void) { + int i; + + if (gNet_mode != eNet_mode_none) { + + for (i = 0; i < gCount_cloaked_cars; i++) { + DoCamouflageThing(gCloaked_cars[i]); + } + } +} diff --git a/src/carma2/newcommon/32-spark.c b/src/carma2/newcommon/32-spark.c index 5b462adcf2..7b9eb9072c 100644 --- a/src/carma2/newcommon/32-spark.c +++ b/src/carma2/newcommon/32-spark.c @@ -65,7 +65,10 @@ void C2_HOOK_FASTCALL MasterEnableCarFunks(tCar_spec* pCar) { // SetPixelmap -// DoCamouflageThing +// STUB: CARMA2_HW 0x004f8f30 +void C2_HOOK_FASTCALL DoCamouflageThing(tCar_spec* pCar) { + NOT_IMPLEMENTED(); +} // DoSolidGraniteThing diff --git a/src/carma2/newcommon/32-spark.h b/src/carma2/newcommon/32-spark.h index c801d88498..42686ffd83 100644 --- a/src/carma2/newcommon/32-spark.h +++ b/src/carma2/newcommon/32-spark.h @@ -60,7 +60,7 @@ extern void C2_HOOK_FASTCALL MasterEnableCarFunks(tCar_spec* pCar_spec); // SetPixelmap -// DoCamouflageThing +extern void C2_HOOK_FASTCALL DoCamouflageThing(tCar_spec* pCar); // DoSolidGraniteThing From 6332744897d8fc46510ca8f169b77cae5484246d Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 13:48:56 +0200 Subject: [PATCH 10/35] Implement CreateBillBoard --- src/carma2/newcommon/27-powerup.c | 51 ++++++++++++++++++++++++++++++- src/carma2/newcommon/27-powerup.h | 2 +- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/27-powerup.c b/src/carma2/newcommon/27-powerup.c index 7d7dbd6e04..a161397126 100644 --- a/src/carma2/newcommon/27-powerup.c +++ b/src/carma2/newcommon/27-powerup.c @@ -441,7 +441,56 @@ void C2_HOOK_FASTCALL RemoveTail(void) { // PrintPowerupIconIn3D -// CreateBillBoard +// FUNCTION: CARMA2_HW 0x004e09d0 +br_actor* C2_HOOK_FASTCALL CreateBillBoard(br_pixelmap* pTexture) { + br_actor* actor; + br_material* material; + br_model* model; + int width; + int height; + br_scalar left; + br_scalar right; + br_scalar top; + br_scalar bottom; + + width = pTexture->width; + height = pTexture->height; + model = BrModelAllocate("Billboard Model", 4, 2); + material = BrMaterialAllocate("Billboard Material"); + actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); + actor->identifier = "Billboard Actor"; + actor->model = model; + actor->material = material; + actor->render_style = BR_RSTYLE_FACES; + model->faces[0].vertices[0] = 0; + model->faces[0].vertices[1] = 1; + model->faces[0].vertices[2] = 2; + model->faces[1].vertices[0] = 2; + model->faces[1].vertices[1] = 3; + model->faces[1].vertices[2] = 0; + model->faces[0].material = NULL; + model->faces[1].material = NULL; + left = (float)-(width / 2); + top = (float)+(height / 2); + BrVector3Set(&model->vertices[0].p, left, top, -2.0f); + bottom = (float)-(height / 2); + BrVector3Set(&model->vertices[1].p, left, bottom, -2.0f); + right = (float)+(width / 2); + BrVector3Set(&model->vertices[2].p, right, bottom, -2.0f); + BrVector3Set(&model->vertices[3].p, right, top, -2.0f); + BrVector2Set(&model->vertices[0].map, 0.0f, 0.0f); + BrVector2Set(&model->vertices[1].map, 0.0f, 1.0f); + BrVector2Set(&model->vertices[2].map, 1.0f, 1.0f); + BrVector2Set(&model->vertices[3].map, 1.0f, 0.0f); + material->colour = 0; + material->colour_map = pTexture; + material->flags = BR_MATF_ALWAYS_VISIBLE | BR_MATF_FORCE_FRONT; + model->flags |= BR_MODF_KEEP_ORIGINAL; + BrMapAdd(pTexture); + BrMaterialAdd(material); + BrModelAdd(model); + return actor; +} // FUNCTION: CARMA2_HW 0x004e0c00 void C2_HOOK_FASTCALL SetDefaultPowerupFilename(void) { diff --git a/src/carma2/newcommon/27-powerup.h b/src/carma2/newcommon/27-powerup.h index 782179200f..0cafb03338 100644 --- a/src/carma2/newcommon/27-powerup.h +++ b/src/carma2/newcommon/27-powerup.h @@ -391,7 +391,7 @@ extern void C2_HOOK_FASTCALL RemoveTail(void); // PrintPowerupIconIn3D -// CreateBillBoard +extern br_actor* C2_HOOK_FASTCALL CreateBillBoard(br_pixelmap* pTexture); extern void C2_HOOK_FASTCALL SetDefaultPowerupFilename(void); From c13c6ee7fda2d172ba28b2a717ebbd91ce3bfc10 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 14:44:04 +0200 Subject: [PATCH 11/35] Implement PrintPowerupIconIn3D --- src/carma2/newcommon/16-graphics1.c | 5 +++- src/carma2/newcommon/16-graphics1.h | 2 +- src/carma2/newcommon/27-powerup.c | 40 ++++++++++++++++++++++++++++- src/carma2/newcommon/27-powerup.h | 2 +- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/16-graphics1.c b/src/carma2/newcommon/16-graphics1.c index 31e7e3ac92..5cb1bb538c 100644 --- a/src/carma2/newcommon/16-graphics1.c +++ b/src/carma2/newcommon/16-graphics1.c @@ -182,7 +182,10 @@ void C2_HOOK_FASTCALL InitWobbleStuff(void) { // StartRenderingHeadups -// RenderThisHeadup +// STUB: CARMA2_HW 0x004e5ad0 +void C2_HOOK_FASTCALL RenderThisHeadup(br_actor* pActor) { + NOT_IMPLEMENTED(); +} // StopRenderingHeadups diff --git a/src/carma2/newcommon/16-graphics1.h b/src/carma2/newcommon/16-graphics1.h index 5ef255f794..110ee454df 100644 --- a/src/carma2/newcommon/16-graphics1.h +++ b/src/carma2/newcommon/16-graphics1.h @@ -74,7 +74,7 @@ extern void C2_HOOK_FASTCALL InitWobbleStuff(void); // StartRenderingHeadups -// RenderThisHeadup +extern void C2_HOOK_FASTCALL RenderThisHeadup(br_actor* pActor); // StopRenderingHeadups diff --git a/src/carma2/newcommon/27-powerup.c b/src/carma2/newcommon/27-powerup.c index a161397126..74fc0d8a98 100644 --- a/src/carma2/newcommon/27-powerup.c +++ b/src/carma2/newcommon/27-powerup.c @@ -1,5 +1,6 @@ #include "27-powerup.h" +#include "16-graphics1.h" #include "32-spark.h" #include "globvrpb.h" #include "rec2_macros.h" @@ -439,7 +440,44 @@ void C2_HOOK_FASTCALL RemoveTail(void) { // ARUndoPowerupRespawn -// PrintPowerupIconIn3D +// FUNCTION: CARMA2_HW 0x004e07f0 +void C2_HOOK_FASTCALL PrintPowerupIconIn3D(int pX, int pY, tHeadup_icon* pIcon, tPowerup* pPowerup, int pScale, tU32 pTime) { + float f; + float scale; + br_fixed_ls prev_opacity; + + if (pIcon == NULL) { + pPowerup->icon_actor->render_style = BR_RSTYLE_FACES; + BrVector3Set(&pIcon->icon_actor->t.t.translate.t, (float)pX + 16.0f, (float)-(pY + 16), 0.0f); + RenderThisHeadup(pIcon->icon_actor); + return; + } + if (pIcon->icon_actor != NULL) { + pIcon->icon_actor->render_style = BR_RSTYLE_FACES; + if (pScale != 0) { + f = (float)(pTime - pIcon->fizzle_start) / 600.0f; + if (pIcon->fizzle_direction > 0) { + f = 1.0f - f; + scale = 1.0f + 5.0f * f; + BrMatrix34Scale(&pIcon->icon_actor->t.t.mat, scale, scale, 1.0f); + } else { + BrMatrix34Scale(&pIcon->icon_actor->t.t.mat, 1.01f - f, 1.01f - f, 1.0f); + } + BrMatrix34PostRotateZ(&pIcon->icon_actor->t.t.mat, (br_angle)((1.0f - f / 2.0f) * 65536.0f)); + pIcon->icon_actor->material->extra_prim[1].v.x = BR_FIXED_INT((1.0f - f) * 255.0f); + BrMaterialUpdate(pIcon->icon_actor->material, BR_MATU_EXTRA_PRIM); + } else { + prev_opacity = pIcon->icon_actor->material->extra_prim[1].v.x; + pIcon->icon_actor->material->extra_prim[1].v.x = BR_FIXED_INT(255); + if (prev_opacity != pIcon->icon_actor->material->extra_prim[1].v.x) { + BrMaterialUpdate(pIcon->icon_actor->material, BR_MATU_EXTRA_PRIM); + } + BrMatrix34Identity(&pIcon->icon_actor->t.t.mat); + } + BrVector3Set(&pIcon->icon_actor->t.t.translate.t, (float)pX + 16.0f, (float)-(pY + 16), 0.0f); + RenderThisHeadup(pIcon->icon_actor); + } +} // FUNCTION: CARMA2_HW 0x004e09d0 br_actor* C2_HOOK_FASTCALL CreateBillBoard(br_pixelmap* pTexture) { diff --git a/src/carma2/newcommon/27-powerup.h b/src/carma2/newcommon/27-powerup.h index 0cafb03338..77efe93c33 100644 --- a/src/carma2/newcommon/27-powerup.h +++ b/src/carma2/newcommon/27-powerup.h @@ -389,7 +389,7 @@ extern void C2_HOOK_FASTCALL RemoveTail(void); // ARUndoPowerupRespawn -// PrintPowerupIconIn3D +extern void C2_HOOK_FASTCALL PrintPowerupIconIn3D(int pX, int pY, tHeadup_icon* pIcon, tPowerup* pPowerup, int pScale, tU32 pTime); extern br_actor* C2_HOOK_FASTCALL CreateBillBoard(br_pixelmap* pTexture); From 9839962ed70f45081b789459e384ab45ba640903 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 15:33:57 +0200 Subject: [PATCH 12/35] Match InitialiseExtraRendersk & AddExtraRender --- src/carma2/newcommon/17-world2.c | 20 ++++++++++++++++++-- src/carma2/newcommon/17-world2.h | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 9d655bda93..0aeae4db56 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -20,9 +20,25 @@ int gCar_simplification_level; // GLOBAL: CARMA2_HW 0x00591368 int gRendering_accessories = 1; -// InitialiseExtraRenders +// GLOBAL: CARMA2_HW 0x006a22c0 +int gCount_extra_renders; -// AddExtraRender +// GLOBAL: CARMA2_HW 0x006a22c8 +tExtra_render gExtra_renders[6]; + +// FUNCTION: CARMA2_HW 0x004e5cb0 +void C2_HOOK_FASTCALL InitialiseExtraRenders(void) { + + gCount_extra_renders = 0; +} + +// FUNCTION: CARMA2_HW 0x004e5cc0 +void C2_HOOK_FASTCALL AddExtraRender(br_actor* pActor, br_material* pMaterial) { + + gExtra_renders[gCount_extra_renders].actor = pActor; + gExtra_renders[gCount_extra_renders].material = pMaterial; + gCount_extra_renders += 1; +} // PointOutOfSight diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index e4133c52f7..d73c21441f 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -4,9 +4,9 @@ #include "c2_hooks.h" #include "rec2_types.h" -// InitialiseExtraRenders +extern void C2_HOOK_FASTCALL InitialiseExtraRenders(void); -// AddExtraRender +extern void C2_HOOK_FASTCALL AddExtraRender(br_actor* pActor, br_material* pMaterial); // PointOutOfSight From ad6856cdd6ca69434925b92a5c41570f3ce2c509 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 15:56:38 +0200 Subject: [PATCH 13/35] Match PointOutOfSight --- src/carma2/newcommon/17-world2.c | 42 +++++++++++++++++++++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 0aeae4db56..d1971baa7a 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -2,6 +2,7 @@ #include "41-utility.h" #include "globvars.h" +#include "rec2_macros.h" #include "c2_string.h" @@ -26,6 +27,9 @@ int gCount_extra_renders; // GLOBAL: CARMA2_HW 0x006a22c8 tExtra_render gExtra_renders[6]; +// GLOBAL: CARMA2_HW 0x00704e40 +int gMirror_on__graphics; + // FUNCTION: CARMA2_HW 0x004e5cb0 void C2_HOOK_FASTCALL InitialiseExtraRenders(void) { @@ -40,7 +44,43 @@ void C2_HOOK_FASTCALL AddExtraRender(br_actor* pActor, br_material* pMaterial) { gCount_extra_renders += 1; } -// PointOutOfSight +// FUNCTION: CARMA2_HW 0x004e5ce0 +int C2_HOOK_FASTCALL PointOutOfSight(const br_vector3* pPoint, undefined4 pArg2, br_scalar pMax_distance) { + br_vector3 distance_vector; + int i; + +#define CAMERA_MAX_DISTANCE(A) ((pMax_distance != 0.f) ? pMax_distance : REC2_SQR(((br_camera*)(A)->type_data)->yon_z)) + + if (gMirror_on__graphics) { + BrVector3Sub(&distance_vector, pPoint, (br_vector3*)gRearview_camera_to_world.m[3]); + if (BrVector3LengthSquared(&distance_vector) < CAMERA_MAX_DISTANCE(gRearview_camera) + && BrVector3Dot(&distance_vector, (br_vector3*)gRearview_camera_to_world.m[2]) < 0.f) { + + return 0; + } + } + + for (i = 0; i < gCount_extra_renders; i++) { + br_actor* a = gExtra_renders[i].actor; + + BrVector3Sub(&distance_vector, pPoint, &a->t.t.translate.t); + if (BrVector3LengthSquared(&distance_vector) < CAMERA_MAX_DISTANCE(a)) { + + return 0; + } + } + + BrVector3Sub(&distance_vector, pPoint, (br_vector3*)gCamera_to_world.m[3]); + if (BrVector3LengthSquared(&distance_vector) >= CAMERA_MAX_DISTANCE(gCamera)) { + return 1; + } + if (BrVector3Dot(&distance_vector, (br_vector3*)gCamera_to_world.m[2]) >= 0.f) { + + return 1; + } +#undef CAMERA_MAX_DISTANCE + return 0; +} // CancelificateClipulatingPlaneyThings diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index d73c21441f..ce6ec3d968 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -8,7 +8,7 @@ extern void C2_HOOK_FASTCALL InitialiseExtraRenders(void); extern void C2_HOOK_FASTCALL AddExtraRender(br_actor* pActor, br_material* pMaterial); -// PointOutOfSight +extern int C2_HOOK_FASTCALL PointOutOfSight(const br_vector3* pPoint, undefined4 pArg2, br_scalar pMax_distance); // CancelificateClipulatingPlaneyThings From 863635f8b9c47b25df8ff3c201c64764dcd73e9e Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 15:58:33 +0200 Subject: [PATCH 14/35] Match UnsuffixedMaterial --- src/carma2/newcommon/17-world2.c | 16 ++++++++++++++-- src/carma2/newcommon/17-world2.h | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index d1971baa7a..b3e700a807 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -246,7 +246,7 @@ tCar_texturing_level C2_HOOK_FASTCALL GetCarTexturingLevel(void) { } // FUNCTION: CARMA2_HW 0x00448ce0 -int C2_HOOK_FASTCALL HasThisSuffix(char* pIdent, char* pSuffix) { +int C2_HOOK_FASTCALL HasThisSuffix(const char* pIdent, const char* pSuffix) { size_t len_ident; size_t len_suffix; @@ -261,7 +261,19 @@ int C2_HOOK_FASTCALL HasThisSuffix(char* pIdent, char* pSuffix) { return strcmp(pIdent + len_ident - len_suffix, pSuffix) == 0; } -// UnsuffixedMaterial +// FUNCTION: CARMA2_HW 0x00448d70 +br_material* C2_HOOK_FASTCALL UnsuffixedMaterial(const char* pOld_ident, const char* pSuffix) { + br_material* result; + int unsuffixed_len; + char* new_id; + + unsuffixed_len = strlen(pOld_ident) - strlen(pSuffix); + new_id = BrMemAllocate(unsuffixed_len + 1, kMem_new_mat_id); + sprintf(new_id, "%.*s", unsuffixed_len, pOld_ident); + result = BrMaterialFind(new_id); + BrMemFree(new_id); + return result; +} // RoadUntexToPersp diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index ce6ec3d968..cd29e6b3e6 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -38,9 +38,9 @@ extern tCar_texturing_level C2_HOOK_FASTCALL GetCarTexturingLevel(void); extern void C2_HOOK_FASTCALL SetCarTexturingLevel(tCar_texturing_level pLevel); -extern int C2_HOOK_FASTCALL HasThisSuffix(char* pIdent, char* pSuffix); +extern int C2_HOOK_FASTCALL HasThisSuffix(const char* pIdent, const char* pSuffix); -// UnsuffixedMaterial +extern br_material* C2_HOOK_FASTCALL UnsuffixedMaterial(const char* pOld_ident, const char* pSuffix); // RoadUntexToPersp From e4b0310a11e7ae8142a6d6293578ec0878c1fcd0 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 16:01:21 +0200 Subject: [PATCH 15/35] Match RoadUntexToPersp --- src/carma2/newcommon/17-world2.c | 14 +++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index b3e700a807..7feda3b11a 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -275,7 +275,19 @@ br_material* C2_HOOK_FASTCALL UnsuffixedMaterial(const char* pOld_ident, const c return result; } -// RoadUntexToPersp +// FUNCTION: CARMA2_HW 0x00447c60 +br_material* C2_HOOK_FASTCALL RoadUntexToPersp(br_model* pModel, tU16 pFace) { + br_material* old_mat; + br_material* new_mat; + + old_mat = pModel->faces[pFace].material; + if (HasThisSuffix(old_mat->identifier, ".road")) { + new_mat = UnsuffixedMaterial(old_mat->identifier, ".road"); + } else { + new_mat = NULL; + } + return new_mat; +} // WallUntexToPersp diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index cd29e6b3e6..faff9176db 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -42,7 +42,7 @@ extern int C2_HOOK_FASTCALL HasThisSuffix(const char* pIdent, const char* pSuffi extern br_material* C2_HOOK_FASTCALL UnsuffixedMaterial(const char* pOld_ident, const char* pSuffix); -// RoadUntexToPersp +extern br_material* C2_HOOK_FASTCALL RoadUntexToPersp(br_model* pModel, tU16 pFace); // WallUntexToPersp From 13225cc09bcebb15924716e3845e47ef3ef50c8c Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 16:07:45 +0200 Subject: [PATCH 16/35] Implement WallUntexToPersp --- src/carma2/newcommon/17-world2.c | 16 +++++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 7feda3b11a..6c71e4b88d 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -289,7 +289,21 @@ br_material* C2_HOOK_FASTCALL RoadUntexToPersp(br_model* pModel, tU16 pFace) { return new_mat; } -// WallUntexToPersp +// FUNCTION: CARMA2_HW 0x004481d0 +br_material* C2_HOOK_FASTCALL WallUntexToPersp(br_model* pModel, tU16 pFace) { + br_material* old_mat; + br_material* new_mat; + + old_mat = pModel->faces[pFace].material; + if (HasThisSuffix(old_mat->identifier, ".lwall")) { + new_mat = UnsuffixedMaterial(old_mat->identifier, ".lwall"); + } else if (HasThisSuffix(old_mat->identifier, ".pwall")) { + new_mat = UnsuffixedMaterial(old_mat->identifier, ".pwall"); + } else { + new_mat = NULL; + } + return new_mat; +} // WallLinearToPersp diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index faff9176db..065c0d6a16 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -44,7 +44,7 @@ extern br_material* C2_HOOK_FASTCALL UnsuffixedMaterial(const char* pOld_ident, extern br_material* C2_HOOK_FASTCALL RoadUntexToPersp(br_model* pModel, tU16 pFace); -// WallUntexToPersp +extern br_material* C2_HOOK_FASTCALL WallUntexToPersp(br_model* pModel, tU16 pFace); // WallLinearToPersp From 4d8a5f7bf7b2aead29b1bd2c9061eb6165ae2465 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 16:09:55 +0200 Subject: [PATCH 17/35] Implement WallLinearToPersp --- src/carma2/newcommon/17-world2.c | 14 +++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 6c71e4b88d..67e4c271bc 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -305,7 +305,19 @@ br_material* C2_HOOK_FASTCALL WallUntexToPersp(br_model* pModel, tU16 pFace) { return new_mat; } -// WallLinearToPersp +// FUNCTION: CARMA2_HW 0x00448390 +br_material* C2_HOOK_FASTCALL WallLinearToPersp(br_model* pModel, tU16 pFace) { + br_material* old_mat; + br_material* new_mat; + + old_mat = pModel->faces[pFace].material; + if (HasThisSuffix(old_mat->identifier, ".pwall")) { + new_mat = UnsuffixedMaterial(old_mat->identifier, ".pwall"); + } else { + new_mat = NULL; + } + return new_mat; +} // GetRoadTexturingLevel diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index 065c0d6a16..c41fdbb0bd 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -46,7 +46,7 @@ extern br_material* C2_HOOK_FASTCALL RoadUntexToPersp(br_model* pModel, tU16 pFa extern br_material* C2_HOOK_FASTCALL WallUntexToPersp(br_model* pModel, tU16 pFace); -// WallLinearToPersp +extern br_material* C2_HOOK_FASTCALL WallLinearToPersp(br_model* pModel, tU16 pFace); // GetRoadTexturingLevel From 16c03a8f66827382e9cccfa0b349093c4605cbaa Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 16:11:35 +0200 Subject: [PATCH 18/35] Match GetRoadTexturingLevel --- src/carma2/newcommon/17-world2.c | 6 +++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 67e4c271bc..70b4d371f2 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -319,7 +319,11 @@ br_material* C2_HOOK_FASTCALL WallLinearToPersp(br_model* pModel, tU16 pFace) { return new_mat; } -// GetRoadTexturingLevel +// FUNCTION: CARMA2_HW 0x00448770 +tRoad_texturing_level C2_HOOK_FASTCALL GetRoadTexturingLevel(void) { + + return gRoad_texturing_level; +} // FUNCTION: CARMA2_HW 0x00448780 void C2_HOOK_FASTCALL SetRoadTexturingLevel(tRoad_texturing_level pLevel) { diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index c41fdbb0bd..fb58155371 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -48,7 +48,7 @@ extern br_material* C2_HOOK_FASTCALL WallUntexToPersp(br_model* pModel, tU16 pFa extern br_material* C2_HOOK_FASTCALL WallLinearToPersp(br_model* pModel, tU16 pFace); -// GetRoadTexturingLevel +extern tRoad_texturing_level C2_HOOK_FASTCALL GetRoadTexturingLevel(void); extern void C2_HOOK_FASTCALL SetRoadTexturingLevel(tRoad_texturing_level pLevel); From 37d75b5fe78b60849cb9229f4e0d6ee224c8d14f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 16:16:00 +0200 Subject: [PATCH 19/35] Match DisposeSuffixedMaterials --- src/carma2/newcommon/17-world2.c | 38 +++++++++++++++++++++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 70b4d371f2..a23e823e4b 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -339,7 +339,43 @@ void C2_HOOK_FASTCALL SetWallTexturingLevel(tWall_texturing_level pLevel) { gWall_texturing_level = pLevel; } -// DisposeSuffixedMaterials +// FUNCTION: CARMA2_HW 0x00448dd0 +br_material* C2_HOOK_FASTCALL DisposeSuffixedMaterials(br_model* pModel, tU16 pFace) { + size_t max_suffix_len; + br_material* mat; + br_material* victim; + // GLOBAL: CARMA2_HW 0x005913a0 + static const char* suffixes[3] = { + ".road", + ".pwall", + ".lwall", + }; + int s; + char* id; + + mat = pModel->faces[pFace].material; + if (mat->identifier != NULL) { + max_suffix_len = 0; + for (s = 0; s < REC2_ASIZE(suffixes); s++) { + if (max_suffix_len < strlen(suffixes[s])) { + max_suffix_len = strlen(suffixes[s]); + } + } + id = BrMemAllocate(strlen(mat->identifier) + max_suffix_len + 1, kMem_new_mat_id); + for (s = 0; s < REC2_ASIZE(suffixes); s++) { + sprintf(id, "%s%s", mat->identifier, suffixes[s]); + victim = BrMaterialFind(id); + if (victim != NULL) { + BrMaterialRemove(victim); + BrMaterialFree(victim); + } + } +#ifdef REC2_FIX_BUGS + BrMemFree(id); +#endif + } + return NULL; +} // DisposeTexturingMaterials diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index fb58155371..beebd54cc2 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -56,7 +56,7 @@ extern void C2_HOOK_FASTCALL SetRoadTexturingLevel(tRoad_texturing_level pLevel) extern void C2_HOOK_FASTCALL SetWallTexturingLevel(tWall_texturing_level pLevel); -// DisposeSuffixedMaterials +extern br_material* C2_HOOK_FASTCALL DisposeSuffixedMaterials(br_model* pModel, tU16 pFace); // DisposeTexturingMaterials From b3e1bd6a0b5e9595c96176aab8e366303ac6de93 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 16:36:39 +0200 Subject: [PATCH 20/35] Match ProcessFaceMaterials --- src/carma2/newcommon/17-world2.c | 35 ++++++++++++++++++++++++++++++-- src/carma2/newcommon/17-world2.h | 4 ++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index a23e823e4b..1830fa10ca 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -86,11 +86,42 @@ int C2_HOOK_FASTCALL PointOutOfSight(const br_vector3* pPoint, undefined4 pArg2, // FixificateClipulatingPlaneyThings -// ProcessModelFaceMaterials +void C2_HOOK_FASTCALL ProcessModelFaceMaterials(br_model* pModel, tPMFMCB* pCallback) { + tU16 f; + br_material* possible_mat; + br_material* new_mat = NULL; + + for (f = 0; f < pModel->nfaces; f++) { + + if (pModel->faces[f].material == NULL) { + continue; + } + possible_mat = pCallback(pModel, f); + if (possible_mat == NULL) { + continue; + } + pModel->faces[f].material = possible_mat; + new_mat = possible_mat; + } + if (new_mat != NULL) { + BrModelUpdate(pModel, BR_MODU_ALL); + } +} // ProcessModelFaceMaterials2 -// ProcessFaceMaterials +// FUNCTION: CARMA2_HW 0x00448850 +intptr_t C2_HOOK_CDECL ProcessFaceMaterials(br_actor* pActor, void* pData) { + tPMFMCB* callback = pData; + + if (pActor->identifier != NULL && pActor->identifier[0] == '&') { + return 0; + } + if (pActor->type == BR_ACTOR_MODEL && pActor->model != NULL) { + ProcessModelFaceMaterials(pActor->model, callback); + } + return BrActorEnum(pActor, ProcessFaceMaterials, pData); +} // FUNCTION: CARMA2_HW 0x004475c0 int C2_HOOK_FASTCALL DRPixelmapHasZeros(br_pixelmap* pm) { diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index beebd54cc2..b974e5c912 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -14,11 +14,11 @@ extern int C2_HOOK_FASTCALL PointOutOfSight(const br_vector3* pPoint, undefined4 // FixificateClipulatingPlaneyThings -// ProcessModelFaceMaterials +extern void C2_HOOK_FASTCALL ProcessModelFaceMaterials(br_model* pModel, tPMFMCB* pCallback); // ProcessModelFaceMaterials2 -// ProcessFaceMaterials +extern intptr_t C2_HOOK_CDECL ProcessFaceMaterials(br_actor* pActor, void* pData); extern int C2_HOOK_FASTCALL DRPixelmapHasZeros(br_pixelmap* pm); From c2f2aaf6d008348bd0dc94d01917984e0a703c73 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 18:59:11 +0200 Subject: [PATCH 21/35] Match FixificateClipulatingPlaneyThings & CancelificateClipulatingPlaneyThings --- src/carma2/newcommon/17-world2.c | 12 ++++++++++-- src/carma2/newcommon/17-world2.h | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 1830fa10ca..6479fd2ea4 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -82,9 +82,17 @@ int C2_HOOK_FASTCALL PointOutOfSight(const br_vector3* pPoint, undefined4 pArg2, return 0; } -// CancelificateClipulatingPlaneyThings +// FUNCTION: CARMA2_HW 0x004e5ef0 +void C2_HOOK_FASTCALL CancelificateClipulatingPlaneyThings(void) { -// FixificateClipulatingPlaneyThings + // empty +} + +// FUNCTION: CARMA2_HW 0x004e5f00 +void C2_HOOK_FASTCALL FixificateClipulatingPlaneyThings(void) { + + // empty +} void C2_HOOK_FASTCALL ProcessModelFaceMaterials(br_model* pModel, tPMFMCB* pCallback) { tU16 f; diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index b974e5c912..5aa2b0a8bf 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -10,9 +10,9 @@ extern void C2_HOOK_FASTCALL AddExtraRender(br_actor* pActor, br_material* pMate extern int C2_HOOK_FASTCALL PointOutOfSight(const br_vector3* pPoint, undefined4 pArg2, br_scalar pMax_distance); -// CancelificateClipulatingPlaneyThings +extern void C2_HOOK_FASTCALL CancelificateClipulatingPlaneyThings(void); -// FixificateClipulatingPlaneyThings +extern void C2_HOOK_FASTCALL FixificateClipulatingPlaneyThings(void); extern void C2_HOOK_FASTCALL ProcessModelFaceMaterials(br_model* pModel, tPMFMCB* pCallback); From 2f465f6224d8b8c5a0a31a9384e7d7e1d2aedf2f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 18:59:55 +0200 Subject: [PATCH 22/35] Implement ProcessModelFaceMaterials2 --- src/carma2/newcommon/17-world2.c | 26 +++++++++++++++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 6479fd2ea4..810d6b51dc 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -116,7 +116,31 @@ void C2_HOOK_FASTCALL ProcessModelFaceMaterials(br_model* pModel, tPMFMCB* pCall } } -// ProcessModelFaceMaterials2 +// FUNCTION: CARMA2_HW 0x00448fd0 +void C2_HOOK_FASTCALL ProcessModelFaceMaterials2(br_model* pModel, material_cbfn* pCallback) { + tU32 i; + tU32 j; + + if (pModel->faces == NULL) { + if (pModel->prepared != NULL) { + for (i = 0; i < pModel->prepared->ngroups; i++) { + + /* FIXME: can this inner loop be removed? */ + for (j = 0; j < pModel->prepared->groups[i].nfaces; j++) { + if (*pModel->prepared->groups[i].face_colours.materials != NULL) { + pCallback(*pModel->prepared->groups[i].face_colours.materials); + } + } + } + } + } else if (pModel->faces != NULL) { + for (i = 0; i < pModel->nfaces; i++) { + if (pModel->faces[i].material != NULL) { + pCallback(pModel->faces[i].material); + } + } + } +} // FUNCTION: CARMA2_HW 0x00448850 intptr_t C2_HOOK_CDECL ProcessFaceMaterials(br_actor* pActor, void* pData) { diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index 5aa2b0a8bf..b419c9fa11 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -16,7 +16,7 @@ extern void C2_HOOK_FASTCALL FixificateClipulatingPlaneyThings(void); extern void C2_HOOK_FASTCALL ProcessModelFaceMaterials(br_model* pModel, tPMFMCB* pCallback); -// ProcessModelFaceMaterials2 +extern void C2_HOOK_FASTCALL ProcessModelFaceMaterials2(br_model* pModel, material_cbfn* pCallback); extern intptr_t C2_HOOK_CDECL ProcessFaceMaterials(br_actor* pActor, void* pData); From 99442b991487ac47f62d2b8920d29280e4375eea Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 19:00:06 +0200 Subject: [PATCH 23/35] Match ProcessMaterials --- src/carma2/newcommon/17-world2.c | 14 +++++++++++--- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index 810d6b51dc..cce9d7b8bd 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -476,9 +476,17 @@ void C2_HOOK_FASTCALL SetCarSimplificationLevel(int pLevel) { // GetCarSimplificationLevel -// STUB: CARMA2_HW 0x00448f90 -intptr_t C2_HOOK_CDECL ProcessMaterials(br_actor* pActor, material_cbfn* pCallback) { - NOT_IMPLEMENTED(); +// FUNCTION: CARMA2_HW 0x00448f90 +intptr_t C2_HOOK_CDECL ProcessMaterials(br_actor* pActor, void* pContext) { + material_cbfn* callback = pContext; + + if (pActor->material != NULL) { + callback(pActor->material); + } + if (pActor->type == BR_ACTOR_MODEL && pActor->model != NULL) { + ProcessModelFaceMaterials2(pActor->model, callback); + } + return BrActorEnum(pActor, ProcessMaterials, callback); } // BuildColourTable diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index b419c9fa11..1d49685e05 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -70,7 +70,7 @@ extern void C2_HOOK_FASTCALL SetCarSimplificationLevel(int pLevel); // GetCarSimplificationLevel -extern intptr_t C2_HOOK_CDECL ProcessMaterials(br_actor* pActor, material_cbfn* pCallback); +extern intptr_t C2_HOOK_CDECL ProcessMaterials(br_actor* pActor, void* pContext); // BuildColourTable From 767485f460b4f6cc00a49cbd689458120460e4e0 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 19:51:38 +0200 Subject: [PATCH 24/35] Match BuildColourTable --- src/carma2/newcommon/17-world2.c | 39 +++++++++++++++++++++++++++++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index cce9d7b8bd..d4a9f6ac5f 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -30,6 +30,16 @@ tExtra_render gExtra_renders[6]; // GLOBAL: CARMA2_HW 0x00704e40 int gMirror_on__graphics; +// GLOBAL: CARMA2_HW 0x0065cf30 +br_colour gRGB_colours[9] = { + 0x000000, 0xffffff, 0xff0000, 0x00ff00, + 0x0000ff, 0xffff00, 0x00ffff, 0xff00ff, + 0xd04702, +}; + +// GLOBAL: CARMA2_HW 0x0074a620 +br_colour gColours[9]; + // FUNCTION: CARMA2_HW 0x004e5cb0 void C2_HOOK_FASTCALL InitialiseExtraRenders(void) { @@ -489,5 +499,32 @@ intptr_t C2_HOOK_CDECL ProcessMaterials(br_actor* pActor, void* pContext) { return BrActorEnum(pActor, ProcessMaterials, callback); } -// BuildColourTable +// FUNCTION: CARMA2_HW 0x004b4ed0 +void C2_HOOK_FASTCALL BuildColourTable(br_pixelmap* pPalette) { + int i; + int j; + int nearest_index; + int red; + int green; + int blue; + float nearest_distance; + float distance; + + for (i = 0; i < (int)REC2_ASIZE(gRGB_colours); i++) { + nearest_distance = 196608.f; + red = (gRGB_colours[i] >> 16) & 0xFF; + green = (gRGB_colours[i] >> 8) & 0xFF; + blue = gRGB_colours[i] & 0xFF; + for (j = 0; j < 256; j++) { + distance = (float)(sqr((double)(signed int)(*((br_uint_8*)pPalette->pixels + 4 * j + 2) - red)) + + sqr((double)(signed int)(*((br_uint_8*)pPalette->pixels + 4 * j) - blue)) + + sqr((double)(signed int)(*((br_uint_8*)pPalette->pixels + 4 * j + 1) - green))); + if (distance < nearest_distance) { + nearest_index = j; + nearest_distance = distance; + } + } + gColours[i] = nearest_index; + } +} diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index 1d49685e05..bd26c773dd 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -72,6 +72,6 @@ extern void C2_HOOK_FASTCALL SetCarSimplificationLevel(int pLevel); extern intptr_t C2_HOOK_CDECL ProcessMaterials(br_actor* pActor, void* pContext); -// BuildColourTable +extern void C2_HOOK_FASTCALL BuildColourTable(br_pixelmap* pPalette); #endif // GUARD_17_WORLD2_H From 52b1c7921757d27946cc445809b63bd34b6b71db Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 19:52:57 +0200 Subject: [PATCH 25/35] Match GetAccessoryRendering --- src/carma2/newcommon/17-world2.c | 6 +++++- src/carma2/newcommon/17-world2.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/17-world2.c b/src/carma2/newcommon/17-world2.c index d4a9f6ac5f..ebb2714711 100644 --- a/src/carma2/newcommon/17-world2.c +++ b/src/carma2/newcommon/17-world2.c @@ -476,7 +476,11 @@ void C2_HOOK_FASTCALL SetAccessoryRendering(int pOn) { gRendering_accessories = pOn; } -// GetAccessoryRendering +// FUNCTION: CARMA2_HW 0x00448f00 +int C2_HOOK_FASTCALL GetAccessoryRendering(void) { + + return gRendering_accessories; +} // FUNCTION: CARMA2_HW 0x00448f10 void C2_HOOK_FASTCALL SetCarSimplificationLevel(int pLevel) { diff --git a/src/carma2/newcommon/17-world2.h b/src/carma2/newcommon/17-world2.h index bd26c773dd..fea5e89304 100644 --- a/src/carma2/newcommon/17-world2.h +++ b/src/carma2/newcommon/17-world2.h @@ -64,7 +64,7 @@ extern intptr_t C2_HOOK_CDECL SetAccessoryRenderingCB(br_actor* pActor, void* pF extern void C2_HOOK_FASTCALL SetAccessoryRendering(int pOn); -// GetAccessoryRendering +extern int C2_HOOK_FASTCALL GetAccessoryRendering(void); extern void C2_HOOK_FASTCALL SetCarSimplificationLevel(int pLevel); From c3e85ed5b008d9b2e558b0d33fe0ff78a26d8622 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 19:54:12 +0200 Subject: [PATCH 26/35] Match SetAlwaysTyping --- src/carma2/newcommon/35-intrface.c | 9 ++++++++- src/carma2/newcommon/35-intrface.h | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/35-intrface.c b/src/carma2/newcommon/35-intrface.c index 2f89cb3850..e1027935f1 100644 --- a/src/carma2/newcommon/35-intrface.c +++ b/src/carma2/newcommon/35-intrface.c @@ -1,6 +1,13 @@ #include "35-intrface.h" -// SetAlwaysTyping +// GLOBAL: CARMA2_HW 0x0068c1f0 +int gAlways_typing; + +// FUNCTION: CARMA2_HW 0x00484620 +void C2_HOOK_FASTCALL SetAlwaysTyping(void) { + + gAlways_typing = 1; +} // ClearAlwaysTyping diff --git a/src/carma2/newcommon/35-intrface.h b/src/carma2/newcommon/35-intrface.h index 7a57f0abe8..1ea5e1db4c 100644 --- a/src/carma2/newcommon/35-intrface.h +++ b/src/carma2/newcommon/35-intrface.h @@ -1,7 +1,9 @@ #ifndef GUARD_35_INTRFACE_H #define GUARD_35_INTRFACE_H -// SetAlwaysTyping +#include "c2_hooks.h" + +extern void C2_HOOK_FASTCALL SetAlwaysTyping(void); // ClearAlwaysTyping From 768c64599ce41f9149e225ebabc0ef74d83b8323 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 19:55:49 +0200 Subject: [PATCH 27/35] Match ClearAlwaysTyping --- src/carma2/newcommon/35-intrface.c | 6 +++++- src/carma2/newcommon/35-intrface.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/35-intrface.c b/src/carma2/newcommon/35-intrface.c index e1027935f1..b9ac3d5fe3 100644 --- a/src/carma2/newcommon/35-intrface.c +++ b/src/carma2/newcommon/35-intrface.c @@ -9,7 +9,11 @@ void C2_HOOK_FASTCALL SetAlwaysTyping(void) { gAlways_typing = 1; } -// ClearAlwaysTyping +// FUNCTION: CARMA2_HW 0x00484630 +void C2_HOOK_FASTCALL ClearAlwaysTyping(void) { + + gAlways_typing = 0; +} // ChoiceDisabled diff --git a/src/carma2/newcommon/35-intrface.h b/src/carma2/newcommon/35-intrface.h index 1ea5e1db4c..afe0dd585c 100644 --- a/src/carma2/newcommon/35-intrface.h +++ b/src/carma2/newcommon/35-intrface.h @@ -5,7 +5,7 @@ extern void C2_HOOK_FASTCALL SetAlwaysTyping(void); -// ClearAlwaysTyping +extern void C2_HOOK_FASTCALL ClearAlwaysTyping(void); // ChoiceDisabled From a427383d925dea5502b45a1d3b4cb6f8b7a8c194 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:05:33 +0200 Subject: [PATCH 28/35] Match ChoiceDisabled --- src/carma2/newcommon/35-intrface.c | 53 ++++++++++++++++++++++++++++-- src/carma2/newcommon/35-intrface.h | 5 +-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/carma2/newcommon/35-intrface.c b/src/carma2/newcommon/35-intrface.c index b9ac3d5fe3..139e559c46 100644 --- a/src/carma2/newcommon/35-intrface.c +++ b/src/carma2/newcommon/35-intrface.c @@ -3,6 +3,12 @@ // GLOBAL: CARMA2_HW 0x0068c1f0 int gAlways_typing; +// GLOBAL: CARMA2_HW 0x0068c1ec +int gDisabled_count; + +// GLOBAL: CARMA2_HW 0x0068c1f8 +int gDisabled_choices[10]; + // FUNCTION: CARMA2_HW 0x00484620 void C2_HOOK_FASTCALL SetAlwaysTyping(void) { @@ -15,11 +21,54 @@ void C2_HOOK_FASTCALL ClearAlwaysTyping(void) { gAlways_typing = 0; } -// ChoiceDisabled +int C2_HOOK_FASTCALL ChoiceDisabled(int pChoice) { + int i; + + for (i = 0; i < gDisabled_count; ++i) { + if (gDisabled_choices[i] == pChoice) { + return 1; + } + } + return 0; +} // ResetInterfaceTimeout -// ChangeSelection +// FUNCTION: CARMA2_HW 0x00484dd0 +void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled) { + + if (ChoiceDisabled(*pNew_selection)) { + if (pSkip_disabled) { + if (*pOld_selection < *pNew_selection) { + do { + *pNew_selection += 1; + if (*pNew_selection < pSpec->move_up_min[pMode]) { + *pNew_selection = pSpec->move_up_max[pMode]; + } + if (*pNew_selection > pSpec->move_up_max[pMode]) { + *pNew_selection = pSpec->move_up_min[pMode]; + } + } while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection)); + } else { + do { + *pNew_selection -= 1; + if (*pNew_selection < pSpec->move_up_min[pMode]) { + *pNew_selection = pSpec->move_up_max[pMode]; + } + if (*pNew_selection > pSpec->move_up_max[pMode]) { + *pNew_selection = pSpec->move_up_min[pMode]; + } + } while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection)); + } + } else { + *pNew_selection = *pOld_selection; + } + } + + if (*pOld_selection != *pNew_selection) { + *pOld_selection = *pNew_selection; + } +} // RecopyAreas diff --git a/src/carma2/newcommon/35-intrface.h b/src/carma2/newcommon/35-intrface.h index afe0dd585c..2ae15dce89 100644 --- a/src/carma2/newcommon/35-intrface.h +++ b/src/carma2/newcommon/35-intrface.h @@ -2,16 +2,17 @@ #define GUARD_35_INTRFACE_H #include "c2_hooks.h" +#include "rec2_types.h" extern void C2_HOOK_FASTCALL SetAlwaysTyping(void); extern void C2_HOOK_FASTCALL ClearAlwaysTyping(void); -// ChoiceDisabled +extern int C2_HOOK_FASTCALL ChoiceDisabled(int pChoice); // ResetInterfaceTimeout -// ChangeSelection +extern void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled); // RecopyAreas From c0f1b892d1a0f7fc6a6eebe604d6efd75723dfc2 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:06:59 +0200 Subject: [PATCH 29/35] Match SelectThisItemIn --- src/carma2/newcommon/35-intrface.c | 9 ++++++++- src/carma2/newcommon/35-intrface.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/35-intrface.c b/src/carma2/newcommon/35-intrface.c index 139e559c46..28bd5a2f96 100644 --- a/src/carma2/newcommon/35-intrface.c +++ b/src/carma2/newcommon/35-intrface.c @@ -76,5 +76,12 @@ void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_se // WhichItemIsSelectedIn -// SelectThisItemIn +// FUNCTION: CARMA2_HW 0x00484f70 +void C2_HOOK_FASTCALL SelectThisItemIn(tFrontend_spec* pFrontend, int pGroup, int pValue) { + int i; + + for (i = pFrontend->radios[pGroup - 1].indexFirstItem; i <= pFrontend->radios[pGroup - 1].indexLastItem; i++) { + pFrontend->items[i].radioButton_selected = i == pValue; + } +} diff --git a/src/carma2/newcommon/35-intrface.h b/src/carma2/newcommon/35-intrface.h index 2ae15dce89..72d085424e 100644 --- a/src/carma2/newcommon/35-intrface.h +++ b/src/carma2/newcommon/35-intrface.h @@ -20,6 +20,6 @@ extern void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* // WhichItemIsSelectedIn -// SelectThisItemIn +extern void C2_HOOK_FASTCALL SelectThisItemIn(tFrontend_spec* pFrontend, int pGroup, int pValue); #endif // GUARD_35_INTRFACE_H From 03faa35c862990360bebb0da377f2f8356345105 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:09:43 +0200 Subject: [PATCH 30/35] Match WhichItemIsSelectedIn --- src/carma2/newcommon/35-intrface.c | 14 +++++++++++++- src/carma2/newcommon/35-intrface.h | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/35-intrface.c b/src/carma2/newcommon/35-intrface.c index 28bd5a2f96..24691ae513 100644 --- a/src/carma2/newcommon/35-intrface.c +++ b/src/carma2/newcommon/35-intrface.c @@ -74,7 +74,19 @@ void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_se // DoInterfaceScreen -// WhichItemIsSelectedIn +// FUNCTION: CARMA2_HW 0x00484f40 +int C2_HOOK_FASTCALL WhichItemIsSelectedIn(tFrontend_spec* pFrontend, int pGroup) { + int i; + + for (i = 0; i < pFrontend->count_items; i++) { + tFrontend_item_spec* item = &pFrontend->items[i]; + + if (item->group == pGroup && item->radioButton_selected) { + return i; + } + } + return -1; +} // FUNCTION: CARMA2_HW 0x00484f70 void C2_HOOK_FASTCALL SelectThisItemIn(tFrontend_spec* pFrontend, int pGroup, int pValue) { diff --git a/src/carma2/newcommon/35-intrface.h b/src/carma2/newcommon/35-intrface.h index 72d085424e..25ea80e4fe 100644 --- a/src/carma2/newcommon/35-intrface.h +++ b/src/carma2/newcommon/35-intrface.h @@ -18,7 +18,7 @@ extern void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* // DoInterfaceScreen -// WhichItemIsSelectedIn +extern int C2_HOOK_FASTCALL WhichItemIsSelectedIn(tFrontend_spec* pFrontend, int pGroup); extern void C2_HOOK_FASTCALL SelectThisItemIn(tFrontend_spec* pFrontend, int pGroup, int pValue); From 0e9d76b42c8cb2203d011b75bfc780673423311a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:32:16 +0200 Subject: [PATCH 31/35] Match LoadInterfaceStuff --- src/carma2/newcommon/10-loading2.c | 7 ++++++- src/carma2/newcommon/10-loading2.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/carma2/newcommon/10-loading2.c b/src/carma2/newcommon/10-loading2.c index 4c05b01a2c..4a3454d2ce 100644 --- a/src/carma2/newcommon/10-loading2.c +++ b/src/carma2/newcommon/10-loading2.c @@ -461,11 +461,16 @@ void C2_HOOK_FASTCALL LoadKeyMapping(void) { PFfclose(f); } -// LoadInterfaceStuff +// FUNCTION: CARMA2_HW 0x00487ea0 +void C2_HOOK_FASTCALL LoadInterfaceStuff(int pWithin_race) { + + // empty +} // FUNCTION: CARMA2_HW 0x00487eb0 void C2_HOOK_FASTCALL InitInterfaceLoadState(void) { + // empty } // AdjustCarCoordinates diff --git a/src/carma2/newcommon/10-loading2.h b/src/carma2/newcommon/10-loading2.h index 064a5f892a..b50026f8e0 100644 --- a/src/carma2/newcommon/10-loading2.h +++ b/src/carma2/newcommon/10-loading2.h @@ -20,7 +20,7 @@ extern void C2_HOOK_FASTCALL FinishLoadingGeneral(void); extern void C2_HOOK_FASTCALL LoadKeyMapping(void); -// LoadInterfaceStuff +extern void C2_HOOK_FASTCALL LoadInterfaceStuff(int pWithin_race); extern void C2_HOOK_FASTCALL InitInterfaceLoadState(void); From e740de3a1e68c418849abb05c07fb6479f2de79f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:33:19 +0200 Subject: [PATCH 32/35] Match LoadFlic and InitFlicQueue --- src/carma2/newcommon/38-flicplay.c | 27 +++++++++++++++++++++++---- src/carma2/newcommon/38-flicplay.h | 8 ++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/carma2/newcommon/38-flicplay.c b/src/carma2/newcommon/38-flicplay.c index fe28492457..7d9f20e857 100644 --- a/src/carma2/newcommon/38-flicplay.c +++ b/src/carma2/newcommon/38-flicplay.c @@ -1,5 +1,7 @@ #include "38-flicplay.h" +#include "rec2_types.h" + // GLOBAL: CARMA2_HW 0x0068b8b4 float gFlic_sound_delay_pre_smack; @@ -15,6 +17,9 @@ float gFlic_sound_delay_post_demo; // GLOBAL: CARMA2_HW 0x006861dc int gTranslation_count; +// GLOBAL: CARMA2_HW 0x006861e8 +tFlic_descriptor* gFirst_flic; + // FUNCTION: CARMA2_HW 0x00461990 int C2_HOOK_FASTCALL TranslationMode(void) { @@ -75,19 +80,33 @@ void C2_HOOK_FASTCALL InitFlics(void) { NOT_IMPLEMENTED(); } -// LoadFlic +// FUNCTION: CARMA2_HW 0x00462a60 +int C2_HOOK_FASTCALL LoadFlic(int pIndex) { -// UnlockFlic + return 0; +} + +// STUB: CARMA2_HW 0x00462a70 +void C2_HOOK_FASTCALL UnlockFlic(int pIndex) { + NOT_IMPLEMENTED(); +} // LoadFlicData -// InitFlicQueue +// FUNCTION: CARMA2_HW 0x00462cc0 +void C2_HOOK_FASTCALL InitFlicQueue(void) { + + gFirst_flic = NULL; +} // FlicQueueFinished // ProcessFlicQueue -// FlushFlicQueue +// STUB: CARMA2_HW 0x00462dc0 +void C2_HOOK_FASTCALL FlushFlicQueue(void) { + NOT_IMPLEMENTED(); +} // STUB: CARMA2_HW 0x00463340 void C2_HOOK_FASTCALL LoadInterfaceStrings(void) { diff --git a/src/carma2/newcommon/38-flicplay.h b/src/carma2/newcommon/38-flicplay.h index f22471ed3f..800129fd29 100644 --- a/src/carma2/newcommon/38-flicplay.h +++ b/src/carma2/newcommon/38-flicplay.h @@ -58,19 +58,19 @@ extern void C2_HOOK_FASTCALL FlicPaletteAllocate(void); extern void C2_HOOK_FASTCALL InitFlics(void); -// LoadFlic +extern int C2_HOOK_FASTCALL LoadFlic(int pIndex); -// UnlockFlic +extern void C2_HOOK_FASTCALL UnlockFlic(int pIndex); // LoadFlicData -// InitFlicQueue +extern void C2_HOOK_FASTCALL InitFlicQueue(void); // FlicQueueFinished // ProcessFlicQueue -// FlushFlicQueue +extern void C2_HOOK_FASTCALL FlushFlicQueue(void); extern void C2_HOOK_FASTCALL LoadInterfaceStrings(void); From d557155cc411b6960f8e531d949014bfabff37f5 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:34:34 +0200 Subject: [PATCH 33/35] Match EdgeTriggerModeOn and EdgeTriggerModeOff --- src/carma2/newcommon/42-input.c | 46 +++++++++++++++++++++++++++------ src/carma2/newcommon/42-input.h | 16 ++++++------ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/carma2/newcommon/42-input.c b/src/carma2/newcommon/42-input.c index e9b9c6269f..e38b4d3311 100644 --- a/src/carma2/newcommon/42-input.c +++ b/src/carma2/newcommon/42-input.c @@ -3,9 +3,15 @@ // GLOBAL: CARMA2_HW 0x0074b5e0 int gKey_mapping[77]; +// GLOBAL: CARMA2_HW 0x0068c1c4 +int gEdge_trigger_mode; + // SetJoystickArrays -// PollKeys +// STUB: CARMA2_HW 0x00481eb0 +void C2_HOOK_FASTCALL PollKeys(void) { + NOT_IMPLEMENTED(); +} // CyclePollKeys @@ -27,7 +33,10 @@ int C2_HOOK_FASTCALL PDKeyDown(int pKey_index) { // PDKeyDown3 -// PDAnyKeyDown +// STUB: CARMA2_HW 0x00482a00 +int C2_HOOK_FASTCALL PDAnyKeyDown(void) { + NOT_IMPLEMENTED(); +} // STUB: CARMA2_HW 0x00482d70 int C2_HOOK_FASTCALL AnyKeyDown(void) { @@ -43,21 +52,42 @@ int C2_HOOK_FASTCALL KeyIsDown(int pKey_index) { // KeyIsDownNoMouldiness -// WaitForNoKeys +// STUB: CARMA2_HW 0x004833b0 +void C2_HOOK_FASTCALL WaitForNoKeys(void) { + NOT_IMPLEMENTED(); +} // GetMousePosition -// InitRollingLetters +// STUB: CARMA2_HW 0x00483c90 +void C2_HOOK_FASTCALL InitRollingLetters(void) { + NOT_IMPLEMENTED(); +} -// EndRollingLetters +// STUB: CARMA2_HW 0x00483ce0 +void C2_HOOK_FASTCALL EndRollingLetters(void) { + NOT_IMPLEMENTED(); +} // AddRollingLetter // ChangeCharTo -// RevertTyping +// STUB: CARMA2_HW 0x00484120 +void C2_HOOK_FASTCALL RevertTyping(int pSlot_index, char* pRevert_str) { + NOT_IMPLEMENTED(); +} -// EdgeTriggerModeOn +// FUNCTION: CARMA2_HW 0x00484600 +void C2_HOOK_FASTCALL EdgeTriggerModeOn(void) { -// EdgeTriggerModeOff + gEdge_trigger_mode = 1; +} + + +// FUNCTION: CARMA2_HW 0x00484610 +void C2_HOOK_FASTCALL EdgeTriggerModeOff(void) { + + gEdge_trigger_mode = 0; +} diff --git a/src/carma2/newcommon/42-input.h b/src/carma2/newcommon/42-input.h index 76238abe87..5f29517534 100644 --- a/src/carma2/newcommon/42-input.h +++ b/src/carma2/newcommon/42-input.h @@ -7,7 +7,7 @@ extern int gKey_mapping[77]; // SetJoystickArrays -// PollKeys +extern void C2_HOOK_FASTCALL PollKeys(void); // CyclePollKeys @@ -25,7 +25,7 @@ extern int C2_HOOK_FASTCALL PDKeyDown(int pKey_index); // PDKeyDown3 -// PDAnyKeyDown +extern int C2_HOOK_FASTCALL PDAnyKeyDown(void); extern int C2_HOOK_FASTCALL AnyKeyDown(void); @@ -35,22 +35,22 @@ extern int C2_HOOK_FASTCALL KeyIsDown(int pKey_index); // KeyIsDownNoMouldiness -// WaitForNoKeys +extern void C2_HOOK_FASTCALL WaitForNoKeys(void); // GetMousePosition -// InitRollingLetters +extern void C2_HOOK_FASTCALL InitRollingLetters(void); -// EndRollingLetters +extern void C2_HOOK_FASTCALL EndRollingLetters(void); // AddRollingLetter // ChangeCharTo -// RevertTyping +extern void C2_HOOK_FASTCALL RevertTyping(int pSlot_index, char* pRevert_str); -// EdgeTriggerModeOn +extern void C2_HOOK_FASTCALL EdgeTriggerModeOn(void); -// EdgeTriggerModeOff +extern void C2_HOOK_FASTCALL EdgeTriggerModeOff(void); #endif // GUARD_42_INPUT_H From 9213b3f82b4bb2d7c5636ef7cd88cd1ca5214649 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:36:33 +0200 Subject: [PATCH 34/35] Match DoInterfaceScreen --- src/carma2/newcommon/18-graphics2.c | 15 +- src/carma2/newcommon/18-graphics2.h | 6 +- src/carma2/newcommon/35-intrface.c | 249 +++++++++++++++++++++++++++- src/carma2/newcommon/35-intrface.h | 4 +- src/carma2/newcommon/69-sound.c | 8 +- src/carma2/newcommon/69-sound.h | 4 +- 6 files changed, 274 insertions(+), 12 deletions(-) diff --git a/src/carma2/newcommon/18-graphics2.c b/src/carma2/newcommon/18-graphics2.c index dc315b730e..580b911cd2 100644 --- a/src/carma2/newcommon/18-graphics2.c +++ b/src/carma2/newcommon/18-graphics2.c @@ -177,7 +177,10 @@ void C2_HOOK_FASTCALL InitTransientBitmaps(void) { // DeallocateAllTransientBitmaps -// RemoveTransientBitmaps +// STUB: CARMA2_HW 0x0043e010 +void C2_HOOK_FASTCALL RemoveTransientBitmaps(int pGraphically_remove_them) { + NOT_IMPLEMENTED(); +} // SaveTransient @@ -189,7 +192,10 @@ void C2_HOOK_FASTCALL InitTransientBitmaps(void) { // StartMouseCursor -// EndMouseCursor +// STUB: CARMA2_HW 0x0043e710 +void C2_HOOK_FASTCALL EndMouseCursor(void) { + NOT_IMPLEMENTED(); +} // DRDrawLine @@ -200,7 +206,10 @@ void C2_HOOK_FASTCALL ClearEntireScreen(void) { // DistanceFromPlane -// KillSplashScreen +// STUB: CARMA2_HW 0x0047b960 +void C2_HOOK_FASTCALL KillSplashScreen(void) { + NOT_IMPLEMENTED(); +} // SplashScreenWith diff --git a/src/carma2/newcommon/18-graphics2.h b/src/carma2/newcommon/18-graphics2.h index 30f42fcb8d..86ad4fe552 100644 --- a/src/carma2/newcommon/18-graphics2.h +++ b/src/carma2/newcommon/18-graphics2.h @@ -46,7 +46,7 @@ extern void C2_HOOK_FASTCALL InitTransientBitmaps(void); // DeallocateAllTransientBitmaps -// RemoveTransientBitmaps +extern void C2_HOOK_FASTCALL RemoveTransientBitmaps(int pGraphically_remove_them); // SaveTransient @@ -58,7 +58,7 @@ extern void C2_HOOK_FASTCALL InitTransientBitmaps(void); // StartMouseCursor -// EndMouseCursor +extern void C2_HOOK_FASTCALL EndMouseCursor(void); // DRDrawLine @@ -66,7 +66,7 @@ extern void C2_HOOK_FASTCALL ClearEntireScreen(void); // DistanceFromPlane -// KillSplashScreen +extern void C2_HOOK_FASTCALL KillSplashScreen(void); // SplashScreenWith diff --git a/src/carma2/newcommon/35-intrface.c b/src/carma2/newcommon/35-intrface.c index 24691ae513..5ff081d578 100644 --- a/src/carma2/newcommon/35-intrface.c +++ b/src/carma2/newcommon/35-intrface.c @@ -1,5 +1,15 @@ #include "35-intrface.h" +#include "08-loading1.h" +#include "10-loading2.h" +#include "18-graphics2.h" +#include "19-font.h" +#include "38-flicplay.h" +#include "42-input.h" +#include "69-sound.h" +#include "globvars.h" +#include "platform.h" + // GLOBAL: CARMA2_HW 0x0068c1f0 int gAlways_typing; @@ -9,6 +19,24 @@ int gDisabled_count; // GLOBAL: CARMA2_HW 0x0068c1f8 int gDisabled_choices[10]; +// GLOBAL: CARMA2_HW 0x0075b8fc +int gTyping_slot; + +// GLOBAL: CARMA2_HW 0x0068c1e8 +const tInterface_spec* gSpec; + +// GLOBAL: CARMA2_HW 0x0068c220 +int gCurrent_mode; + +// GLOBAL: CARMA2_HW 0x0068c224 +int gCurrent_choice; + +// GLOBAL: CARMA2_HW 0x0068c228 +tU32 gStart_time; + +// GLOBAL: CARMA2_HW 0x0079ecb8 +int gMouse_in_use; + // FUNCTION: CARMA2_HW 0x00484620 void C2_HOOK_FASTCALL SetAlwaysTyping(void) { @@ -32,7 +60,10 @@ int C2_HOOK_FASTCALL ChoiceDisabled(int pChoice) { return 0; } -// ResetInterfaceTimeout +void C2_HOOK_FASTCALL ResetInterfaceTimeout__intrface(void) { + + gStart_time = PDGetTotalTime(); +} // FUNCTION: CARMA2_HW 0x00484dd0 void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled) { @@ -72,7 +103,221 @@ void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_se // RecopyAreas -// DoInterfaceScreen +// FUNCTION: CARMA2_HW 0x004846e0 +int C2_HOOK_FASTCALL DoInterfaceScreen(const tInterface_spec* pSpec, int pOptions, int pCurrent_choice) { + tProg_status entry_status; + int i; + int last_choice; + int escaped; + int timed_out; + int go_ahead; + int result; + int the_key; + int the_max; + int defeat_mode_change; + char the_str[256]; + + entry_status = gProgram_state.prog_status; + gTyping_slot = -1; + EdgeTriggerModeOn(); + gSpec = pSpec; + gDisabled_count = 0; + LoadInterfaceStuff(gProgram_state.racing); + gProgram_state.dont_save_or_load = pSpec->dont_save_or_load; + for (i = 0; i < pSpec->number_of_button_flics; i++) { + LoadFlic(pSpec->flicker_on_flics[i].flic_index); + LoadFlic(pSpec->flicker_off_flics[i].flic_index); + LoadFlic(pSpec->pushed_flics[i].flic_index); + } + + InitFlicQueue(); + ResetInterfaceTimeout__intrface(); + gCurrent_choice = pCurrent_choice; + gCurrent_mode = pSpec->initial_imode; + if (pSpec->font_needed) { + InitRollingLetters(); + LoadFont(0); + } + KillSplashScreen(); + if (pSpec->start_proc1 != NULL) { + pSpec->start_proc1(); + } + if (pSpec->start_proc2 != NULL) { + pSpec->start_proc2(); + } + last_choice = -1; + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 0); + WaitForNoKeys(); + gMouse_in_use = 0; + last_choice = gCurrent_choice; + for (;;) { + if (last_choice != gCurrent_choice) { + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1); + } + last_choice = gCurrent_choice; + PollKeys(); + EdgeTriggerModeOff(); + the_key = PDAnyKeyDown(); + if (the_key != -1 && the_key != 4) { + gMouse_in_use = 0; + ResetInterfaceTimeout__intrface(); + } + EdgeTriggerModeOn(); + if ((gTyping_slot < 0 || gAlways_typing) && (PDKeyDown(70) || PDKeyDown(85))) { + if (pSpec->move_left_delta[gCurrent_mode] != 0) { + gCurrent_choice += pSpec->move_left_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_left_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_left_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_left_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_left_min[gCurrent_mode]; + } + DRS3StartSound(gEffects_outlet, eSoundId_LeftButton); + } + if (pSpec->move_left_proc[gCurrent_mode] != NULL) { + defeat_mode_change = pSpec->move_left_proc[gCurrent_mode](&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_left_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_left_new_mode[gCurrent_mode]; + } + } + if ((gTyping_slot < 0 || gAlways_typing) && (PDKeyDown(71) || PDKeyDown(87))) { + if (pSpec->move_right_delta[gCurrent_mode] != 0) { + gCurrent_choice += pSpec->move_right_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_right_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_right_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_right_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_right_min[gCurrent_mode]; + } + DRS3StartSound(gEffects_outlet, eSoundId_LeftButton); + } + if (pSpec->move_right_proc[gCurrent_mode] != NULL) { + defeat_mode_change = pSpec->move_right_proc[gCurrent_mode](&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_right_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_right_new_mode[gCurrent_mode]; + } + } + if (PDKeyDown(72) || PDKeyDown(89)) { + if (pSpec->move_up_delta[gCurrent_mode] != 0) { + gCurrent_choice += pSpec->move_up_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_up_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_up_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_up_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_up_min[gCurrent_mode]; + } + DRS3StartSound(gEffects_outlet, eSoundId_LeftButton); + } + if (pSpec->move_up_proc[gCurrent_mode] != NULL) { + defeat_mode_change = pSpec->move_up_proc[gCurrent_mode](&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_up_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_up_new_mode[gCurrent_mode]; + } + } + if (PDKeyDown(73) || PDKeyDown(83)) { + if (pSpec->move_down_delta[gCurrent_mode] != 0) { + gCurrent_choice += pSpec->move_down_delta[gCurrent_mode]; + if (gCurrent_choice < pSpec->move_down_min[gCurrent_mode]) { + gCurrent_choice = pSpec->move_down_max[gCurrent_mode]; + } + if (gCurrent_choice > pSpec->move_down_max[gCurrent_mode]) { + gCurrent_choice = pSpec->move_down_min[gCurrent_mode]; + } + DRS3StartSound(gEffects_outlet, eSoundId_LeftButton); + } + if (pSpec->move_down_proc[gCurrent_mode] != NULL) { + defeat_mode_change = pSpec->move_down_proc[gCurrent_mode](&gCurrent_choice, &gCurrent_mode); + } else { + defeat_mode_change = 0; + } + if (pSpec->move_down_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) { + gCurrent_mode = pSpec->move_down_new_mode[gCurrent_mode]; + } + } + if (gTyping_slot >= 0 && pSpec->typeable[gCurrent_mode] && gTyping_slot != gCurrent_choice && !gAlways_typing) { + gCurrent_choice = gTyping_slot; + } + if (last_choice != gCurrent_choice) { + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1); + } + timed_out = pSpec->time_out && (PDGetTotalTime() >= gStart_time + pSpec->time_out); + RemoveTransientBitmaps(1); + go_ahead = 1; + if (pSpec->go_ahead_proc[gCurrent_mode]) { + go_ahead = pSpec->go_ahead_proc[gCurrent_mode](&gCurrent_choice, &gCurrent_mode); + } + if (PDKeyDown(63)) { + DRS3StartSound(gEffects_outlet, eSoundId_EscEsc); + escaped = pSpec->escape_allowed[gCurrent_mode]; + if (pSpec->escape_proc[gCurrent_mode] != NULL) { + escaped = pSpec->escape_proc[gCurrent_mode](&gCurrent_choice, &gCurrent_mode); + } + } else { + escaped = 0; + } + if (escaped && gTyping_slot >= 0 && !gAlways_typing) { + escaped = 0; + pSpec->get_original_string(0, gTyping_slot, the_str, &the_max); + RevertTyping(gTyping_slot, the_str); + gTyping = 0; + gTyping_slot = -1; + } + if (last_choice != gCurrent_choice) { + ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1); + } + if (entry_status != eProg_idling && gProgram_state.prog_status == eProg_idling) { + escaped = 1; + } + if (pSpec->exit_proc != NULL) { + if (pSpec->exit_proc(&gCurrent_choice, &gCurrent_mode)) { + break; + } + } + if (go_ahead || timed_out || escaped) { + break; + } + } + + gTyping = 0; + if (pSpec->font_needed) { + EndRollingLetters(); + DisposeFont(0); + } + RemoveTransientBitmaps(1); + FlushFlicQueue(); + for (i = 0; i < pSpec->number_of_button_flics; i++) { + UnlockFlic(pSpec->flicker_on_flics[i].flic_index); + UnlockFlic(pSpec->flicker_off_flics[i].flic_index); + UnlockFlic(pSpec->pushed_flics[i].flic_index); + } + + if (gCurrent_choice == pSpec->escape_code) { + escaped = 1; + go_ahead = 0; + } + if (escaped) { + gCurrent_choice = pSpec->escape_code; + } + if (pSpec->done_proc != NULL) { + result = (pSpec->done_proc)(gCurrent_choice, gCurrent_mode, go_ahead, escaped, timed_out); + } else { + result = gCurrent_choice; + } + gProgram_state.dont_save_or_load = 0; + EndMouseCursor(); + UnlockInterfaceStuff(); + EdgeTriggerModeOff(); + return result; +} // FUNCTION: CARMA2_HW 0x00484f40 int C2_HOOK_FASTCALL WhichItemIsSelectedIn(tFrontend_spec* pFrontend, int pGroup) { diff --git a/src/carma2/newcommon/35-intrface.h b/src/carma2/newcommon/35-intrface.h index 25ea80e4fe..9744adec3b 100644 --- a/src/carma2/newcommon/35-intrface.h +++ b/src/carma2/newcommon/35-intrface.h @@ -10,13 +10,13 @@ extern void C2_HOOK_FASTCALL ClearAlwaysTyping(void); extern int C2_HOOK_FASTCALL ChoiceDisabled(int pChoice); -// ResetInterfaceTimeout +extern void C2_HOOK_FASTCALL ResetInterfaceTimeout__intrface(void); extern void C2_HOOK_FASTCALL ChangeSelection(const tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled); // RecopyAreas -// DoInterfaceScreen +extern int C2_HOOK_FASTCALL DoInterfaceScreen(const tInterface_spec* pSpec, int pOptions, int pCurrent_choice); extern int C2_HOOK_FASTCALL WhichItemIsSelectedIn(tFrontend_spec* pFrontend, int pGroup); diff --git a/src/carma2/newcommon/69-sound.c b/src/carma2/newcommon/69-sound.c index 854d4e60c6..3ab2709882 100644 --- a/src/carma2/newcommon/69-sound.c +++ b/src/carma2/newcommon/69-sound.c @@ -77,6 +77,9 @@ const char* gSound_periodicity_choices[3] = { // GLOBAL: CARMA2_HW 0x00595c48 int gSound_detail_level = 1; +// GLOBAL: CARMA2_HW 0x006845fc +tS3_outlet* gEffects_outlet; + // FUNCTION: CARMA2_HW 0x00500060 void C2_HOOK_FASTCALL SplungeSomeData(void* pData, br_size_t size) { @@ -119,7 +122,10 @@ void C2_HOOK_FASTCALL InitSound(void) { NOT_IMPLEMENTED(); } -// DRS3StartSound +// STUB: CARMA2_HW 0x00455690 +tS3_sound_tag C2_HOOK_FASTCALL DRS3StartSound(tS3_outlet* pOutlet, tS3_sound_id pSound) { + NOT_IMPLEMENTED(); +} int C2_HOOK_FASTCALL DRS3StartSoundNoPiping(tS3_outlet* pOutlet, tS3_sound_id pSound) { if (gSound_enabled) { diff --git a/src/carma2/newcommon/69-sound.h b/src/carma2/newcommon/69-sound.h index 48d3f11568..12f06f5f98 100644 --- a/src/carma2/newcommon/69-sound.h +++ b/src/carma2/newcommon/69-sound.h @@ -9,6 +9,8 @@ #include +extern tS3_outlet* gEffects_outlet; + extern int gCD_fully_installed; extern void C2_HOOK_FASTCALL SplungeSomeData(void* pData, br_size_t size); @@ -17,7 +19,7 @@ extern void C2_HOOK_FASTCALL UsePathFileToDetermineIfFullInstallation(void); extern void C2_HOOK_FASTCALL InitSound(void); -// DRS3StartSound +extern tS3_sound_tag C2_HOOK_FASTCALL DRS3StartSound(tS3_outlet* pOutlet, tS3_sound_id pSound); extern int C2_HOOK_FASTCALL DRS3StartSoundNoPiping(tS3_outlet* pOutlet, tS3_sound_id pSound); From 9d3f7c581930ddf1bf006ea81902c05f1b6b2179 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 23 Jun 2026 20:38:06 +0200 Subject: [PATCH 35/35] Fix MinGW warning --- src/carma2/newcommon/28-world3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/carma2/newcommon/28-world3.c b/src/carma2/newcommon/28-world3.c index e7bdf26311..ec8c1da804 100644 --- a/src/carma2/newcommon/28-world3.c +++ b/src/carma2/newcommon/28-world3.c @@ -420,7 +420,9 @@ br_material* C2_HOOK_FASTCALL LoadSingleMaterial(tBrender_storage* pStorage_spac FatalError(kFatalError_InsufficientMaterialSlots); return NULL; } - +#ifdef REC2_FIX_BUGS + return NULL; +#endif } // FUNCTION: CARMA2_HW 0x00501930