Fix reccmp warnings (#469)

* fix array sizes

* fixes reccmp warnings

* enable intrinsics, patches some functions
This commit is contained in:
Dethrace Engineering Department 2025-08-28 13:14:28 +12:00 committed by GitHub
parent 0a0fc8bf7f
commit b3cc5d5393
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 205 additions and 103 deletions

View File

@ -144,6 +144,18 @@ jobs:
report_filename: ${{ github.workspace}}/new-reccmp-report.json
original_binary_url: https://archive.org/download/carm-95/CARM95.EXE
original_binary_filename: CARM95.EXE
reccmp_output_filename: ${{ github.workspace}}/reccmp-output.txt
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: reccmp-output.txt
path: ${{ github.workspace}}/reccmp-output.txt
if-no-files-found: error
- name: Validate correctness
run: |
if grep -q "Decreased" ${{ github.workspace}}/reccmp-output.txt; then
echo "::warning file=reccmp-output.txt::Decomp correctness decreased"
fi
- name: Update report in reccmp-report
if: github.ref == 'refs/heads/main'
run: |

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
.vscode
reccmp-user.yml
reccmp-build.yml
reccmp-report*

View File

@ -47,7 +47,7 @@ option(DETHRACE_PLATFORM_SDL2 "Support SDL 2 platform driver" ON)
option(MSVC_42_FOR_RECCMP "Build with MSVC 4.2 to match assembly" OFF)
if (MSVC_42_FOR_RECCMP)
if(MSVC_42_FOR_RECCMP)
set(DETHRACE_FIX_BUGS OFF)
set(DETHRACE_3DFX_PATCH OFF)
set(DETHRACE_SOUND_ENABLED OFF)
@ -56,13 +56,12 @@ if (MSVC_42_FOR_RECCMP)
set(DETHRACE_PLATFORM_SDL2 OFF)
set(BRENDER_BUILD_DRIVERS OFF)
set(CMAKE_C_FLAGS_DEBUG "/Zi /Od /MTd")
set(CMAKE_C_FLAGS_DEBUG "/Zi /Oi /MLd")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG")
include("reccmp")
endif()
function(add_compile_flag_if_supported TARGET FLAG)
cmake_parse_arguments(ARGS "" "" "LANGUAGES" ${ARGN})

View File

@ -191,6 +191,9 @@ if(MSVC_42_FOR_RECCMP)
add_executable(dethrace WIN32)
set_target_properties(dethrace PROPERTIES OUTPUT_NAME "CARM95")
target_link_options(dethrace PRIVATE /INCREMENTAL:NO /subsystem:windows /ENTRY:mainCRTStartup)
set_source_files_properties(common/loading.c PROPERTIES COMPILE_FLAGS "/Oi")
set_source_files_properties(common/crush.c PROPERTIES COMPILE_FLAGS "/Oi")
reccmp_add_target(dethrace ID CARM95)
reccmp_configure()
else()

View File

@ -497,7 +497,7 @@ tEdit_func* gEdit_funcs[10][18][8] = {
};
// GLOBAL: CARM95 0x0051cc80
tCheat gKev_keys[44] = {
tCheat gKev_keys[43] = {
{ 0xa11ee75d, 0xf805eddd, SetFlag, 0x0a11ee75d },
{ 0x564e78b9, 0x99155115, SetFlag, 0x0564e78b9 },
{ 0x1f47e5e8, 0xa715222c, SetFlag2, 1 },
@ -543,7 +543,6 @@ tCheat gKev_keys[44] = {
{ 0x0, 0x0, 0x0, 0x0 },
};
// GLOBAL: CARM95 0x0051cf30
int gAllow_car_flying;

View File

@ -10,7 +10,7 @@ extern tU32 gLast_repair_time;
extern tEdit_mode gWhich_edit_mode;
extern char* gEdit_mode_names[10];
extern tEdit_func* gEdit_funcs[10][18][8];
extern tCheat gKev_keys[44];
extern tCheat gKev_keys[43];
extern int gAllow_car_flying;
extern int gEntering_message;
extern tU32 gPalette_fade_time;

View File

@ -260,10 +260,10 @@ br_scalar EdgeU(br_angle pSky, br_angle pView, br_angle pPerfect) {
br_scalar b;
br_scalar c;
a = cos(BrAngleToRadian(pPerfect));
a = cos(BrAngleToRadian(pPerfect)) * cos(BrAngleToRadian(pPerfect));
b = sin(BrAngleToRadian(pView));
c = cos(BrAngleToRadian(pView));
return b * a * a / (BrAngleToRadian(pSky) * (1.f + c));
c = cos(BrAngleToRadian(pView) + 1.0f) * BrAngleToRadian(pSky);
return b * a / c;
}
// IDA: void __usercall MungeSkyModel(br_actor *pCamera@<EAX>, br_model *pModel@<EDX>)
@ -949,7 +949,7 @@ void SetYon(br_scalar pYon) {
pYon = 5.0f;
}
for (i = 0; i < COUNT_OF(gCamera_list); i++) {
for (i = 0; i < BR_ASIZE(gCamera_list); i++) {
if (gCamera_list[i]) {
camera_ptr = gCamera_list[i]->type_data;
camera_ptr->yon_z = pYon;

View File

@ -84,7 +84,13 @@ int gPed_kill_count_headup;
int gDim_amount;
// GLOBAL: CARM95 0x00544e70
// gHeadup_images
#ifdef DETHRACE_FIX_BUGS
br_pixelmap* gHeadup_images[32]; // Modified by DethRace for the demo
#else
br_pixelmap* gHeadup_images[31];
#endif
// GLOBAL: CARM95 0x00544e58
int gNet_cash_headup;
@ -317,12 +323,12 @@ void DimRectangle(br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int p
int line_skip;
int width;
#ifdef DETHRACE_3DFX_PATCH
#ifdef DETHRACE_3DFX_PATCH
if (gDevious_2d) {
DeviouslyDimRectangle(pPixelmap, pLeft, pTop, pRight, pBottom, pKnock_out_corners);
return;
}
#endif
#endif
ptr = (tU8*)pPixelmap->pixels + pLeft + pPixelmap->row_bytes * pTop;
line_skip = pPixelmap->row_bytes - pRight + pLeft;

View File

@ -25,7 +25,11 @@ extern int gTimer_headup;
extern int gTime_awarded_headup;
extern int gPed_kill_count_headup;
extern int gDim_amount;
#ifdef DETHRACE_FIX_BUGS
extern br_pixelmap* gHeadup_images[32];
#else
extern br_pixelmap* gHeadup_images[31];
#endif
extern int gNet_cash_headup;
extern int gNet_ped_headup;
extern int gCredits_lost_headup;

View File

@ -340,7 +340,7 @@ int KeyIsDown(int pKey_index) {
case -2:
return 1;
case -1:
for (i = 0; i < COUNT_OF(gGo_ahead_keys); i++) {
for (i = 0; i < BR_ASIZE(gGo_ahead_keys); i++) {
if (gKey_array[gGo_ahead_keys[i]]) {
return 1;
}

View File

@ -44,7 +44,7 @@
#define OPPONENT_APC_IDX 3
// GLOBAL: CARM95 0x0050a3f0
tHeadup_info gHeadup_image_info[32] = {
tHeadup_info gHeadup_image_info[] = {
// Modified by DethRace to fit the "demo timeout" fancy head-up.
{ "LADY.PIX", eNet_or_otherwise },
{ "GENT.PIX", eNet_or_otherwise },
@ -76,8 +76,11 @@ tHeadup_info gHeadup_image_info[32] = {
{ "GAMEOVER.PIX", eNet_only },
{ "UBROKE.PIX", eNet_only },
{ "ULOST.PIX", eNet_only },
{ "UWON.PIX", eNet_only },
{ "DTIMEOUT.PIX", eNot_net }, // Only used by the demo, not present in the full version
{ "UWON.PIX", eNet_only }
#ifdef DETHRACE_FIX_BUGS
,
{ "DTIMEOUT.PIX", eNot_net } // Only used by the demo, not present in the full version
#endif
};
char* gYour_car_names[2][6];
@ -736,7 +739,8 @@ void DRLoadLights(char* pPath_name) {
PossibleService();
number_of_lights = BrActorLoadMany(pPath_name, light_array, COUNT_OF(light_array));
for (i = 0; i < number_of_lights; i++) {
for (i = 0; number_of_lights > i; ++i) {
gLight_array[gNumber_of_lights] = light_array[i];
gNumber_of_lights++;
}
@ -1340,66 +1344,79 @@ void ReadNonCarMechanicsData(FILE* pF, tNon_car_spec* non_car) {
int j;
char s[256];
tCollision_info* c;
br_scalar wid;
br_scalar het;
br_scalar len;
br_scalar len; // epb-120
br_scalar wid; // ebp-110
br_scalar het; // ebp-4
br_scalar ts;
br_scalar ts1;
br_scalar snap_angle;
non_car->collision_info.driver = 0;
number = GetAnInt(pF);
non_car->collision_info.index = number;
GetThreeFloats(pF, &non_car->free_cmpos.v[0], &non_car->free_cmpos.v[1], &non_car->free_cmpos.v[2]);
GetThreeFloats(pF, &non_car->attached_cmpos.v[0], &non_car->attached_cmpos.v[1], &non_car->attached_cmpos.v[2]);
GetThreeFloats(pF, &non_car->collision_info.bounds[1].min.v[0], &non_car->collision_info.bounds[1].min.v[1], &non_car->collision_info.bounds[1].min.v[2]);
GetThreeFloats(pF, &non_car->collision_info.bounds[1].max.v[0], &non_car->collision_info.bounds[1].max.v[1], &non_car->collision_info.bounds[1].max.v[2]);
non_car->collision_info.extra_point_num = GetAnInt(pF);
if (non_car->collision_info.extra_point_num > 6) {
sprintf(s, "%d", non_car->collision_info.index);
c = &non_car->collision_info;
c->driver = 0;
c->index = GetAnInt(pF);
ReadVector3(pF, non_car->free_cmpos.v[0], non_car->free_cmpos.v[1], non_car->free_cmpos.v[2]);
ReadVector3(pF, non_car->attached_cmpos.v[0], non_car->attached_cmpos.v[1], non_car->attached_cmpos.v[2]);
ReadVector3(pF, c->bounds[1].min.v[0], c->bounds[1].min.v[1], c->bounds[1].min.v[2]);
ReadVector3(pF, c->bounds[1].max.v[0], c->bounds[1].max.v[1], c->bounds[1].max.v[2]);
c->extra_point_num = GetAnInt(pF);
if (c->extra_point_num > 6) {
sprintf(s, "%d", c->index);
FatalError(kFatalError_TooManyExtraPointsForCar_S, s);
}
for (i = 0; non_car->collision_info.extra_point_num > i; ++i) {
GetThreeFloats(pF, &non_car->collision_info.extra_points[i].v[0], &non_car->collision_info.extra_points[i].v[1], &non_car->collision_info.extra_points[i].v[2]);
for (i = 0; c->extra_point_num > i; ++i) {
ReadVector3(pF, c->extra_points[i].v[0], c->extra_points[i].v[1], c->extra_points[i].v[2]);
}
GetPairOfFloats(pF, &non_car->free_mass, &non_car->attached_mass);
GetThreeFloats(pF, &len, &wid, &het);
ReadPairOfFloats(pF, non_car->free_mass, non_car->attached_mass);
do {
float x[3];
GetThreeFloats(pF, &x[2], &x[1], &x[0]);
wid = x[2];
het = x[1];
len = x[0];
} while (0);
snap_angle = GetAFloat(pF);
non_car->snap_off_cosine = cos(BrAngleToRadian(BrDegreeToAngle(snap_angle)));
non_car->collision_info.break_off_radians_squared = snap_angle * 3.14f / 180.f * (snap_angle * 3.14f / 180.f);
c->break_off_radians_squared = snap_angle * 3.14 / 180.0 * (snap_angle * 3.14 / 180.0);
ts = GetAFloat(pF);
non_car->min_torque_squared = ts * ts;
non_car->collision_info.bounds[0].min = non_car->collision_info.bounds[1].min;
non_car->collision_info.bounds[0].max = non_car->collision_info.bounds[1].max;
for (i = 0; non_car->collision_info.extra_point_num > i; ++i) {
for (j = 0; j < 3; ++j) {
if (non_car->collision_info.extra_points[i].v[j] < non_car->collision_info.bounds[0].min.v[j]) {
non_car->collision_info.bounds[0].min.v[j] = non_car->collision_info.extra_points[i].v[j];
BrVector3Copy(&c->bounds[0].min, &c->bounds[1].min);
BrVector3Copy(&c->bounds[0].max, &c->bounds[1].max);
for (i = 0; i < c->extra_point_num; i++) {
for (j = 0; j < 3; j++) {
if (c->bounds[0].min.v[j] > c->extra_points[i].v[j]) {
c->bounds[0].min.v[j] = c->extra_points[i].v[j];
}
if (non_car->collision_info.extra_points[i].v[j] > non_car->collision_info.bounds[0].max.v[j]) {
non_car->collision_info.bounds[0].max.v[j] = non_car->collision_info.extra_points[i].v[j];
if (c->extra_points[i].v[j] > c->bounds[0].max.v[j]) {
c->bounds[0].max.v[j] = c->extra_points[i].v[j];
}
}
}
non_car->collision_info.bounds[2] = non_car->collision_info.bounds[0];
non_car->I_over_M.v[2] = (wid * wid + len * len) / 12.0;
non_car->I_over_M.v[1] = (het * het + len * len) / 12.0;
non_car->I_over_M.v[0] = (het * het + wid * wid) / 12.0;
BrVector3Scale(&non_car->free_cmpos, &non_car->free_cmpos, WORLD_SCALE);
BrVector3Scale(&non_car->attached_cmpos, &non_car->attached_cmpos, WORLD_SCALE);
BrVector3Scale(&non_car->I_over_M, &non_car->I_over_M, 47.610001);
BrVector3Scale(&non_car->collision_info.bounds[1].min, &non_car->collision_info.bounds[1].min, WORLD_SCALE);
BrVector3Scale(&non_car->collision_info.bounds[1].max, &non_car->collision_info.bounds[1].max, WORLD_SCALE);
memcpy(&c->bounds[2], &c->bounds[0], sizeof(c->bounds[2]));
ts1 = BR_SQR2(wid, het);
non_car->I_over_M.v[2] = ts1 / 12.0f;
ts1 = BR_SQR2(wid, len);
non_car->I_over_M.v[1] = ts1 / 12.0f;
ts1 = BR_SQR2(het, len);
non_car->I_over_M.v[0] = ts1 / 12.0f;
DRVector3Scale(&non_car->free_cmpos, &non_car->free_cmpos, WORLD_SCALE);
DRVector3Scale(&non_car->attached_cmpos, &non_car->attached_cmpos, WORLD_SCALE);
DRVector3Scale(&non_car->I_over_M, &non_car->I_over_M, 47.61000061035156f);
DRVector3Scale(&c->bounds[1].min, &c->bounds[1].min, WORLD_SCALE);
DRVector3Scale(&c->bounds[1].max, &c->bounds[1].max, WORLD_SCALE);
for (i = 0; non_car->collision_info.extra_point_num > i; ++i) {
BrVector3Scale(&non_car->collision_info.extra_points[i], &non_car->collision_info.extra_points[i], WORLD_SCALE);
for (i = 0; c->extra_point_num > i; ++i) {
DRVector3Scale(&c->extra_points[i], &c->extra_points[i], WORLD_SCALE);
}
non_car->collision_info.max_bounds[0] = non_car->collision_info.bounds[0];
non_car->collision_info.max_bounds[1] = non_car->collision_info.bounds[2];
for (i = 0; non_car->collision_info.extra_point_num > i; ++i) {
non_car->collision_info.original_extra_points_z[i] = non_car->collision_info.extra_points[i].v[2];
memcpy(&c->max_bounds[0], &c->bounds[0], sizeof(c->max_bounds[0]));
memcpy(&c->max_bounds[1], &c->bounds[1], sizeof(c->max_bounds[0]));
for (i = 0; i < c->extra_point_num; i++) {
c->original_extra_points_z[i] = c->extra_points[i].v[2];
}
}
@ -1866,8 +1883,9 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner,
int vertex_total;
if (pDriver == eDriver_local_human) {
if (strcmp(gProgram_state.car_name, pCar_name) == 0)
if (strcmp(gProgram_state.car_name, pCar_name) == 0) {
return;
}
if (gProgram_state.car_name[0] != '\0') {
DisposeCar(&gProgram_state.current_car, gProgram_state.current_car.index);
ClearOutStorageSpace(&gOur_car_storage_space);
@ -1878,6 +1896,8 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner,
pCar_spec->index = pOwner;
if (pDriver == eDriver_local_human) {
gProgram_state.current_car_index = pOwner;
}
if (pDriver == eDriver_local_human) {
gFunk_groove_flags[0] = 1;
gGroove_funk_offset = 0;
} else {
@ -1895,10 +1915,10 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner,
if (gGroove_funk_offset < 0) {
FatalError(kFatalError_NoFunkGrooveSlotBunchesLeft);
}
if (strcmp(pCar_name, "STELLA.TXT") == 0) {
pCar_spec->proxy_ray_distance = 6.0f;
} else {
if (strcmp(pCar_name, "STELLA.TXT") != 0) {
pCar_spec->proxy_ray_distance = 0.0f;
} else {
pCar_spec->proxy_ray_distance = 6.0f;
}
PathCat(the_path, gApplication_path, "CARS");
PathCat(the_path, the_path, pCar_name);
@ -2484,10 +2504,12 @@ void LoadHeadupImages(void) {
for (i = 0; i < COUNT_OF(gHeadup_image_info); i++) {
PossibleService();
if (gHeadup_image_info[i].avail && (gHeadup_image_info[i].avail != eNot_net || gNet_mode) && (gHeadup_image_info[i].avail != eNet_only || !gNet_mode)) {
gHeadup_images[i] = NULL;
} else {
if ((gHeadup_image_info[i].avail == eNet_or_otherwise)
|| ((gHeadup_image_info[i].avail == eNot_net) && (gNet_mode == eNet_mode_none))
|| ((gHeadup_image_info[i].avail == eNet_only) && gNet_mode)) {
gHeadup_images[i] = LoadPixelmap(gHeadup_image_info[i].name);
} else {
gHeadup_images[i] = NULL;
}
}
}
@ -2522,11 +2544,11 @@ FILE* OpenRaceFile(void) {
// IDA: void __usercall SkipRestOfRace(FILE *pF@<EAX>)
// FUNCTION: CARM95 0x0042434a
void SkipRestOfRace(FILE* pF) {
int j;
int k;
int text_chunk_count;
int line_count;
char s[256];
int k; // at [ebp-110h]
int j; // at [ebp-10Ch]
int text_chunk_count; // at [ebp-108h]
int line_count; // at [ebp-104h]
char s[256]; // at [ebp-100h]
GetALineAndDontArgue(pF, s);
GetALineAndDontArgue(pF, s);
@ -2539,9 +2561,10 @@ void SkipRestOfRace(FILE* pF) {
GetALineAndDontArgue(pF, s);
line_count = GetAnInt(pF);
while (line_count > 8) {
GetALineAndDontArgue(pF, s);
line_count--;
GetALineAndDontArgue(pF, s);
}
for (k = 0; k < line_count; k++) {
GetALineAndDontArgue(pF, s);
}

View File

@ -3,7 +3,7 @@
#include "dr_types.h"
extern tHeadup_info gHeadup_image_info[32];
extern tHeadup_info gHeadup_image_info[];
extern char* gYour_car_names[2][6];
extern char* gDrivable_car_names[6];
extern char* gDamage_names[12];

View File

@ -26,7 +26,7 @@ int StraightestArcForCorner2D(br_vector2* pCent, br_scalar* pRadius, br_scalar*
// There appears to be two different implementations of this function in different binaries.
// One does calculations in 2d space, this one calculates in 3d space.
// FUNCTION: CARM95 0x0049feaa
static void StraightestArcForCorner(float* p1, float* p2, float* p3, br_vector3* p4, br_vector3* p5, br_vector3* p6, br_vector3* p7, br_vector3* p8, float p9, float p10) {
void StraightestArcForCorner(float* p1, float* p2, float* p3, br_vector3* p4, br_vector3* p5, br_vector3* p6, br_vector3* p7, br_vector3* p8, float p9, float p10) {
br_vector3 rel1;
br_vector3 rel3;
br_vector3 rot1;
@ -194,7 +194,7 @@ tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_o
int later_straight;
int next_left_not_right;
float v104;
float v104;
car_spec = pOpponent_spec->car_spec;
engine_damage = car_spec->damage_units[0].damage_level;

View File

@ -1214,7 +1214,7 @@ int KeyAssignGoAhead(int* pCurrent_choice, int* pCurrent_mode) {
if (*pCurrent_mode == 0) {
key = -1;
if (*pCurrent_choice == 0) {
for (i = 0; i < COUNT_OF(gKey_defns); i++) {
for (i = 0; i < BR_ASIZE(gKey_defns); i++) {
if (gKey_mapping[gKey_defns[i]] == -2) {
key = i;
break;
@ -1282,7 +1282,7 @@ int KeyAssignGoAhead(int* pCurrent_choice, int* pCurrent_mode) {
if (key != -1 && key != 63) {
for (i = 27; i < 65; i++) {
if (gKey_mapping[i] == key && gKey_defns[gCurrent_key] != i) {
for (j = 0; j < COUNT_OF(gKey_defns); j++) {
for (j = 0; j < BR_ASIZE(gKey_defns); j++) {
if (gKey_defns[j] == i) {
gKey_mapping[i] = -2;
gPending_entry = j;

View File

@ -1320,7 +1320,7 @@ int MungePedestrianAction(tPedestrian_data* pPedestrian, float pDanger_level) {
void MakeFlagWavingBastardWaveHisFlagWhichIsTheProbablyTheLastThingHeWillEverDo(void) {
if (gFlag_waving_bastard != NULL
&& gFlag_waving_bastard->current_action != gFlag_waving_bastard->fatal_car_impact_action
&& (gFlag_waving_bastard->current_action != gFlag_waving_bastard->fatal_car_impact_action)
&& gFlag_waving_bastard->current_action != gFlag_waving_bastard->fatal_ground_impact_action) {
ChangeActionTo(gFlag_waving_bastard, 7, 1);
}

View File

@ -1215,7 +1215,7 @@ void ResetPedHarvest(tPowerup* pPowerup, tCar_spec* pCar) {
int i;
gPedestrian_harvest = 0;
for (i = 0; i < COUNT_OF(gPed_harvest_sounds); i++) {
for (i = 0; i < BR_ASIZE(gPed_harvest_sounds); i++) {
DRS3StartSound3D(gPedestrians_outlet, gPed_harvest_sounds[i], &pCar->pos,
&gZero_v__powerup, 1, 255, -1, -1);
}

View File

@ -35,19 +35,17 @@ int gIn_check_quit = 0;
// GLOBAL: CARM95 0x0052148c
tU32 gLost_time = 0;
// GLOBAL: CARM95 0x00521490
// gLong_key
// GLOBAL: CARM95 0x005214a0
// gOther_long_key
#if BR_ENDIAN_BIG
// GLOBAL: CARM95 0x00521490
tU32 gLong_key[4] = { 0x6c1b995f, 0xb9cd5f13, 0xcb04200e, 0x5e1ca10e };
// GLOBAL: CARM95 0x005214a0
tU32 gOther_long_key[4] = { 0x67a8d626, 0xb6dd451b, 0x327e2213, 0x15c29437 };
#else
// GLOBAL: CARM95 0x00521490
tU32 gLong_key[4] = { 0x5f991b6c, 0x135fcdb9, 0x0e2004cb, 0x0ea11c5e };
// GLOBAL: CARM95 0x005214a0
tU32 gOther_long_key[4] = { 0x26d6a867, 0x1b45ddb6, 0x13227e32, 0x3794c215 };
#endif

View File

@ -2376,13 +2376,13 @@ br_material* DisposeSuffixedMaterials(br_model* pModel, tU16 pFace) {
return NULL;
}
max_suffix_len = 0;
for (s = 0; s < COUNT_OF(suffixes); s++) {
for (s = 0; s < BR_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_3);
for (s = 0; s < COUNT_OF(suffixes); s++) {
for (s = 0; s < BR_ASIZE(suffixes); s++) {
sprintf(id, "%s%s", mat->identifier, suffixes[s]);
victim = BrMaterialFind(id);
if (victim != NULL) {
@ -3262,7 +3262,7 @@ br_scalar NormaliseDegreeAngle(br_scalar pAngle) {
} \
break; \
case eMove_flash: \
if (2 * fmod(f_the_time, (PERIOD)) > (PERIOD)) { \
if (2 * fmod(f_the_time, (PERIOD)) > (PERIOD)) { \
DEST = (FLASH_VALUE); \
} else { \
DEST = -(FLASH_VALUE); \
@ -3843,16 +3843,18 @@ void ObjectGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pM
br_scalar pos;
br_bounds* bounds;
#ifdef DETHRACE_FIX_BUGS
x_size = 0;
y_size = 0;
z_size = 0;
pos = 0;
#endif
switch (pGroove->object_type) {
case eGroove_object_spin:
if (pGroove->object_data.spin_info.axis == eGroove_axis_y) {
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.spin_info.period != 0.0) {
if (pGroove->object_data.spin_info.period != 0.0f) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0;
}
} else if (pGroove->object_mode == eMove_controlled) {

View File

@ -1,12 +1,12 @@
#ifndef MACROS_H
#define MACROS_H
#define DR_JOIN2(A,B) A##B
#define DR_JOIN(A,B) DR_JOIN2(A, B)
#define DR_STATIC_ASSERT(V) typedef int DR_JOIN(dr_static_assert_, __COUNTER__)[(V)?1:-1]
#define DR_JOIN2(A, B) A##B
#define DR_JOIN(A, B) DR_JOIN2(A, B)
#define DR_STATIC_ASSERT(V) typedef int DR_JOIN(dr_static_assert_, __COUNTER__)[(V) ? 1 : -1]
#define VEHICLE_TYPE_FROM_ID(id) ((tVehicle_type)(id >> 8))
#define VEHICLE_INDEX_FROM_ID(id) ((id)&0x00ff)
#define VEHICLE_INDEX_FROM_ID(id) ((id) & 0x00ff)
// #define VEC3_TRANSLATE(mat) (*(br_vector3*)(&mat->m[3][0]))
@ -19,10 +19,10 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define CONSTRAIN_BETWEEN(lowerbound, upperbound, val) (MIN((upperbound), MAX((lowerbound), (val))))
#define COUNT_OF(array) (sizeof((array)) / sizeof((array)[0]))
#define COUNT_OF(array) (int)(sizeof((array)) / sizeof((array)[0]))
#define LEN(array) (sizeof((array)) / sizeof((array)[0]))
#define DEG_TO_RAD(degrees) ((degrees)*3.141592653589793 / 180.0)
#define DEG_TO_RAD(degrees) ((degrees) * 3.141592653589793 / 180.0)
#define V11MODEL(model) (((struct v11model*)model->prepared))
#define CAR(c) ((tCar_spec*)c)
@ -56,4 +56,38 @@
(V2) = (T); \
} while (0)
#define ReadVector3(pF, a, b, c) \
do { \
float x[3]; \
GetThreeFloats(pF, &x[2], &x[1], &x[0]); \
a = x[2]; \
b = x[1]; \
c = x[0]; \
\
} while (0)
#define ReadVector32(pF, a, b, c) \
do { \
float x[3]; \
GetThreeFloats(pF, &x[2], &x[1], &x[0]); \
b = x[2]; \
c = x[1]; \
a = x[0]; \
} while (0)
#define ReadPairOfFloats(pF, a, b) \
do { \
float x[2]; \
GetPairOfFloats(pF, &x[1], &x[0]); \
a = x[1]; \
b = x[0]; \
} while (0)
#define DRVector3Scale(v1, v2, s) \
do { \
(v1)->v[0] = BR_MUL((v2)->v[0], s); \
(v1)->v[1] = BR_MUL((v2)->v[1], s); \
(v1)->v[2] = BR_MUL((v2)->v[2], s); \
} while (0)
#endif

View File

@ -373,12 +373,6 @@
// LIBRARY: CARM95 0x004df5f0
// BrResRemove
// LIBRARY: CARM95 0x004df8b0
// BrStrDup
// LIBRARY: CARM95 0x004df920
// BrMemSet2
// LIBRARY: CARM95 0x004df980
// BrSwap32

View File

@ -173,3 +173,30 @@
// LIBRARY: CARM95 0x005002d0
// wcstombs
// LIBRARY: CARM95 0x004EABD2
// __CIcos
// LIBRARY: CARM95 0x004EABC8
// __CIsin
// LIBRARY: CARM95 0x004EC51A
// __CIfmod
// LIBRARY: CARM95 0x004EA874
// __ftol
// LIBRARY: CARM95 0x004F076E
// __cintrindisp1
// LIBRARY: CARM95 0x0052D6C2
// __OP_COSjmptab
// LIBRARY: CARM95 0x0052D6A2
// __OP_SINjmptab
// LIBRARY: CARM95 0x0052D140
// __OP_FMODjmptab
// LIBRARY: CARM95 0x004F0730
// __cintrindisp2