diff --git a/lib/BRender-v1.3.2 b/lib/BRender-v1.3.2 index 3428d574..1e3d22b0 160000 --- a/lib/BRender-v1.3.2 +++ b/lib/BRender-v1.3.2 @@ -1 +1 @@ -Subproject commit 3428d57450a90191e4aa1bc9033601335de0799c +Subproject commit 1e3d22b0bee8b649ba0db9bdbe04c1a5eebb2d7f diff --git a/src/DETHRACE/CMakeLists.txt b/src/DETHRACE/CMakeLists.txt index b3aa0457..5cf7e7c6 100644 --- a/src/DETHRACE/CMakeLists.txt +++ b/src/DETHRACE/CMakeLists.txt @@ -59,7 +59,7 @@ if(DETHRACE_REPLAY_DEBUG) target_compile_definitions(dethrace_obj PRIVATE DETHRACE_REPLAY_DEBUG) endif() -if (MINGW) +if(MINGW) target_compile_options(dethrace_obj PRIVATE -Wno-error=incompatible-pointer-types) endif() @@ -68,6 +68,8 @@ target_sources(dethrace_obj PRIVATE common/opponent.c common/oil.c common/racesumm.c + common/replay.c + common/loading.c common/brucetrk.c common/brucetrk.h @@ -115,8 +117,7 @@ target_sources(dethrace_obj PRIVATE common/input.h common/intrface.c common/intrface.h - common/loading.c - common/loading.h + common/loadsave.c common/loadsave.h common/main.c @@ -149,8 +150,7 @@ target_sources(dethrace_obj PRIVATE common/racestrt.h common/raycast.c common/raycast.h - common/replay.c - common/replay.h + common/sound.c common/sound.h common/spark.c @@ -190,7 +190,7 @@ endif() # Create our main game binary. if(MSVC_42_FOR_RECCMP) add_executable(dethrace WIN32) - set(CMAKE_C_FLAGS_DEBUG "/Od /Oi /Zi /MLd /G5") + set(CMAKE_C_FLAGS_DEBUG "/Oi /Zi /MLd /G5") add_compile_definitions(_DEBUG) set_target_properties(dethrace PROPERTIES OUTPUT_NAME "CARM95") @@ -198,6 +198,8 @@ if(MSVC_42_FOR_RECCMP) set_source_files_properties(common/structur.c PROPERTIES COMPILE_FLAGS "/FAs") set_source_files_properties(common/racesumm.c PROPERTIES COMPILE_FLAGS "/FAs") + set_source_files_properties(common/replay.c PROPERTIES COMPILE_FLAGS "/FAs") + set_source_files_properties(common/loading.c PROPERTIES COMPILE_FLAGS "/FAs") reccmp_add_target(dethrace ID CARM95) reccmp_configure() @@ -296,6 +298,7 @@ if(DETHRACE_INSTALL) OPTIONAL ) endif() + if(DETHRACE_PLATFORM_SDL3) install(FILES "$" DESTINATION "." diff --git a/src/DETHRACE/common/loading.c b/src/DETHRACE/common/loading.c index 84a08781..78c396ab 100644 --- a/src/DETHRACE/common/loading.c +++ b/src/DETHRACE/common/loading.c @@ -352,11 +352,7 @@ tU16 MemReadU16(char** pPtr) { // IDA: tU8 __usercall MemReadU8@(char **pPtr@) // FUNCTION: CARM95 0x0041c50e tU8 MemReadU8(char** pPtr) { - tU8 raw_byte; - - memcpy(&raw_byte, *pPtr, sizeof(raw_byte)); - *pPtr += sizeof(raw_byte); - return raw_byte; + return *(*pPtr)++; } // IDA: tS32 __usercall MemReadS32@(char **pPtr@) @@ -389,9 +385,7 @@ tS16 MemReadS16(char** pPtr) { tS8 MemReadS8(char** pPtr) { tS8 raw_byte; - memcpy(&raw_byte, *pPtr, sizeof(raw_byte)); - *pPtr += sizeof(raw_byte); - return raw_byte; + return *(*pPtr)++; } // IDA: void __usercall MemSkipBytes(char **pPtr@, int pBytes_to_skip@) @@ -561,7 +555,7 @@ void FinishLoadingGeneral(void) { // FUNCTION: CARM95 0x0041d22d br_pixelmap* LoadPixelmap(char* pName) { tPath_name the_path; - br_pixelmap* pm = NULL; + br_pixelmap* pm; char* end; end = strrchr(pName, '.'); @@ -569,7 +563,7 @@ br_pixelmap* LoadPixelmap(char* pName) { end = &pName[strlen(pName)]; } - if (end - pName == 4 && memcmp(pName, "none", end - pName) == 0) { + if (end - pName == 4 && memcmp(pName, "none", 4) == 0) { return NULL; } @@ -579,6 +573,7 @@ br_pixelmap* LoadPixelmap(char* pName) { PathCat(the_path, the_path, pName); AllowOpenToFail(); pm = DRPixelmapLoad(the_path); + DoNotAllowOpenToFail(); if (pm == NULL) { PathCat(the_path, gApplication_path, "PIXELMAP"); PathCat(the_path, the_path, pName); @@ -599,6 +594,7 @@ br_uint_32 LoadPixelmaps(char* pFile_name, br_pixelmap** pPixelmaps, br_uint_16 PathCat(path, path, pFile_name); AllowOpenToFail(); count = DRPixelmapLoadMany(path, pPixelmaps, pNum); + DoNotAllowOpenToFail(); if (count == 0) { PathCat(path, gApplication_path, "PIXELMAP"); PathCat(path, path, pFile_name); @@ -621,34 +617,43 @@ br_pixelmap* LoadShadeTable(char* pName) { // FUNCTION: CARM95 0x0041d4c8 br_material* LoadMaterial(char* pName) { tPath_name the_path; +#ifdef DETHRACE_3DFX_PATCH br_material* result; +#endif PossibleService(); PathCat(the_path, gApplication_path, "MATERIAL"); PathCat(the_path, the_path, pName); - result = BrMaterialLoad(the_path); + #ifdef DETHRACE_3DFX_PATCH + result = BrMaterialLoad(the_path); if (result != NULL) { GlorifyMaterial(&result, 1); } -#endif return result; +#else + return BrMaterialLoad(the_path); +#endif } // IDA: br_model* __usercall LoadModel@(char *pName@) // FUNCTION: CARM95 0x0041d525 br_model* LoadModel(char* pName) { tPath_name the_path; +#ifdef DETHRACE_3DFX_PATCH br_model* model; +#endif PossibleService(); PathCat(the_path, gApplication_path, "MODELS"); PathCat(the_path, the_path, pName); - model = BrModelLoad(the_path); #ifdef DETHRACE_3DFX_PATCH + model = BrModelLoad(the_path); WhitenVertexRGB(&model, 1); -#endif return model; +#else + return BrModelLoad(the_path); +#endif } // IDA: br_actor* __usercall LoadActor@(char *pName@) @@ -685,9 +690,7 @@ void DRLoadShadeTable(char* pPath_name) { // IDA: void __usercall RezeroPixelmaps(br_pixelmap **pPixelmap_array@, int pCount@) // FUNCTION: CARM95 0x0041d7b6 void RezeroPixelmaps(br_pixelmap** pPixelmap_array, int pCount) { - - while (pCount != 0) { - pCount--; + while (--pCount >= 0) { pPixelmap_array[pCount]->origin_x = 0; pPixelmap_array[pCount]->origin_y = 0; } @@ -699,7 +702,6 @@ void DRLoadPixelmaps(char* pPath_name) { br_pixelmap* pixelmap_array[100]; int number_of_pixelmaps; - int i; PossibleService(); number_of_pixelmaps = DRPixelmapLoadMany(pPath_name, pixelmap_array, COUNT_OF(pixelmap_array)); @@ -796,6 +798,8 @@ void LoadInRegisteeDir(char* pThe_dir_path) { // IDA: void __cdecl LoadInRegistees() // FUNCTION: CARM95 0x0041d5df void LoadInRegistees(void) { + tPath_name the_path; + LoadInRegisteeDir(gApplication_path); } @@ -879,8 +883,12 @@ void UnlockInterfaceStuff(void) { // IDA: void __cdecl InitInterfaceLoadState() // FUNCTION: CARM95 0x0041dcc7 void InitInterfaceLoadState(void) { + int i; - memset(gCursors, 0, sizeof(gCursors)); + // original code uses 4, not BR_ASIZE(gCursors). Bug? + for (i = 0; i < 4; i++) { + gCursors[i] = NULL; + } } // IDA: tS8* __usercall ConvertPixTo16BitStripMap@(br_pixelmap *pBr_map@) @@ -956,7 +964,6 @@ tS8* ConvertPixTo16BitStripMap(br_pixelmap* pBr_map) { return (tS8*)strip_image; } -// IDA: tS8* __usercall ConvertPixToStripMap@(br_pixelmap *pThe_br_map@) // Jeff: This appears to be used only for dashboard views, either to save memory storage or pixel copies. // See also: `CopyStripImage` // It is a simple RLE algorithm, but only targets runs of blank pixels. @@ -966,6 +973,7 @@ tS8* ConvertPixTo16BitStripMap(br_pixelmap* pBr_map) { // chunk_count (1 byte) // for each chunk: // chunk_length (1 signed byte). If positive, skip this number of blank pixels. If negative, copy the following `length` bytes +// IDA: tS8* __usercall ConvertPixToStripMap@(br_pixelmap *pThe_br_map@) // FUNCTION: CARM95 0x0041dd01 tS8* ConvertPixToStripMap(br_pixelmap* pThe_br_map) { int i; @@ -981,63 +989,62 @@ tS8* ConvertPixToStripMap(br_pixelmap* pThe_br_map) { tU8* temp_strip_image; tU8 new_line[800]; tU8 the_byte; - int total; - temp_strip_image = BrMemAllocate(pThe_br_map->row_bytes * pThe_br_map->height, kMem_strip_image); + the_strip_image = BrMemAllocate(pThe_br_map->row_bytes * pThe_br_map->height, kMem_strip_image); + current_strip_pointer = the_strip_image; current_size = 2; - - *(tU16*)temp_strip_image = pThe_br_map->height; - current_strip_pointer = temp_strip_image; + *(tU16*)current_strip_pointer = pThe_br_map->height; + current_strip_pointer += 2; for (i = 0; i < pThe_br_map->height; i++) { next_byte = (tU8*)pThe_br_map->pixels + i * pThe_br_map->row_bytes; // points to start of this line - new_line_length = 2; // leave space at the start of the line to store number of chunks and first chunk length - j = 0; - counter = 0; - total = 0; + + new_line_length = 2; counting_blanks = *next_byte == 0; + counter = 0; chunk_counter = 0; - the_byte = 0; // Added to keep compiler happy - while (1) { - while (counter <= 126) { - if (j == pThe_br_map->width) { - break; - } + j = 0; + + do { + if (counter <= 126 && j != pThe_br_map->width) { the_byte = *next_byte; - if ((the_byte == 0 && !counting_blanks) || (the_byte != 0 && counting_blanks)) { - break; + if ((the_byte == 0) == counting_blanks) { + goto linex; } - if (!counting_blanks) { - new_line[new_line_length] = the_byte; - new_line_length++; - } - counter++; - j++; - next_byte++; } if (counting_blanks) { new_line[new_line_length - 1] = counter; } else { - new_line[new_line_length - counter - 1] = -counter; + new_line[new_line_length - counter - 1] = ~counter + 1; } + counting_blanks = the_byte == 0; - chunk_counter++; - total += counter; counter = 0; + chunk_counter++; if (j == pThe_br_map->width) { break; + } else { + new_line_length++; } - new_line_length++; - } + continue; + linex: + if (!counting_blanks) { + new_line[new_line_length++] = the_byte; + } + next_byte++; + counter++; + j++; + } while (1); + new_line[0] = chunk_counter; - current_strip_pointer = &temp_strip_image[current_size]; + current_strip_pointer = &the_strip_image[current_size]; memcpy(current_strip_pointer, new_line, new_line_length); current_size += new_line_length; } - the_strip_image = BrMemAllocate(current_size, kMem_strip_image_perm); - memcpy(the_strip_image, temp_strip_image, current_size); - BrMemFree(temp_strip_image); - return (tS8*)the_strip_image; + temp_strip_image = BrMemAllocate(current_size, kMem_strip_image_perm); + memcpy(temp_strip_image, the_strip_image, current_size); + BrMemFree(the_strip_image); + return (tS8*)temp_strip_image; } // IDA: void __usercall KillWindscreen(br_model *pModel@, br_material *pMaterial@) @@ -1046,16 +1053,15 @@ void KillWindscreen(br_model* pModel, br_material* pMaterial) { br_face* face; int i; - if (pModel == NULL || pModel->nfaces == 0) { - return; - } - for (i = 0; i < pModel->nfaces; i++) { - face = &pModel->faces[i]; - if (face->material == pMaterial) { - face->material = NULL; + if (pModel != NULL && pModel->nfaces != 0) { + + for (i = 0, face = pModel->faces; i < pModel->nfaces; i++, face++) { + if (face->material == pMaterial) { + face->material = NULL; + } } + BrModelUpdate(pModel, BR_MODU_ALL); } - BrModelUpdate(pModel, BR_MODU_ALL); } // IDA: void __usercall DropOffDyingPeds(tCar_spec *pCar@) @@ -1326,14 +1332,14 @@ void LoadHeadups(FILE* pF, int pIndex, tCar_spec* pCar_spec) { str = strtok(NULL, "\t ,/"); strcpy(s, str); switch (s[0]) { - case 'c': - pCar_spec->headup_slots[pIndex][j].justification = 2; - break; case 'l': - pCar_spec->headup_slots[pIndex][j].justification = 0; + pCar_spec->headup_slots[pIndex][j].justification = eJust_left; break; case 'r': - pCar_spec->headup_slots[pIndex][j].justification = 1; + pCar_spec->headup_slots[pIndex][j].justification = eJust_right; + break; + case 'c': + pCar_spec->headup_slots[pIndex][j].justification = eJust_centre; break; } if (s[1] == 'c') { @@ -1341,9 +1347,7 @@ void LoadHeadups(FILE* pF, int pIndex, tCar_spec* pCar_spec) { } str = strtok(NULL, "\t ,/"); sscanf(str, "%d", &pCar_spec->headup_slots[pIndex][j].dim_left); - if (pCar_spec->headup_slots[pIndex][j].dim_left < 0) { - pCar_spec->headup_slots[pIndex][j].dimmed_background = 0; - } else { + if (pCar_spec->headup_slots[pIndex][j].dim_left >= 0) { pCar_spec->headup_slots[pIndex][j].dimmed_background = 1; str = strtok(NULL, "\t ,/"); sscanf(str, "%d", &pCar_spec->headup_slots[pIndex][j].dim_top); @@ -1351,6 +1355,8 @@ void LoadHeadups(FILE* pF, int pIndex, tCar_spec* pCar_spec) { sscanf(str, "%d", &pCar_spec->headup_slots[pIndex][j].dim_right); str = strtok(NULL, "\t ,/"); sscanf(str, "%d", &pCar_spec->headup_slots[pIndex][j].dim_bottom); + } else { + pCar_spec->headup_slots[pIndex][j].dimmed_background = 0; } } } @@ -1459,94 +1465,97 @@ void ReadMechanicsData(FILE* pF, tCar_spec* c) { br_scalar force; GetALineAndDontArgue(pF, s); - for (i = strlen(s) - 1; s[i] == ' '; --i) { - ; + i = strlen(s) - 1; + while (s[i] == ' ') { + i--; } version = s[i]; - for (i = 0; i < 4; ++i) { - GetThreeFloats(pF, &c->wpos[i].v[0], &c->wpos[i].v[1], &c->wpos[i].v[2]); + for (i = 0; i < COUNT_OF(c->wpos); i++) { + ReadThreeFloats(pF, c->wpos[i].v[0], c->wpos[i].v[1], c->wpos[i].v[2]); } actor_offset = &c->car_model_actors[c->principal_car_actor].actor->t.t.translate.t; - GetThreeFloats(pF, &c->cmpos.v[0], &c->cmpos.v[1], &c->cmpos.v[2]); + ReadThreeFloats(pF, c->cmpos.v[0], c->cmpos.v[1], c->cmpos.v[2]); if (version < '3') { c->extra_point_num = 0; i = GetAnInt(pF); } - GetThreeFloats(pF, &c->bounds[1].min.v[0], &c->bounds[1].min.v[1], &c->bounds[1].min.v[2]); - GetThreeFloats(pF, &c->bounds[1].max.v[0], &c->bounds[1].max.v[1], &c->bounds[1].max.v[2]); - c->bounds[1].min.v[0] = c->bounds[1].min.v[0] + actor_offset->v[0]; - c->bounds[1].min.v[1] = c->bounds[1].min.v[1] + actor_offset->v[1]; - c->bounds[1].min.v[2] = c->bounds[1].min.v[2] + actor_offset->v[2]; - c->bounds[1].max.v[0] = c->bounds[1].max.v[0] + actor_offset->v[0]; - c->bounds[1].max.v[1] = c->bounds[1].max.v[1] + actor_offset->v[1]; - c->bounds[1].max.v[2] = c->bounds[1].max.v[2] + actor_offset->v[2]; + ReadThreeFloats(pF, c->bounds[1].min.v[0], c->bounds[1].min.v[1], c->bounds[1].min.v[2]); + ReadThreeFloats(pF, c->bounds[1].max.v[0], c->bounds[1].max.v[1], c->bounds[1].max.v[2]); + BrVector3Accumulate(&c->bounds[1].min, actor_offset); + BrVector3Accumulate(&c->bounds[1].max, actor_offset); + if (version >= '3') { 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; c->extra_point_num > i; ++i) { - GetThreeFloats(pF, &c->extra_points[i].v[0], &c->extra_points[i].v[1], &c->extra_points[i].v[2]); + for (i = 0; i < c->extra_point_num; i++) { + ReadThreeFloats(pF, c->extra_points[i].v[0], c->extra_points[i].v[1], c->extra_points[i].v[2]); c->extra_points[i].v[0] = c->extra_points[i].v[0] + actor_offset->v[0]; c->extra_points[i].v[1] = c->extra_points[i].v[1] + actor_offset->v[1]; c->extra_points[i].v[2] = c->extra_points[i].v[2] + actor_offset->v[2]; } } c->maxcurve = 1.0 / GetAFloat(pF); - GetPairOfFloats(pF, &c->susp_give[1], &c->susp_give[0]); + ReadPairOfFloats(pF, c->susp_give[1], c->susp_give[0]); c->ride_height = GetAFloat(pF); c->ride_height = c->bounds[1].min.v[1] + 0.01; c->damping = GetAFloat(pF); c->M = GetAFloat(pF); c->freduction = GetAFloat(pF); - if (version >= '4') { - GetThreeFloats(pF, &theta_front, &theta_back, &theta_comp); - } else { - GetPairOfFloats(pF, &theta_front, &theta_back); + if (version < '4') { + ReadPairOfFloats(pF, theta_front, theta_back); theta_comp = theta_back; + } else { + ReadThreeFloats(pF, theta_front, theta_back, theta_comp); } - GetThreeFloats(pF, &wid, &het, &len); - c->rolling_r_front = 0.050000001; - c->rolling_r_back = 0.050000001; + ReadThreeFloats(pF, wid, het, len); + c->rolling_r_front = 0.05; + c->rolling_r_back = 0.05; c->max_gear = 6; speed = 200.0; force = 4.0; c->friction_elipticity = 1.0; c->down_force_speed = 2000.0; - c->initial_brake = c->M * 12.0; - c->brake_increase = c->M * 12.0; - if (version >= '2' && version <= '4') { - c->friction_elipticity = GetAFloat(pF); // 2, 3, 4 + c->initial_brake = c->M * 12.0f; + c->brake_increase = c->M * 12.0f; + + switch (version) { + case '2': + case '3': + case '4': + c->friction_elipticity = GetAFloat(pF); c->down_force_speed = GetAFloat(pF); - c->initial_brake = GetAFloat(pF) * c->M * 12.0; - c->brake_increase = GetAFloat(pF) * c->M * 12.0; - } - if (version >= '1' && version <= '4') { - GetPairOfFloats(pF, &c->rolling_r_front, &c->rolling_r_back); // 1, 2, 3, 4 + c->initial_brake = GetAFloat(pF) * c->M * 12.0f; + c->brake_increase = GetAFloat(pF) * c->M * 12.0f; + case '1': + ReadPairOfFloats(pF, c->rolling_r_front, c->rolling_r_back); c->max_gear = GetAnInt(pF); speed = GetAFloat(pF); force = GetAFloat(pF); + break; } - speed = speed * 4.0 / 9.0; - c->speed_revs_ratio = speed / (double)c->max_gear / 6000.0; - c->force_torque_ratio = (double)c->max_gear * c->M * force; + speed = speed * 4.0f / 9.0f; + c->speed_revs_ratio = speed / c->max_gear / 6000.0f; + c->force_torque_ratio = c->max_gear * c->M * force; c->mu[1] = tan(theta_front * 3.14 / 180.0) / 4.0; c->mu[0] = tan(theta_back * 3.14 / 180.0) / 4.0; c->mu[2] = tan(theta_comp * 3.14 / 180.0) / 4.0; - c->mu[0] *= sqrt((c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[2].v[2] - c->wpos[0].v[2]) * (c->M * 5.0)); - c->mu[1] *= sqrt((c->wpos[0].v[2] - c->cmpos.v[2]) / (c->wpos[0].v[2] - c->wpos[2].v[2]) * (c->M * 5.0)); - c->mu[2] *= sqrt((c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[2].v[2] - c->wpos[0].v[2]) * (c->M * 5.0)); + c->mu[0] *= sqrt((c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[2].v[2] - c->wpos[0].v[2]) * (c->M * 5.0f)); + c->mu[1] *= sqrt((c->wpos[0].v[2] - c->cmpos.v[2]) / (c->wpos[0].v[2] - c->wpos[2].v[2]) * (c->M * 5.0f)); + c->mu[2] *= sqrt((c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[2].v[2] - c->wpos[0].v[2]) * (c->M * 5.0f)); - for (i = 0; i < 4; ++i) { + for (i = 0; i < COUNT_OF(c->wpos); i++) { c->wpos[i].v[1] = c->ride_height; } - c->bounds[0].min = c->bounds[1].min; - c->bounds[0].max = c->bounds[1].max; - for (i = 0; c->extra_point_num > i; ++i) { - for (j = 0; j < 3; ++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->extra_points[i].v[j] < c->bounds[0].min.v[j]) { c->bounds[0].min.v[j] = c->extra_points[i].v[j]; } @@ -1555,47 +1564,38 @@ void ReadMechanicsData(FILE* pF, tCar_spec* c) { } } } - memcpy(&c->bounds[2], &c->bounds[0], sizeof(br_bounds)); - c->I.v[2] = (het * het + wid * wid) * c->M / 12.0; - c->I.v[1] = (wid * wid + len * len) * c->M / 12.0; - c->I.v[0] = (het * het + len * len) * c->M / 12.0; + c->bounds[2] = c->bounds[0]; + ts1 = het * het + wid * wid; + c->I.v[2] = ts1 * c->M / 12.0f; + ts1 = BR_SQR2(len, wid); + c->I.v[1] = ts1 * c->M / 12.0f; + ts1 = BR_SQR2(len, het); + c->I.v[0] = ts1 * c->M / 12.0f; - for (i = 0; i < 4; ++i) { - c->wpos[i].v[0] = c->wpos[i].v[0] * 6.9; - c->wpos[i].v[1] = c->wpos[i].v[1] * 6.9; - c->wpos[i].v[2] = c->wpos[i].v[2] * 6.9; + for (i = 0; i < COUNT_OF(c->wpos); i++) { + BrVector3Scale(&c->wpos[i], &c->wpos[i], WORLD_SCALE_D); + } + BrVector3Scale(&c->cmpos, &c->cmpos, WORLD_SCALE); + BrVector3Scale(&c->I, &c->I, 47.61f); + BrVector3Scale(&c->bounds[1].min, &c->bounds[1].min, WORLD_SCALE); + BrVector3Scale(&c->bounds[1].max, &c->bounds[1].max, WORLD_SCALE); + for (i = 0; c->extra_point_num > i; ++i) { + BrVector3Scale(&c->extra_points[i], &c->extra_points[i], WORLD_SCALE); } - c->cmpos.v[0] = c->cmpos.v[0] * 6.9000001; - c->cmpos.v[1] = c->cmpos.v[1] * 6.9000001; - c->cmpos.v[2] = c->cmpos.v[2] * 6.9000001; - c->I.v[0] = c->I.v[0] * 47.610001; - c->I.v[1] = c->I.v[1] * 47.610001; - c->I.v[2] = c->I.v[2] * 47.610001; - c->bounds[1].min.v[0] = c->bounds[1].min.v[0] * 6.9000001; - c->bounds[1].min.v[1] = c->bounds[1].min.v[1] * 6.9000001; - c->bounds[1].min.v[2] = c->bounds[1].min.v[2] * 6.9000001; - c->bounds[1].max.v[0] = c->bounds[1].max.v[0] * 6.9000001; - c->bounds[1].max.v[1] = c->bounds[1].max.v[1] * 6.9000001; - c->bounds[1].max.v[2] = c->bounds[1].max.v[2] * 6.9000001; - for (i = 0; c->extra_point_num > i; ++i) { - c->extra_points[i].v[0] = c->extra_points[i].v[0] * 6.9000001; - c->extra_points[i].v[1] = c->extra_points[i].v[1] * 6.9000001; - c->extra_points[i].v[2] = c->extra_points[i].v[2] * 6.9000001; - } - memcpy(c->max_bounds, c->bounds, sizeof(br_bounds)); - memcpy(&c->max_bounds[1], &c->bounds[1], sizeof(br_bounds)); - for (i = 0; c->extra_point_num > i; ++i) { + c->max_bounds[0] = c->bounds[0]; + c->max_bounds[1] = c->bounds[1]; + for (i = 0; i < c->extra_point_num; i++) { c->original_extra_points_z[i] = c->extra_points[i].v[2]; } - c->maxcurve = c->maxcurve / 6.9; - c->ride_height = c->ride_height * 6.9; + c->maxcurve = c->maxcurve / WORLD_SCALE_D; + c->ride_height = c->ride_height * WORLD_SCALE_D; // JeffH this seems to do nothing since these fields are not yet initialized - for (i = 0; i < 2; ++i) { - c->susp_height[i] = c->susp_height[i] * 6.9; - c->sk[i] = c->sk[i] / 6.9; - c->sb[i] = c->sb[i] / sqrt(c->sb[i]); + for (i = 0; i < COUNT_OF(c->susp_height); i++) { + c->susp_height[i] *= WORLD_SCALE_D; + c->sk[i] /= WORLD_SCALE_D; + c->sb[i] /= sqrt(WORLD_SCALE_D); } GetAString(pF, s); SetCarSuspGiveAndHeight(c, 1.0, 1.0, 1.0, 0.0, 0.0); @@ -1647,24 +1647,19 @@ void GetDamageProgram(FILE* pF, tCar_spec* pCar_spec, tImpact_location pImpact_l strcpy(delim, "\t ,/"); strcat(delim, "&"); - for (i = 0; i < count; i++) { - the_clause = &pCar_spec->damage_programs[pImpact_location].clauses[i]; + for (i = 0, the_clause = pCar_spec->damage_programs[pImpact_location].clauses; i < count; i++, the_clause++) { the_clause->condition_count = 0; GetALineAndDontArgue(pF, s); str = strtok(s, delim); do { - switch (str[0]) { - case 'x': + if (str[0] == 'x') { the_clause->conditions[the_clause->condition_count].axis_comp = 0; - break; - case 'y': + } else if (str[0] == 'y') { the_clause->conditions[the_clause->condition_count].axis_comp = 1; - break; - case 'z': + } else if (str[0] == 'z') { the_clause->conditions[the_clause->condition_count].axis_comp = 2; + } else { break; - default: - goto LABEL_17; } if (str[1] == '>') { the_clause->conditions[the_clause->condition_count].condition_operator = 1; @@ -1677,7 +1672,7 @@ void GetDamageProgram(FILE* pF, tCar_spec* pCar_spec, tImpact_location pImpact_l the_clause->condition_count++; str = strtok(NULL, delim); } while (the_clause->condition_count < 2); - LABEL_17: + the_clause->effect_count = GetAnInt(pF); for (j = 0; j < the_clause->effect_count; j++) { the_clause->effects[j].type = -1; @@ -1695,7 +1690,6 @@ void GetDamageProgram(FILE* pF, tCar_spec* pCar_spec, tImpact_location pImpact_l str = strtok(NULL, "\t ,/"); sscanf(str, "%f", &the_clause->effects[j].weakness_factor); } - ++the_clause; } } @@ -1709,11 +1703,10 @@ intptr_t LinkModel(br_actor* pActor, tModel_pool* pModel_pool) { if (pModel_pool->model_array[i]->identifier && !strcmp(pModel_pool->model_array[i]->identifier, pActor->model->identifier)) { pActor->model = pModel_pool->model_array[i]; - return 0; + break; } } } - // LOG_WARN("failed to link model %s", pActor->model->identifier); return 0; } @@ -1725,7 +1718,7 @@ void FreeUpBonnetModels(br_model** pModel_array, int pModel_count) { // TODO: this causes a use-after-free somewhere... for (i = 0; i < pModel_count; i++) { if (pModel_array[i]) { - if (strcmp("Ebonnet.DAT", pModel_array[i]->identifier) == 0 || strcmp("FIN.DAT", pModel_array[i]->identifier) == 0) { + if (strcmp(pModel_array[i]->identifier, "Ebonnet.DAT") == 0 || strcmp(pModel_array[i]->identifier, "FIN.DAT") == 0) { BrModelRemove(pModel_array[i]); BrModelFree(pModel_array[i]); pModel_array[i] = NULL; @@ -1793,20 +1786,19 @@ int RemoveDoubleSided(br_model* pModel) { if (pModel && pModel->nfaces) { num_double_sided_faces = 0; - for (i = 0; i < pModel->nfaces; i++) { - face = &pModel->faces[i]; + for (i = 0, face = pModel->faces; i < pModel->nfaces; i++, face++) { if (face->material) { if (face->material->user == DOUBLESIDED_USER_FLAG) { num_double_sided_faces++; } } } - if (num_double_sided_faces > 0) { + if (num_double_sided_faces != 0) { faces = BrResAllocate(pModel, sizeof(br_face) * (num_double_sided_faces + pModel->nfaces), kMem_misc); memcpy(faces, pModel->faces, sizeof(br_face) * pModel->nfaces); orig_nfaces = pModel->nfaces; - face = pModel->faces; - for (i = 0; i < orig_nfaces; i++) { + + for (i = 0, face = pModel->faces; i < orig_nfaces; i++, face++) { if (face->material && face->material->user == DOUBLESIDED_USER_FLAG) { faces[pModel->nfaces].vertices[0] = face->vertices[1]; faces[pModel->nfaces].vertices[1] = face->vertices[0]; @@ -1815,7 +1807,6 @@ int RemoveDoubleSided(br_model* pModel) { faces[pModel->nfaces].material = face->material; pModel->nfaces++; } - face++; } BrResFree(pModel->faces); pModel->faces = faces; @@ -1832,14 +1823,12 @@ void MungeWindscreen(br_model* pModel) { int i; if (pModel && pModel->nfaces) { - face = pModel->faces; - for (i = 0; i < pModel->nfaces; i++) { - if (!face->material + for (i = 0, face = pModel->faces; i < pModel->nfaces; i++, face++) { + if (face->material == NULL || (face->material->identifier && gSource_screen_mat != NULL && !strcmp(face->material->identifier, gSource_screen_mat->identifier))) { face->material = gDestn_screen_mat; } - face++; } BrModelUpdate(pModel, BR_MODU_ALL); } @@ -1851,10 +1840,13 @@ void SetModelFlags(br_model* pModel, int pOwner) { if (pModel != NULL && pModel->nfaces != 0) { #if defined(DETHRACE_FIX_BUGS) /* Show Squad Car in the wreck gallery. */ - if (gAusterity_mode) { + if (!gAusterity_mode) { #else - if (pOwner == OPPONENT_APC_IDX || gAusterity_mode) { + if (pOwner != OPPONENT_APC_IDX && !gAusterity_mode) { #endif + pModel->flags |= BR_MODF_DONT_WELD | BR_MODF_KEEP_ORIGINAL | BR_MODF_UPDATEABLE; + BrModelUpdate(pModel, BR_MODU_ALL); + } else { #ifdef DETHRACE_3DFX_PATCH if (!gMaterial_fogging) #endif @@ -1863,11 +1855,8 @@ void SetModelFlags(br_model* pModel, int pOwner) { pModel->flags &= ~(BR_MODF_KEEP_ORIGINAL | BR_MODF_UPDATEABLE); BrModelUpdate(pModel, BR_MODU_ALL); } - return; } } - pModel->flags |= BR_MODF_DONT_WELD | BR_MODF_KEEP_ORIGINAL | BR_MODF_UPDATEABLE; - BrModelUpdate(pModel, BR_MODU_ALL); } } @@ -1949,13 +1938,14 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, PathCat(the_path, the_path, "CARS"); PathCat(the_path, the_path, pCar_name); AllowOpenToFail(); - g = DRfopen(the_path, "rt"); - if (g == NULL) { + h = DRfopen(the_path, "rt"); + DoNotAllowOpenToFail(); + if (h == NULL) { PathCat(the_path, gApplication_path, gGraf_specs[gGraf_spec_index].data_dir_name); PathCat(the_path, the_path, "CARS"); PathCat(the_path, the_path, gBasic_car_names[0]); - g = DRfopen(the_path, "rt"); - if (g == NULL) { + h = DRfopen(the_path, "rt"); + if (h == NULL) { FatalError(kFatalError_OpenResolutionDependentFile); } } @@ -1973,7 +1963,9 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, #endif pCar_spec->driver_name[sizeof(pCar_spec->driver_name) - 1] = '\0'; } else { - strcpy(pCar_spec->driver_name, "X"); + pCar_spec->driver_name[0] = 'X'; + pCar_spec->driver_name[1] = '\0'; + // strcpy(pCar_spec->driver_name, "X"); } pCar_spec->can_be_stolen = 0; pCar_spec->has_been_stolen = 0; @@ -1988,11 +1980,9 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, GetALineAndDontArgue(f, s); if (pDriver == eDriver_local_human) { for (j = 0; j < COUNT_OF(pCar_spec->cockpit_images); j++) { - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); - if (gAusterity_mode) { - pCar_spec->cockpit_images[j] = NULL; - } else { + if (!gAusterity_mode) { the_image = LoadPixelmap(str); if (the_image == NULL) { FatalError(kFatalError_LoadCockpitImage); @@ -2006,8 +1996,10 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, pCar_spec->cockpit_images[j] = ConvertPixToStripMap(the_image); } BrPixelmapFree(the_image); + } else { + pCar_spec->cockpit_images[j] = NULL; } - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->render_left[j]); str = strtok(NULL, "\t ,/"); @@ -2018,32 +2010,32 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, sscanf(str, "%d", &pCar_spec->render_bottom[j]); PossibleService(); } - LoadSpeedo(g, 0, pCar_spec); + LoadSpeedo(h, 0, pCar_spec); if (gAusterity_mode) { - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); } else { - LoadSpeedo(g, 1, pCar_spec); + LoadSpeedo(h, 1, pCar_spec); } PossibleService(); - LoadTacho(g, 0, pCar_spec); + LoadTacho(h, 0, pCar_spec); if (gAusterity_mode) { - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); } else { - LoadTacho(g, 1, pCar_spec); + LoadTacho(h, 1, pCar_spec); } PossibleService(); - LoadGear(g, 0, pCar_spec); + LoadGear(h, 0, pCar_spec); if (gAusterity_mode) { - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); } else { - LoadGear(g, 1, pCar_spec); + LoadGear(h, 1, pCar_spec); } PossibleService(); - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->number_of_hands_images); for (j = 0; j < pCar_spec->number_of_hands_images; j++) { - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->lhands_x[j]); str = strtok(NULL, "\t ,/"); @@ -2082,7 +2074,7 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, sscanf(str, "%f", &pCar_spec->mirror_z_offset); str = strtok(NULL, "\t ,/"); sscanf(str, "%f", &pCar_spec->rearview_camera_angle); - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->mirror_left); str = strtok(NULL, "\t ,/"); @@ -2091,7 +2083,7 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, sscanf(str, "%d", &pCar_spec->mirror_right); str = strtok(NULL, "\t ,/"); sscanf(str, "%d", &pCar_spec->mirror_bottom); - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->prat_left); str = strtok(NULL, "\t ,/"); @@ -2112,29 +2104,29 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, pCar_spec->prat_cam_bottom = LoadPixelmap(str); PossibleService(); for (j = 0; j < COUNT_OF(pCar_spec->damage_units); ++j) { - if (j == eDamage_driver) { - pCar_spec->damage_units[eDamage_driver].images = NULL; - } else { - GetALineAndDontArgue(g, s); + if (j != eDamage_driver) { + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->damage_units[j].x_coord); str = strtok(NULL, "\t ,/"); sscanf(str, "%d", &pCar_spec->damage_units[j].y_coord); for (k = 0; k < COUNT_OF(pCar_spec->damage_units[j].periods); k++) { str = strtok(NULL, "\t ,/"); - sscanf(str, "%f", &temp_float); - rate = 1000.0 / temp_float / 2.0; - pCar_spec->damage_units[j].periods[k] = rate; + sscanf(str, "%f", &rate); + pCar_spec->damage_units[j].periods[k] = 1000.0 / rate / 2.0; } str = strtok(NULL, "\t ,/"); pCar_spec->damage_units[j].images = LoadPixelmap(str); - if (pCar_spec->damage_units[j].images == NULL) + if (pCar_spec->damage_units[j].images == NULL) { FatalError(kFatalError_LoadDamageImage); + } + } else { + pCar_spec->damage_units[j].images = NULL; } pCar_spec->damage_units[j].damage_level = 0; PossibleService(); } - GetALineAndDontArgue(g, s); + GetALineAndDontArgue(h, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->damage_x_offset); str = strtok(NULL, "\t ,/"); @@ -2146,11 +2138,11 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, str = strtok(NULL, "\t ,/"); pCar_spec->damage_background = LoadPixelmap(str); + pCar_spec->dim_count[0] = GetAnInt(h); for (i = 0; i < COUNT_OF(pCar_spec->dim_count); i++) { - pCar_spec->dim_count[i] = GetAnInt(g); for (j = 0; j < pCar_spec->dim_count[i]; j++) GetFourInts( - g, + h, &pCar_spec->dim_left[i][j], &pCar_spec->dim_top[i][j], &pCar_spec->dim_right[i][j], @@ -2158,26 +2150,26 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, } PathCat(the_path, gApplication_path, gGraf_specs[gGraf_spec_index].data_dir_name); PathCat(the_path, the_path, "HEADUP.TXT"); - h = DRfopen(the_path, "rt"); - if (h == NULL) { + g = DRfopen(the_path, "rt"); + if (g == NULL) { FatalError(kFatalError_OpenHeadupsFile); } PossibleService(); - LoadHeadups(h, 0, pCar_spec); - LoadHeadups(h, 1, pCar_spec); + LoadHeadups(g, 0, pCar_spec); + LoadHeadups(g, 1, pCar_spec); PossibleService(); - fclose(h); + fclose(g); PathCat(the_path, gApplication_path, "PARTSHOP.TXT"); - h = DRfopen(the_path, "rt"); - if (h == NULL) { + g = DRfopen(the_path, "rt"); + if (g == NULL) { FatalError(kFatalError_OpenPartsshopFile); } for (i = 0; i < COUNT_OF(pCar_spec->power_ups); ++i) { - GetALineAndDontArgue(h, s); + GetALineAndDontArgue(g, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->power_ups[i].number_of_parts); for (j = 0; j < pCar_spec->power_ups[i].number_of_parts; j++) { - GetALineAndDontArgue(h, s); + GetALineAndDontArgue(g, s); str = strtok(s, "\t ,/"); sscanf(str, "%d", &pCar_spec->power_ups[i].info[j].rank_required); str = strtok(NULL, "\t ,/"); @@ -2190,19 +2182,19 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, } PossibleService(); } - fclose(h); + fclose(g); AdjustCarCoordinates(&gProgram_state.current_car); AdjustRenderScreenSize(); PossibleService(); ReinitialiseRearviewCamera(); GetALineAndDontArgue(f, s); } else { - while (!feof(f)) { + do { GetALineAndDontArgue(f, s); - if (strcmp(s, "END OF DRIVABLE STUFF") == 0) { - break; - } - } + // if (strcmp(s, "END OF DRIVABLE STUFF") == 0) { + // break; + // } + } while (!feof(f) && strcmp(s, "END OF DRIVABLE STUFF") != 0); pCar_spec->red_line = 8000; } PossibleService(); @@ -2227,14 +2219,14 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, LoadSomePixelmaps(pStorage_space, f); SkipNLines(f); SkipNLines(f); - } else if (gGraf_data_index) { - SkipNLines(f); + } else if (gGraf_data_index == 0) { SkipNLines(f); LoadSomePixelmaps(pStorage_space, f); + SkipNLines(f); } else { SkipNLines(f); - LoadSomePixelmaps(pStorage_space, f); SkipNLines(f); + LoadSomePixelmaps(pStorage_space, f); } LoadSomeShadeTables(pStorage_space, f); old_material_count = pStorage_space->materials_count; @@ -2242,22 +2234,25 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, LoadSomeMaterials(pStorage_space, f); SkipNLines(f); SkipNLines(f); - } else if (gGraf_data_index) { - SkipNLines(f); + } else if (gGraf_data_index == 0) { SkipNLines(f); LoadSomeMaterials(pStorage_space, f); + SkipNLines(f); } else { SkipNLines(f); - LoadSomeMaterials(pStorage_space, f); SkipNLines(f); + LoadSomeMaterials(pStorage_space, f); } number_of_floorpans = 5; for (i = old_material_count; i < pStorage_space->materials_count; i++) { if (pStorage_space->materials[i] != NULL && pStorage_space->materials[i]->colour_map != NULL) { - pStorage_space->materials[i]->flags |= BR_MATF_LIGHT | BR_MATF_PRELIT | BR_MATF_SMOOTH; + pStorage_space->materials[i]->flags |= (BR_MATF_LIGHT | BR_MATF_PRELIT); + pStorage_space->materials[i]->flags |= BR_MATF_SMOOTH; +#ifdef DETHRACE_FIX_BUGS // Added by jeff. This seems to be required with BRender 1.3.2 pStorage_space->materials[i]->flags &= ~BR_MATF_LIGHT; +#endif if (pStorage_space->materials[i]->flags & BR_MATF_TWO_SIDED) { its_a_floorpan = 0; for (j = 0; j < number_of_floorpans; j++) { @@ -2266,10 +2261,12 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, break; } } - if (!its_a_floorpan) { + if (its_a_floorpan) { + pStorage_space->materials[i]->flags &= ~BR_MATF_TWO_SIDED; + } else { pStorage_space->materials[i]->user = DOUBLESIDED_USER_FLAG; + pStorage_space->materials[i]->flags &= ~BR_MATF_TWO_SIDED; } - pStorage_space->materials[i]->flags &= ~BR_MATF_TWO_SIDED; } pStorage_space->materials[i]->index_shade = gShade_list[0]; BrMaterialUpdate(pStorage_space->materials[i], BR_MATU_ALL); @@ -2294,14 +2291,14 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, str = strtok(s, "\t ,/"); sscanf(str, "%f", &temp_float); if (temp_float < 0.f && pDriver != eDriver_local_human) { - FreeUpBonnetModels(&pStorage_space->models[old_model_count], pStorage_space->models_count - old_model_count); + FreeUpBonnetModels(pStorage_space->models + old_model_count, pStorage_space->models_count - old_model_count); pCar_spec->car_actor_count--; break; } - if (temp_float >= 1.f) { - pCar_spec->car_model_actors[i].min_distance_squared = temp_float * temp_float; - } else { + if (temp_float < 1.f) { pCar_spec->car_model_actors[i].min_distance_squared = temp_float; + } else { + pCar_spec->car_model_actors[i].min_distance_squared = temp_float * temp_float; } str = strtok(NULL, "\t ,/"); PathCat(the_path, gApplication_path, "ACTORS"); @@ -2323,10 +2320,10 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, pCar_spec->principal_car_actor = i; } } - if (pDriver != eDriver_local_human && pCar_spec->car_model_actors[pCar_spec->car_actor_count - 1].min_distance_squared < 0.f) { - SwitchCarActor(pCar_spec, pCar_spec->car_actor_count - 2); - } else { + if (pDriver == eDriver_local_human || pCar_spec->car_model_actors[pCar_spec->car_actor_count - 1].min_distance_squared >= 0.f) { SwitchCarActor(pCar_spec, pCar_spec->car_actor_count - 1); + } else { + SwitchCarActor(pCar_spec, pCar_spec->car_actor_count - 2); } GetAString(f, s); pCar_spec->screen_material = BrMaterialFind(s); @@ -2417,16 +2414,14 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, AddGroovidelics(f, pOwner, pCar_spec->car_master_actor, gGroove_funk_offset, 1); for (i = 0; i < pCar_spec->car_actor_count; i++) { PossibleService(); - if (pOwner == OPPONENT_APC_IDX || gAusterity_mode) { + if (pOwner != OPPONENT_APC_IDX && !gAusterity_mode) { + ReadCrushData(f, &pCar_spec->car_model_actors[i].crush_data); + } else { pCar_spec->car_model_actors[i].crush_data.softness_factor = SkipCrushData(f); pCar_spec->car_model_actors[i].crush_data.crush_points = NULL; pCar_spec->car_model_actors[i].crush_data.number_of_crush_points = 0; - } else { - ReadCrushData(f, &pCar_spec->car_model_actors[i].crush_data); } - if (pCar_spec->driver < eDriver_net_human || gAusterity_mode) { - pCar_spec->car_model_actors[i].undamaged_vertices = NULL; - } else { + if (pCar_spec->driver >= eDriver_net_human && !gAusterity_mode) { PossibleService(); vertex_array_size = sizeof(br_vertex) * pCar_spec->car_model_actors[i].actor->model->nvertices; pCar_spec->car_model_actors[i].undamaged_vertices = BrMemAllocate(vertex_array_size, kMem_undamaged_vertices); @@ -2434,6 +2429,8 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, pCar_spec->car_model_actors[i].undamaged_vertices, pCar_spec->car_model_actors[i].actor->model->vertices, vertex_array_size); + } else { + pCar_spec->car_model_actors[i].undamaged_vertices = NULL; } } if (pDriver != eDriver_local_human) { @@ -2449,16 +2446,15 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, ReadShrapnelMaterials(f, (tCollision_info*)pCar_spec); vertex_total = 0; model = pCar_spec->car_model_actors[pCar_spec->principal_car_actor].actor->model; - for (i = 0; i < V11MODEL(model)->ngroups; i++) { - vertex_total += V11MODEL(model)->groups[i].nvertices; + for (group = 0; group < V11MODEL(model)->ngroups; group++) { + // non-matching assembly due to using open sourced BRender 1.3.2 struct + vertex_total += V11MODEL(model)->groups[group].nvertices; } for (i = 0; i < COUNT_OF(pCar_spec->fire_vertex); i++) { if (feof(f)) { - initial_vertex = IRandomBetween(0, vertex_total - 1); - pCar_spec->fire_vertex[i] = initial_vertex; + pCar_spec->fire_vertex[i] = IRandomBetween(0, vertex_total - 1); } else { - initial_vertex = GetAnInt(f); - pCar_spec->fire_vertex[i] = initial_vertex; + pCar_spec->fire_vertex[i] = GetAnInt(f); if (pCar_spec->fire_vertex[i] >= vertex_total) { pCar_spec->fire_vertex[i] = 0; } @@ -2476,7 +2472,7 @@ void LoadCar(char* pCar_name, tDriver pDriver, tCar_spec* pCar_spec, int pOwner, } } fclose(f); - fclose(g); + fclose(h); #if DETHRACE_FIX_BUGS #define CHECK_BINDING_INDEX(IDX) \ @@ -2598,57 +2594,61 @@ void LoadRaces(tRace_list_spec* pRace_list, int* pCount, int pRace_type_index) { int j; int k; int number_of_racers; - int last_race = 0; + int last_race; char s[256]; char* str; gCurrent_race_file_index = pRace_type_index + 1; f = OpenRaceFile(); - number_of_racers = 0; - for (i = 0; !last_race; i++) { - GetALineAndDontArgue(f, s); - if (strcmp(s, "END") == 0) { + i = 0; + + do { + GetALineAndDontArgue(f, pRace_list[i].name); + if (strcmp(pRace_list[i].name, "END") == 0) { last_race = 1; } else { - strcpy(pRace_list[i].name, s); SkipRestOfRace(f); - // s = (s + 48); - number_of_racers++; + i++; + last_race = 0; } - } + } while (!last_race); - *pCount = number_of_racers; + *pCount = i; fclose(f); - j = 0; + +#ifdef DETHRACE_FIX_BUGS if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) { j = 99; } - for (i = 0; i < number_of_racers; i++) { +#endif + for (i = 0; i < *pCount; i++) { +#ifdef DETHRACE_FIX_BUGS if (harness_game_info.mode == eGame_carmageddon_demo || harness_game_info.mode == eGame_splatpack_demo || harness_game_info.mode == eGame_splatpack_xmas_demo) { pRace_list[i].suggested_rank = gDemo_rank; pRace_list[i].rank_required = j; j -= 3; - } else { - pRace_list[i].suggested_rank = 99 - j / (number_of_racers - 3); + } else +#endif + { + pRace_list[i].suggested_rank = 99 - 100 * i / (*pCount - 3); if (i >= 3) { pRace_list[i].rank_required = pRace_list[i - 2].suggested_rank; } else { pRace_list[i].rank_required = 99; } - j += 100; } } - pRace_list[number_of_racers - 1].rank_required = 1; - if (pRace_list[number_of_racers - 2].rank_required == 1) { + pRace_list[*pCount - 1].rank_required = 1; + if (pRace_list[*pCount - 2].rank_required == 1) { --*pCount; } - for (i = 0; i < number_of_racers; i++) { - if (i < *pCount - 3) { - pRace_list[i].best_rank = pRace_list[i + 3].suggested_rank; - } else { + for (i = 0; i < *pCount; i++) { + if (i >= *pCount - 3) { pRace_list[i].best_rank = 1; + } else { + pRace_list[i].best_rank = pRace_list[i + 3].suggested_rank + 1; } } } @@ -2675,6 +2675,7 @@ void LoadOpponentMugShot(int pIndex) { &gOpponents[pIndex].mug_shot_image_data, &gOpponents[pIndex].mug_shot_image_data_length)) { FatalError(kFatalError_LoadOpponentMugShotFile); + return; } MAMSLock((void**)&gOpponents[pIndex].mug_shot_image_data); } @@ -2723,7 +2724,9 @@ void LoadRaceInfo(int pRace_index, tRace_info* pRace_info) { tText_chunk* the_chunk; f = OpenRaceFile(); - for (temp_index = pRace_index; temp_index != 0; temp_index--) { + temp_index = pRace_index; + + while (temp_index--) { PossibleService(); GetALineAndDontArgue(f, s); SkipRestOfRace(f); @@ -2761,14 +2764,13 @@ void LoadRaceInfo(int pRace_index, tRace_info* pRace_info) { pRace_info->text_chunk_count = GetAnInt(f); pRace_info->text_chunks = BrMemAllocate(sizeof(tText_chunk) * pRace_info->text_chunk_count, kMem_race_text_chunk); - the_chunk = pRace_info->text_chunks; - for (i = 0; i < pRace_info->text_chunk_count; i++) { + for (j = 0, the_chunk = pRace_info->text_chunks; j < pRace_info->text_chunk_count; j++, the_chunk++) { PossibleService(); GetPairOfInts(f, &the_chunk->x_coord, &the_chunk->y_coord); GetPairOfInts(f, &the_chunk->frame_cue, &the_chunk->frame_end); the_chunk->line_count = GetAnInt(f); while (the_chunk->line_count > 8) { - --the_chunk->line_count; + the_chunk->line_count--; GetALineAndDontArgue(f, s); } for (k = 0; k < the_chunk->line_count; k++) { @@ -2776,7 +2778,6 @@ void LoadRaceInfo(int pRace_index, tRace_info* pRace_info) { the_chunk->text[k] = BrMemAllocate(strlen(s) + 1, kMem_race_text_str); strcpy(the_chunk->text[k], s); } - the_chunk++; } fclose(f); } @@ -2790,15 +2791,13 @@ void DisposeRaceInfo(tRace_info* pRace_info) { tText_chunk* the_chunk; if (gNet_mode == eNet_mode_none) { - the_chunk = pRace_info->text_chunks; - for (i = 0; i < pRace_info->text_chunk_count; i++) { + for (j = 0, the_chunk = pRace_info->text_chunks; j < pRace_info->text_chunk_count; j++, the_chunk++) { PossibleService(); - for (j = 0; j < the_chunk->line_count; j++) { - if (the_chunk->text[j]) { - BrMemFree(the_chunk->text[j]); + for (k = 0; k < the_chunk->line_count; k++) { + if (the_chunk->text[k]) { + BrMemFree(the_chunk->text[k]); } } - the_chunk++; } if (pRace_info->text_chunks) { BrMemFree(pRace_info->text_chunks); @@ -2813,8 +2812,8 @@ void DisposeRaceInfo(tRace_info* pRace_info) { if (pRace_info->info_image_data) { BrMemFree(pRace_info->info_image_data); } - for (k = 0; k < pRace_info->number_of_racers; k++) { - UnlockOpponentMugshot(pRace_info->opponent_list[k].index); + for (i = 0; i < pRace_info->number_of_racers; i++) { + UnlockOpponentMugshot(pRace_info->opponent_list[i].index); } PossibleService(); } @@ -2946,21 +2945,19 @@ br_font* LoadBRFont(char* pName) { the_font->flags = BrSwap32(the_font->flags); // swap endianness - the_font->glyph_x = the_font->glyph_x >> 8 | the_font->glyph_x << 8; - the_font->glyph_y = the_font->glyph_y >> 8 | the_font->glyph_y << 8; - the_font->spacing_x = the_font->spacing_x >> 8 | the_font->spacing_x << 8; - the_font->spacing_y = the_font->spacing_y >> 8 | the_font->spacing_y << 8; + the_font->glyph_x = the_font->glyph_x >> 8 | (the_font->glyph_x & 0xff) << 8; + the_font->glyph_y = the_font->glyph_y >> 8 | (the_font->glyph_y & 0xff) << 8; + the_font->spacing_x = the_font->spacing_x >> 8 | (the_font->spacing_x & 0xff) << 8; + the_font->spacing_y = the_font->spacing_y >> 8 | (the_font->spacing_y & 0xff) << 8; #endif - data_size = sizeof(br_int_8) * 256; - the_font->width = BrMemAllocate(data_size, kMem_br_font_wid); - fread(the_font->width, data_size, 1, f); - data_size = sizeof(br_uint_16) * 256; - the_font->encoding = BrMemAllocate(data_size, kMem_br_font_enc); - fread(the_font->encoding, data_size, 1u, f); + the_font->width = BrMemAllocate(sizeof(br_int_8) * 256, kMem_br_font_wid); + fread(the_font->width, sizeof(br_int_8) * 256, 1, f); + the_font->encoding = BrMemAllocate(sizeof(br_uint_16) * 256, kMem_br_font_enc); + fread(the_font->encoding, sizeof(br_uint_16) * 256, 1u, f); #if !BR_ENDIAN_BIG for (i = 0; i < 256; i++) { - the_font->encoding[i] = the_font->encoding[i] >> 8 | the_font->encoding[i] << 8; + the_font->encoding[i] = ((the_font->encoding[i] & 0xff) << 8) | ((the_font->encoding[i] >> 8)); } #endif PossibleService(); @@ -3193,8 +3190,7 @@ void GetPairOfScalars(FILE* pF, br_scalar* pS1, br_scalar* pS2) { // IDA: void __usercall GetThreeScalars(FILE *pF@, br_scalar *pS1@, br_scalar *pS2@, br_scalar *pS3@) // FUNCTION: CARM95 0x00425d98 void GetThreeScalars(FILE* pF, br_scalar* pS1, br_scalar* pS2, br_scalar* pS3) { - - GetThreeFloats(pF, pS1, pS2, pS3); + ReadThreeFloats(pF, *pS1, *pS2, *pS3); } // IDA: void __usercall GetFourScalars(FILE *pF@, br_scalar *pF1@, br_scalar *pF2@, br_scalar *pF3@, br_scalar *pF4) @@ -3356,12 +3352,12 @@ void LoadMiscStrings(void) { FatalError(kFatalError_OpenTextTxt); } for (i = 0; i < 250; i++) { - GetALineAndDontArgue(f, s); - gMisc_strings[i] = BrMemAllocate(strlen(s) + 1, kMem_misc_string); - strcpy(gMisc_strings[i], s); if (feof(f)) { break; } + GetALineAndDontArgue(f, s); + gMisc_strings[i] = BrMemAllocate(strlen(s) + 1, kMem_misc_string); + strcpy(gMisc_strings[i], s); } fclose(f); } @@ -3387,96 +3383,124 @@ FILE* OldDRfopen(char* pFilename, char* pMode) { // GLOBAL: CARM95 0x50a5e0 static int source_exists = 1; int len; - char ch; +#ifdef DETHRACE_FIX_BUGS fp = Harness_Hook_fopen(pFilename, pMode); +#else + fp = fopen(pFilename, pMode); +#endif - if (fp != NULL) { + if (fp == NULL) { + if (gCD_fully_installed) { + return NULL; + } + // source_exists = 1 means we haven't checked the CD yet + if (source_exists == 1) { + source_check[0] = '\0'; + strcpy(source_check, "DATA"); + strcat(source_check, gDir_separator); + strcat(source_check, "GENERAL.TXT"); + path_file[0] = '\0'; + strcpy(path_file, gApplication_path); + strcat(path_file, gDir_separator); + strcat(path_file, "PATHS.TXT"); + + if (!PDCheckDriveExists(path_file)) { + source_exists = 0; + LOG_WARN("PATHS.TXT not found"); + return NULL; + } + test1 = fopen(path_file, "rt"); + if (!test1) { + source_exists = 0; + LOG_WARN("PATHS.TXT couldnt be opened"); + return NULL; + } + + CD_dir[0] = '\0'; + GetALineAndDontArgue(test1, CD_dir); + if (!strchr(gDir_separator, CD_dir[strlen(CD_dir) - 1])) { + strcat(CD_dir, gDir_separator); + } + strcat(CD_dir, source_check); + fclose(test1); + + if (!PDCheckDriveExists(CD_dir)) { + PDFatalError("Carmageddon CD not in drive."); + if (gCD_fully_installed) { + source_exists = 0; + } + } else { + source_exists++; + } + } + if (source_exists) { + data_dir = strstr(pFilename, "DATA"); + if (data_dir == NULL) { + return NULL; + } + if (GetCDPathFromPathsTxtFile(CD_dir) == 0) { + return NULL; + } + if (!strchr(gDir_separator, CD_dir[strlen(CD_dir) - 1])) { + strcat(CD_dir, gDir_separator); + } + strcat(CD_dir, data_dir); + if (PDCheckDriveExists(CD_dir) == 0) { + return NULL; + } + fp = fopen(CD_dir, pMode); + if (!fp) { + } + } + } else { + +#ifdef DETHRACE_FIX_BUGS // Demo does not check gDecode_thing ("i am fiddling" in PROG.ACT) // If the text file starts with a '@' character, it will be decoded, otherwise used as-is. if (harness_game_info.mode == eGame_carmageddon_demo) { return fp; - } else { - len = strlen(pFilename); - if (gDecode_thing != 0) { - if (strcmp(&pFilename[len - 4], ".TXT") == 0 - && strcmp(&pFilename[len - 12], "DKEYMAP0.TXT") != 0 - && strcmp(&pFilename[len - 12], "DKEYMAP1.TXT") != 0 - && strcmp(&pFilename[len - 12], "DKEYMAP2.TXT") != 0 - && strcmp(&pFilename[len - 12], "DKEYMAP3.TXT") != 0 - && strcmp(&pFilename[len - 12], "KEYMAP_0.TXT") != 0 - && strcmp(&pFilename[len - 12], "KEYMAP_1.TXT") != 0 - && strcmp(&pFilename[len - 12], "KEYMAP_2.TXT") != 0 - && strcmp(&pFilename[len - 12], "KEYMAP_3.TXT") != 0 - && strcmp(&pFilename[len - 11], "OPTIONS.TXT") != 0 - && strcmp(&pFilename[len - 12], "KEYNAMES.TXT") != 0 - && strcmp(&pFilename[len - 10], "KEYMAP.TXT") != 0 - && strcmp(&pFilename[len - 9], "PATHS.TXT") != 0 - && strcmp(&pFilename[len - 11], "PRATCAM.TXT") != 0) { - ch = fgetc(fp); - if (ch != gDecode_thing) { - fclose(fp); - return NULL; - } - ungetc(ch, fp); - return fp; + } +#endif + len = strlen(pFilename); + if (gDecode_thing != 0) { + if (strcmp(&pFilename[len - 4], ".TXT") == 0 + && strcmp(&pFilename[len - 12], "DKEYMAP0.TXT") != 0 + && strcmp(&pFilename[len - 12], "DKEYMAP1.TXT") != 0 + && strcmp(&pFilename[len - 12], "DKEYMAP2.TXT") != 0 + && strcmp(&pFilename[len - 12], "DKEYMAP3.TXT") != 0 + && strcmp(&pFilename[len - 12], "KEYMAP_0.TXT") != 0 + && strcmp(&pFilename[len - 12], "KEYMAP_1.TXT") != 0 + && strcmp(&pFilename[len - 12], "KEYMAP_2.TXT") != 0 + && strcmp(&pFilename[len - 12], "KEYMAP_3.TXT") != 0 + && strcmp(&pFilename[len - 11], "OPTIONS.TXT") != 0 + && strcmp(&pFilename[len - 12], "KEYNAMES.TXT") != 0 + && strcmp(&pFilename[len - 10], "KEYMAP.TXT") != 0 + && strcmp(&pFilename[len - 9], "PATHS.TXT") != 0 + && strcmp(&pFilename[len - 11], "PRATCAM.TXT") != 0) { + + char ch; + + // Not sure if this was an artifact of a "/Oi" codepath or a macro directly used here (and only here..!) by Stainess +#if _MSC_VER == 1020 + if (--fp->_cnt >= 0) { + ch = *fp->_ptr++; + } else { + ch = _filbuf(fp); } +#else + ch = fgetc(fp); +#endif + if (ch != gDecode_thing) { + fclose(fp); + return NULL; + } + ungetc(ch, fp); } } } - if (gCD_fully_installed) { - return fp; - } - // source_exists = 1 means we haven't checked the CD yet - if (source_exists == 1) { - strcpy(path_file, "DATA"); - strcat(path_file, gDir_separator); - strcat(path_file, "PATHS.TXT"); - - if (!PDCheckDriveExists(path_file)) { - source_exists = 0; - LOG_WARN("PATHS.TXT not found"); - return NULL; - } - test1 = fopen(path_file, "rt"); - if (!test1) { - source_exists = 0; - LOG_WARN("PATHS.TXT couldnt be opened"); - return NULL; - } - - GetALineAndDontArgue(test1, source_check); - strcat(source_check, gDir_separator); - strcat(source_check, "DATA"); - strcat(source_check, gDir_separator); - strcat(source_check, "GENERAL.TXT"); - - fclose(test1); - if (PDCheckDriveExists(source_check)) { - source_exists++; - } else { - PDFatalError("Carmageddon CD not in drive."); - if (gCD_fully_installed) { - source_exists = 0; - } - } - } - if (!source_exists) { - return fp; - } - - data_dir = strstr(pFilename, "DATA"); - if (data_dir != NULL) { - if (GetCDPathFromPathsTxtFile(CD_dir)) { - strcat(CD_dir, gDir_separator); - strcat(CD_dir, data_dir); - if (PDCheckDriveExists(CD_dir)) { - fp = fopen(CD_dir, pMode); - } - } - } return fp; } @@ -3488,9 +3512,11 @@ void AllowOpenToFail(void) { } // IDA: void __cdecl DoNotAllowOpenToFail() +// FUNCTION: CARM95 0x00426578 void DoNotAllowOpenToFail(void) { - gAllow_open_to_fail = 0; + // this function has an empty body in retail executables + // gAllow_open_to_fail = 0; } // IDA: FILE* __usercall DRfopen@(char *pFilename@, char *pMode@) @@ -3545,66 +3571,115 @@ int GetCDPathFromPathsTxtFile(char* pPath_name) { int TestForOriginalCarmaCDinDrive(void) { // The symbol dump didn't include any local variable information. // These names are not necessarily the original names. - tPath_name cd_pathname; - tPath_name cd_data_pathname; - tPath_name cutscene_pathname; - FILE* paths_txt_fp; - tPath_name paths_txt; - int paths_txt_first_char; + char CD_dir[512]; // [esp+Ch] [ebp-608h] BYREF + char ch; // [esp+20Ch] [ebp-408h] + tPath_name path_file; // [esp+210h] [ebp-404h] BYREF + char CD_data_dir[512]; // [esp+310h] [ebp-304h] BYREF + FILE* fp; // [esp+510h] [ebp-104h] + tPath_name cutscene_dir; // [esp+514h] [ebp-100h] BYREF +#ifdef DETHRACE_FIX_BUGS if (harness_game_config.enable_cd_check == 0) { return 1; } +#endif - paths_txt[0] = 0; - strcat(paths_txt, gApplication_path); - strcat(paths_txt, gDir_separator); - strcat(paths_txt, "PATHS.TXT"); - - if (!PDCheckDriveExists(paths_txt)) { + path_file[0] = 0; + strcpy(path_file, gApplication_path); + strcat(path_file, gDir_separator); + strcat(path_file, "PATHS.TXT"); + if (!PDCheckDriveExists(path_file)) { return 0; } - - paths_txt_fp = fopen(paths_txt, "rt"); - if (!paths_txt_fp) { + fp = fopen(path_file, "rt"); + if (!fp) { return 0; } - paths_txt_first_char = fgetc(paths_txt_fp); - ungetc(paths_txt_first_char, paths_txt_fp); - GetALineAndDontArgue(paths_txt_fp, cd_pathname); - fclose(paths_txt_fp); - strcpy(cd_data_pathname, cd_pathname); - strcat(cd_data_pathname, gDir_separator); - strcat(cd_data_pathname, "DATA"); - - if (DRStricmp(cd_pathname, gApplication_path) == 0) { + ch = fgetc(fp); + ungetc(ch, fp); + CD_dir[0] = 0; + GetALineAndDontArgue(fp, CD_dir); + fclose(fp); + strcpy(CD_data_dir, CD_dir); + if (!strchr(gDir_separator, CD_data_dir[strlen(CD_data_dir) - 1])) { + strcat(CD_data_dir, gDir_separator); + } + strcat(CD_data_dir, "DATA"); + if (!DRStricmp(CD_data_dir, gApplication_path)) { return 0; } - - strcpy(cutscene_pathname, cd_data_pathname); - strcat(cutscene_pathname, gDir_separator); - strcat(cutscene_pathname, "CUTSCENE"); - - if (!PDCheckDriveExists2(cd_data_pathname, "GENERAL.TXT", 100)) { + strcpy(cutscene_dir, CD_data_dir); + if (!strchr(gDir_separator, cutscene_dir[strlen(cutscene_dir) - 1])) { + strcat(cutscene_dir, gDir_separator); + } + strcat(cutscene_dir, "CUTSCENE"); + if (!PDCheckDriveExists2(CD_data_dir, "GENERAL.TXT", 100) + || (!PDCheckDriveExists2(CD_dir, "CARMA.EXE", 0xF4240) + && !PDCheckDriveExists2(CD_dir, "CARMAG.EXE", 1000000) + && !PDCheckDriveExists2(CD_dir, "MAINPROG.EXE", 1000000) + && !PDCheckDriveExists2(CD_dir, "CARMSPLT.EXE", 1000000) + && !PDCheckDriveExists2(CD_dir, "CARMGSPL.EXE", 1000000)) +#ifdef DETHRACE_FIX_BUGS + || !PDCheckDriveExists2(cutscene_dir, harness_game_info.defines.INTRO_SMK_FILE, 2000000)) { +#else + || !PDCheckDriveExists2(cutscene_dir, "SPLINTRO.SMK", 2000000)) { +#endif return 0; } - if (!PDCheckDriveExists2(cd_pathname, "CARMA.EXE", 1000000) - && !PDCheckDriveExists2(cd_pathname, "CARMAG.EXE", 1000000) - && !PDCheckDriveExists2(cd_pathname, "MAINPROG.EXE", 1000000) - && !PDCheckDriveExists2(cd_pathname, "CARMSPLT.EXE", 1000000) - && !PDCheckDriveExists2(cd_pathname, "CARMGSPL.EXE", 1000000)) { - return 0; - } - - // changed from static file reference to handle all game modes - if (!PDCheckDriveExists2(cutscene_pathname, harness_game_info.defines.INTRO_SMK_FILE, 2000000)) { - return 0; - } - - if (paths_txt_first_char != '@') { - EncodeFile(paths_txt); + if (ch != '@') { + EncodeFile(path_file); } return 1; + + // paths_txt[0] = 0; + // strcat(paths_txt, gApplication_path); + // strcat(paths_txt, gDir_separator); + // strcat(paths_txt, "PATHS.TXT"); + + // if (!PDCheckDriveExists(paths_txt)) { + // return 0; + // } + + // paths_txt_fp = fopen(paths_txt, "rt"); + // if (!paths_txt_fp) { + // return 0; + // } + // paths_txt_first_char = fgetc(paths_txt_fp); + // ungetc(paths_txt_first_char, paths_txt_fp); + // GetALineAndDontArgue(paths_txt_fp, cd_pathname); + // fclose(paths_txt_fp); + // strcpy(cd_data_pathname, cd_pathname); + // strcat(cd_data_pathname, gDir_separator); + // strcat(cd_data_pathname, "DATA"); + + // if (DRStricmp(cd_pathname, gApplication_path) == 0) { + // return 0; + // } + + // strcpy(cutscene_pathname, cd_data_pathname); + // strcat(cutscene_pathname, gDir_separator); + // strcat(cutscene_pathname, "CUTSCENE"); + + // if (!PDCheckDriveExists2(cd_data_pathname, "GENERAL.TXT", 100)) { + // return 0; + // } + // if (!PDCheckDriveExists2(cd_pathname, "CARMA.EXE", 1000000) + // && !PDCheckDriveExists2(cd_pathname, "CARMAG.EXE", 1000000) + // && !PDCheckDriveExists2(cd_pathname, "MAINPROG.EXE", 1000000) + // && !PDCheckDriveExists2(cd_pathname, "CARMSPLT.EXE", 1000000) + // && !PDCheckDriveExists2(cd_pathname, "CARMGSPL.EXE", 1000000)) { + // return 0; + // } + + // // changed from static file reference to handle all game modes + // if (!PDCheckDriveExists2(cutscene_pathname, harness_game_info.defines.INTRO_SMK_FILE, 2000000)) { + // return 0; + // } + + // if (paths_txt_first_char != '@') { + // EncodeFile(paths_txt); + // } + // return 1; } // IDA: int __cdecl OriginalCarmaCDinDrive() @@ -3619,9 +3694,8 @@ int CarmaCDinDriveOrFullGameInstalled(void) { if (gCD_fully_installed) { return 1; - } else { - return OriginalCarmaCDinDrive(); } + return OriginalCarmaCDinDrive(); } // IDA: void __usercall ReadNetworkSettings(FILE *pF@, tNet_game_options *pOptions@) @@ -3673,54 +3747,43 @@ int SaveOptions(void) { gMap_render_y = 6.f; gMap_render_width = 64.f; gMap_render_height = 40.f; - if (f == NULL) { + + if (f == NULL + || fprintf(f, "YonFactor %f\n", GetYonFactor()) < 0 + || fprintf(f, "SkyTextureOn %d\n", GetSkyTextureOn()) < 0 + || fprintf(f, "CarTexturingLevel %d\n", GetCarTexturingLevel()) < 0 + || fprintf(f, "RoadTexturingLevel %d\n", GetRoadTexturingLevel()) < 0 + || fprintf(f, "WallTexturingLevel %d\n", GetWallTexturingLevel()) < 0 + || fprintf(f, "ShadowLevel %d\n", GetShadowLevel()) < 0 + || fprintf(f, "DepthCueingOn %d\n", GetDepthCueingOn()) < 0 + || fprintf(f, "Yon %f\n", GetYon()) < 0 + || fprintf(f, "CarSimplificationLevel %d\n", GetCarSimplificationLevel()) < 0 + || fprintf(f, "AccessoryRendering %d\n", GetAccessoryRendering()) < 0 + || fprintf(f, "SmokeOn %d\n", GetSmokeOn()) < 0 + || fprintf(f, "SoundDetailLevel %d\n", GetSoundDetailLevel()) < 0 + || fprintf(f, "ScreenSize %d\n", GetScreenSize()) < 0 + || fprintf(f, "MapRenderX %f\n", gMap_render_x) < 0 + || fprintf(f, "MapRenderY %f\n", gMap_render_y) < 0 + || fprintf(f, "MapRenderWidth %f\n", gMap_render_width) < 0 + || fprintf(f, "MapRenderHeight %f\n", gMap_render_height) < 0 + || fprintf(f, "PlayerName 0\n%s\n", (gProgram_state.player_name[0][0] != '\0') ? gProgram_state.player_name[0] : "MAX DAMAGE") < 0 + || fprintf(f, "PlayerName 1\n%s\n", (gProgram_state.player_name[1][0] != '\0') ? gProgram_state.player_name[1] : "DIE ANNA") < 0 + || fprintf(f, "NetName 0\n%s\n", (gNet_player_name[0] != '\0') ? gNet_player_name : "RON TURN") < 0 + || fprintf(f, "EVolume %d\n", gProgram_state.effects_volume) < 0 + || fprintf(f, "MVolume %d\n", gProgram_state.music_volume) < 0 + || fprintf(f, "KeyMapIndex %d\n", gKey_map_index) < 0 + || fprintf(f, "NETGAMETYPE %d\n", gLast_game_type) < 0 + || PrintNetOptions(f, 0) < 0 + || PrintNetOptions(f, 1) < 0 + || PrintNetOptions(f, 2) < 0 + || PrintNetOptions(f, 3) < 0 + || PrintNetOptions(f, 4) < 0 + || PrintNetOptions(f, 5) < 0 + || PrintNetOptions(f, 6) < 0 + || PrintNetOptions(f, 7) < 0 + || fclose(f) != 0) { return 0; } - -#define BAIL_IF_NEGATIVE(VAL) \ - if ((VAL) < 0) { \ - LOG_WARN(#VAL " FAILED\n"); \ - return 0; \ - } - - BAIL_IF_NEGATIVE(fprintf(f, "YonFactor %f\n", GetYonFactor())); - BAIL_IF_NEGATIVE(fprintf(f, "SkyTextureOn %d\n", GetSkyTextureOn())); - BAIL_IF_NEGATIVE(fprintf(f, "CarTexturingLevel %d\n", GetCarTexturingLevel())); - BAIL_IF_NEGATIVE(fprintf(f, "RoadTexturingLevel %d\n", GetRoadTexturingLevel())); - BAIL_IF_NEGATIVE(fprintf(f, "WallTexturingLevel %d\n", GetWallTexturingLevel())); - BAIL_IF_NEGATIVE(fprintf(f, "ShadowLevel %d\n", GetShadowLevel())); - BAIL_IF_NEGATIVE(fprintf(f, "DepthCueingOn %d\n", GetDepthCueingOn())); - BAIL_IF_NEGATIVE(fprintf(f, "Yon %f\n", GetYon())); - BAIL_IF_NEGATIVE(fprintf(f, "CarSimplificationLevel %d\n", GetCarSimplificationLevel())); - BAIL_IF_NEGATIVE(fprintf(f, "AccessoryRendering %d\n", GetAccessoryRendering())); - BAIL_IF_NEGATIVE(fprintf(f, "SmokeOn %d\n", GetSmokeOn())); - BAIL_IF_NEGATIVE(fprintf(f, "SoundDetailLevel %d\n", GetSoundDetailLevel())); - BAIL_IF_NEGATIVE(fprintf(f, "ScreenSize %d\n", GetScreenSize())); - BAIL_IF_NEGATIVE(fprintf(f, "MapRenderX %f\n", gMap_render_x)); - BAIL_IF_NEGATIVE(fprintf(f, "MapRenderY %f\n", gMap_render_y)); - BAIL_IF_NEGATIVE(fprintf(f, "MapRenderWidth %f\n", gMap_render_width)); - BAIL_IF_NEGATIVE(fprintf(f, "MapRenderHeight %f\n", gMap_render_height)); - BAIL_IF_NEGATIVE(fprintf(f, "PlayerName 0\n%s\n", (gProgram_state.player_name[0][0] == '\0') ? "MAX DAMAGE" : gProgram_state.player_name[0])); - BAIL_IF_NEGATIVE(fprintf(f, "PlayerName 1\n%s\n", (gProgram_state.player_name[1][0] == '\0') ? "DIE ANNA" : gProgram_state.player_name[1])); - BAIL_IF_NEGATIVE(fprintf(f, "NetName 0\n%s\n", (gNet_player_name[0] == '\0') ? "RON TURN" : gNet_player_name)); - BAIL_IF_NEGATIVE(fprintf(f, "EVolume %d\n", gProgram_state.effects_volume)); - BAIL_IF_NEGATIVE(fprintf(f, "MVolume %d\n", gProgram_state.music_volume)); - BAIL_IF_NEGATIVE(fprintf(f, "KeyMapIndex %d\n", gKey_map_index)); - - BAIL_IF_NEGATIVE(fprintf(f, "NETGAMETYPE %d\n", gLast_game_type)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 0)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 1)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 2)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 3)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 4)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 5)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 6)); - BAIL_IF_NEGATIVE(PrintNetOptions(f, 7)); - -#undef BAIL_IF_NEGATIVE - - fclose(f); - return 1; } @@ -3790,7 +3853,10 @@ int RestoreOptions(void) { gProgram_state.music_volume = (int)arg; } else if (!strcmp(token, "KeyMapIndex")) { gKey_map_index = (int)arg; - } else if (!strcmp(token, "Joystick_min1x")) { + } +#ifdef __DOS__ + // this code only exists in the DOS build + else if (!strcmp(token, "Joystick_min1x")) { gJoystick_min1x = (int)arg; } else if (!strcmp(token, "Joystick_min1y")) { gJoystick_min1y = (int)arg; @@ -3806,7 +3872,9 @@ int RestoreOptions(void) { gJoystick_range2x = (int)arg; } else if (!strcmp(token, "Joystick_range2y")) { gJoystick_range2y = (int)arg; - } else if (!strcmp(token, "NetName")) { + } +#endif + else if (!strcmp(token, "NetName")) { fgets(line, 80, f); s = strtok(line, "\n\r"); strcpy(gNet_player_name, s); diff --git a/src/DETHRACE/common/replay.c b/src/DETHRACE/common/replay.c index 8e780de7..924dd539 100644 --- a/src/DETHRACE/common/replay.c +++ b/src/DETHRACE/common/replay.c @@ -136,108 +136,113 @@ void StopSaving(void) { void ActualActionReplayHeadups(int pSpecial_zappy_bastard) { tU32 the_time; int x; - tU16 played_col1; - tU16 played_col2; - tU16 to_play_col1; - tU16 to_play_col2; + // dethrace: these are unused, present in DOS build but removed in the windows build + // tU16 played_col1; + // tU16 played_col2; + // tU16 to_play_col1; + // tU16 to_play_col2; the_time = PDGetTotalTime(); - if (gSave_file || PDKeyDown(KEY_SHIFT_ANY)) { - return; - } - if ((the_time / 400) % 2) { - DRMaskedStamp(gCurrent_graf_data->action_replay_R_x, - gCurrent_graf_data->action_replay_R_y, - gReplay_pixies[0]); - } - DRMaskedStamp(gCurrent_graf_data->action_replay_controls_x, - gCurrent_graf_data->action_replay_controls_y, - gReplay_pixies[1]); - if (pSpecial_zappy_bastard < 0) { - DRMaskedStamp(gCurrent_graf_data->action_replay_rew_start_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[2]); - } else if (pSpecial_zappy_bastard == 0) { - if (gReplay_rate < -1.f) { - DRMaskedStamp(gCurrent_graf_data->action_replay_rew_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[3]); - } else if (gReplay_rate > 1.f) { - DRMaskedStamp(gCurrent_graf_data->action_replay_ffwd_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[7]); - } else if (gReplay_rate == 1.f) { - DRMaskedStamp(gCurrent_graf_data->action_replay_play_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[6]); - } else if (gReplay_rate == -1.f) { - DRMaskedStamp(gCurrent_graf_data->action_replay_rev_play_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[4]); - } else { - DRMaskedStamp(gCurrent_graf_data->action_replay_pause_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[5]); - } - } else { - DRMaskedStamp(gCurrent_graf_data->action_replay_fwd_end_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[8]); - } + if (!gSave_file && !PDKeyDown(KEY_SHIFT_ANY)) { - x = gProgress_line_left[gGraf_data_index] + (float)(gProgress_line_right[gGraf_data_index] - gProgress_line_left[gGraf_data_index]) * (gLast_replay_frame_time - gAction_replay_start_time) / (gAction_replay_end_time - gAction_replay_start_time); - if (x > gProgress_line_left[gGraf_data_index]) { + if ((the_time / 400) % 2) { + DRMaskedStamp(gCurrent_graf_data->action_replay_R_x, + gCurrent_graf_data->action_replay_R_y, + gReplay_pixies[0]); + } + DRMaskedStamp(gCurrent_graf_data->action_replay_controls_x, + gCurrent_graf_data->action_replay_controls_y, + gReplay_pixies[1]); + if (pSpecial_zappy_bastard < 0) { + DRMaskedStamp(gCurrent_graf_data->action_replay_rew_start_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[2]); + } else if (pSpecial_zappy_bastard > 0) { + DRMaskedStamp(gCurrent_graf_data->action_replay_fwd_end_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[8]); + } else { + if (gReplay_rate < -1.f) { + DRMaskedStamp(gCurrent_graf_data->action_replay_rew_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[3]); + } else if (gReplay_rate > 1.f) { + DRMaskedStamp(gCurrent_graf_data->action_replay_ffwd_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[7]); + } else if (gReplay_rate == 1.f) { + DRMaskedStamp(gCurrent_graf_data->action_replay_play_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[6]); + } else if (gReplay_rate == -1.f) { + DRMaskedStamp(gCurrent_graf_data->action_replay_rev_play_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[4]); + } else { + DRMaskedStamp(gCurrent_graf_data->action_replay_pause_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[5]); + } + } + + x = (int)((gLast_replay_frame_time - gAction_replay_start_time) + / (double)(gAction_replay_end_time - gAction_replay_start_time) + * (gProgress_line_right[gGraf_data_index] - gProgress_line_left[gGraf_data_index])) + + gProgress_line_left[gGraf_data_index]; + + if (x > gProgress_line_left[gGraf_data_index]) { + BrPixelmapLine(gBack_screen, + gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index], + x - 1, gProgress_line_top[gGraf_data_index], + 2); + BrPixelmapLine(gBack_screen, + gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 1, + x - 1, gProgress_line_top[gGraf_data_index] + 1, + 4); + BrPixelmapLine(gBack_screen, + gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2, + x - 1, gProgress_line_top[gGraf_data_index] + 2, + 2); + } + if (x < gProgress_line_right[gGraf_data_index]) { + BrPixelmapLine(gBack_screen, + x, gProgress_line_top[gGraf_data_index], + gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index], + 81); + BrPixelmapLine(gBack_screen, + x, gProgress_line_top[gGraf_data_index] + 1, + gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 1, + 82); + BrPixelmapLine(gBack_screen, + x, gProgress_line_top[gGraf_data_index] + 2, + gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2, + 81); + } BrPixelmapLine(gBack_screen, - gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index], - x - 1, gProgress_line_top[gGraf_data_index], + gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index], + gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2, 2); BrPixelmapLine(gBack_screen, - gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 1, - x - 1, gProgress_line_top[gGraf_data_index] + 1, - 4); - BrPixelmapLine(gBack_screen, - gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2, - x - 1, gProgress_line_top[gGraf_data_index] + 2, - 2); - } - if (x < gProgress_line_right[gGraf_data_index]) { - BrPixelmapLine(gBack_screen, - x, gProgress_line_top[gGraf_data_index], - gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index], - 81); - BrPixelmapLine(gBack_screen, - x, gProgress_line_top[gGraf_data_index] + 1, - gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 1, - 82); - BrPixelmapLine(gBack_screen, - x, gProgress_line_top[gGraf_data_index] + 2, - gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2, + gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index], + gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2, 81); + if (gCam_change_button_down) { + DRMaskedStamp(gCurrent_graf_data->action_replay_camera_x, + gCurrent_graf_data->action_replay_hilite_y, + gReplay_pixies[9]); + } + if (the_time - gCam_change_time < 2000) { + TransDRPixelmapText(gBack_screen, + gCurrent_graf_data->action_replay_cam_text_x - DRTextWidth(&gFonts[kFont_ORANGHED], GetMiscString(kMiscString_StandardCamera + gAction_replay_camera_mode)), + gCurrent_graf_data->action_replay_cam_text_y, + &gFonts[kFont_ORANGHED], + GetMiscString(kMiscString_StandardCamera + gAction_replay_camera_mode), + 2 * gCurrent_graf_data->action_replay_cam_text_x); + } + TurnOnPaletteConversion(); + DoMouseCursor(); + TurnOffPaletteConversion(); } - BrPixelmapLine(gBack_screen, - gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index], - gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2, - 2); - BrPixelmapLine(gBack_screen, - gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index], - gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2, - 81); - if (gCam_change_button_down) { - DRMaskedStamp(gCurrent_graf_data->action_replay_camera_x, - gCurrent_graf_data->action_replay_hilite_y, - gReplay_pixies[9]); - } - if (the_time - gCam_change_time < 2000) { - TransDRPixelmapText(gBack_screen, - gCurrent_graf_data->action_replay_cam_text_x - DRTextWidth(&gFonts[kFont_ORANGHED], GetMiscString(gAction_replay_camera_mode ? kMiscString_PanningCamera : kMiscString_StandardCamera)), - gCurrent_graf_data->action_replay_cam_text_y, - &gFonts[kFont_ORANGHED], - GetMiscString(gAction_replay_camera_mode ? kMiscString_PanningCamera : kMiscString_StandardCamera), - 2 * gCurrent_graf_data->action_replay_cam_text_x); - } - TurnOnPaletteConversion(); - DoMouseCursor(); - TurnOffPaletteConversion(); } // IDA: void __cdecl DoActionReplayPostSwap() @@ -281,23 +286,20 @@ void MoveReplayBuffer(tS32 pMove_amount) { old_play_ptr = NULL; gLast_replay_zappy_screen = 0; - old_play_ptr2 = GetPipePlayPtr(); - play_ptr = old_play_ptr2; + play_ptr = GetPipePlayPtr(); + old_play_ptr2 = play_ptr; old_time = GetTotalTime(); - for (i = 0; i < abs(pMove_amount) && play_ptr != old_play_ptr; i++) { - if (KeyIsDown(KEYMAP_ESCAPE)) { - break; - } + for (i = 0; i < abs(pMove_amount) && play_ptr != old_play_ptr && !KeyIsDown(KEYMAP_ESCAPE); i++) { if (SomeReplayLeft()) { PipingFrameReset(); } old_play_ptr = play_ptr; - if (pMove_amount >= 1) { + if (pMove_amount > 0) { while (!ApplyPipedSession(&play_ptr)) { DoZappyActionReplayHeadups(pMove_amount); } SetPipePlayPtr(play_ptr); - } else if (pMove_amount <= -1) { + } else if (pMove_amount < 0) { while (!UndoPipedSession(&play_ptr)) { DoZappyActionReplayHeadups(pMove_amount); } @@ -349,48 +351,48 @@ void MoveToStartOfReplay(void) { // FUNCTION: CARM95 0x0041b661 void ToggleReplay(void) { - if (!IsActionReplayAvailable()) { - NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_ACTION_REPLAY_UNAVAILABLE)); - return; - } - if (!gAction_replay_mode) { - if (gMap_mode) { - ToggleMap(); - } - if (gNet_mode == eNet_mode_host) { - SendGameplayToAllPlayers(eNet_gameplay_host_paused, 0, 0, 0, 0); - } - gReplay_rate = 1.f; - gPaused = 1; - gStopped_time = PDGetTotalTime(); - gPlay_direction = 1; - gAction_replay_end_time = GetTotalTime(); - gLast_replay_frame_time = gAction_replay_end_time; - gAction_replay_start_time = GetARStartTime(); - ResetPipePlayToEnd(); - LoadInterfaceStuff(1); - StartMouseCursor(); - gKey_down = KEY_KP_ENTER; - gPending_replay_rate = 0; - gCam_change_time = PDGetTotalTime(); - if (!gRace_finished) { - SaveCameraPosition(0); + if (IsActionReplayAvailable()) { + if (!gAction_replay_mode) { + if (gMap_mode) { + ToggleMap(); + } + if (gNet_mode == eNet_mode_host) { + SendGameplayToAllPlayers(eNet_gameplay_host_paused, 0, 0, 0, 0); + } + gReplay_rate = 1.f; + gPaused = 1; + gStopped_time = PDGetTotalTime(); + gPlay_direction = 1; + gAction_replay_end_time = GetTotalTime(); + gLast_replay_frame_time = gAction_replay_end_time; + gAction_replay_start_time = GetARStartTime(); + ResetPipePlayToEnd(); + LoadInterfaceStuff(1); + StartMouseCursor(); + gKey_down = KEY_KP_ENTER; + gPending_replay_rate = 0; + gCam_change_time = PDGetTotalTime(); + if (!gRace_finished) { + SaveCameraPosition(0); + } + } else { + MoveToEndOfReplay(); + EndMouseCursor(); + S3RegisterSampleFilters(NULL, NULL); + UnlockInterfaceStuff(); + AddLostTime(PDGetTotalTime() - gStopped_time); + if (!gRace_finished) { + RestoreCameraPosition(0); + } + if (gNet_mode == eNet_mode_host) { + SendGameplayToAllPlayers(eNet_gameplay_host_unpaused, 0, 0, 0, 0); + } } + gAction_replay_mode = !gAction_replay_mode; + ForceRebuildActiveCarList(); } else { - MoveToEndOfReplay(); - EndMouseCursor(); - S3SetEffects(NULL, NULL); - UnlockInterfaceStuff(); - AddLostTime(PDGetTotalTime() - gStopped_time); - if (!gRace_finished) { - RestoreCameraPosition(0); - } - if (gNet_mode == eNet_mode_host) { - SendGameplayToAllPlayers(eNet_gameplay_host_unpaused, 0, 0, 0, 0); - } + NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_ACTION_REPLAY_UNAVAILABLE)); } - gAction_replay_mode = !gAction_replay_mode; - ForceRebuildActiveCarList(); } // IDA: void __usercall ReverseSound(tS3_effect_tag pEffect_index@, tS3_sound_tag pSound_tag@) @@ -402,7 +404,7 @@ void ReverseSound(tS3_effect_tag pEffect_index, tS3_sound_tag pSound_tag) { // IDA: int __cdecl FindUniqueFile() // FUNCTION: CARM95 0x0041b819 int FindUniqueFile(void) { - int index; + int index = 0; FILE* f; tPath_name the_path; @@ -429,8 +431,11 @@ void PollActionReplayControls(tU32 pFrame_period) { int y_coord; int i; tU32 real_time; + // GLOBAL: CARM95 0x50a200 static tU32 last_real_time = 0; + + // GLOBAL: CARM95 0x0050A208 static int psuedo_mouse_keys[8] = { KEY_KP_7, KEY_KP_4, @@ -441,7 +446,9 @@ void PollActionReplayControls(tU32 pFrame_period) { KEY_KP_9, KEY_KP_MULTIPLY, }; + /* clang-format off */ + // GLOBAL: CARM95 0x0050A228 static tRectangle mouse_areas[2][8] = { { { 63, 182, 92, 198, }, @@ -470,23 +477,26 @@ void PollActionReplayControls(tU32 pFrame_period) { old_replay_rate = gReplay_rate; old_key_down = gKey_down == KEY_CAPSLOCK ? -1 : gKey_down; gKey_down = PDAnyKeyDown(); - if (KeyIsDown(KEYMAP_REPLAYMODE) && old_key_down == -1) { + if (old_key_down == -1 && KeyIsDown(KEYMAP_REPLAYMODE)) { ToggleReplay(); return; } - if (gKey_down == -1) { + if (gKey_down != -1) { + gMouse_in_use = 0; + } else { if ((old_key_down == -1 || old_key_down == KEY_KP_4 || old_key_down == KEY_KP_6 || old_key_down == KEY_KP_MULTIPLY) && EitherMouseButtonDown()) { GetMousePosition(&x_coord, &y_coord); for (i = 0; i < COUNT_OF(mouse_areas[0]); i++) { - if (mouse_areas[gGraf_data_index][i].left <= x_coord && mouse_areas[gGraf_data_index][i].top <= y_coord && mouse_areas[gGraf_data_index][i].right >= x_coord && mouse_areas[gGraf_data_index][i].bottom >= y_coord) { + if (mouse_areas[gGraf_data_index][i].left <= x_coord + && mouse_areas[gGraf_data_index][i].top <= y_coord + && mouse_areas[gGraf_data_index][i].right > x_coord + && mouse_areas[gGraf_data_index][i].bottom > y_coord) { gKey_down = psuedo_mouse_keys[i]; break; } } } - } else { - gMouse_in_use = 0; } if (gKey_down == KEY_KP_DIVIDE && old_key_down != KEY_KP_DIVIDE) { @@ -505,10 +515,8 @@ void PollActionReplayControls(tU32 pFrame_period) { gCam_change_button_down = 1; if (old_key_down != KEY_KP_MULTIPLY) { gCam_change_time = PDGetTotalTime(); - if (gAction_replay_camera_mode == eAction_replay_action) { + if (gAction_replay_camera_mode++ == eAction_replay_action) { gAction_replay_camera_mode = eAction_replay_standard; - } else { - gAction_replay_camera_mode++; } } } else { @@ -533,21 +541,21 @@ void PollActionReplayControls(tU32 pFrame_period) { gPlay_direction = 1; gSingle_frame_mode = 1; } else if (gKey_down == KEY_KP_4 || gKey_down == KEY_PAGEUP) { - if (gReplay_rate > -1.2f) { + if (gReplay_rate > -1.2) { gReplay_rate = -1.2f; } if (last_real_time != 0) { - gReplay_rate -= 0.002f * (real_time - last_real_time); + gReplay_rate -= 0.002 * (real_time - last_real_time); } if (gReplay_rate < -8.f) { gReplay_rate = -8.f; } } else if (gKey_down == KEY_KP_6 || gKey_down == KEY_PAGEDOWN) { - if (gReplay_rate < 1.2f) { + if (gReplay_rate < 1.2) { gReplay_rate = 1.2f; } if (last_real_time != 0) { - gReplay_rate += 0.002f * (real_time - last_real_time); + gReplay_rate += 0.002 * (real_time - last_real_time); } if (gReplay_rate > 8.f) { gReplay_rate = 8.f; @@ -586,35 +594,42 @@ void PollActionReplayControls(tU32 pFrame_period) { if (gPending_replay_rate != 0.f) { gReplay_rate = gPending_replay_rate; + gPending_replay_rate = 0; } - if (old_replay_rate * gReplay_rate >= 0.f) { - gPending_replay_rate = 0.f; - } else { + if (old_replay_rate * gReplay_rate < 0.f) { gPending_replay_rate = gReplay_rate; gReplay_rate = 0.f; + } else { + gPending_replay_rate = 0.f; } if (old_replay_rate != 0.f) { - gFrame_period = gFrame_period * gReplay_rate / old_replay_rate; + gFrame_period = gFrame_period * (gReplay_rate / old_replay_rate); + } + + if (fabs(gReplay_rate) < 1.2) { + last_real_time = 0; + } else { + last_real_time = real_time; } - last_real_time = fabs(gReplay_rate) >= 1.2f ? real_time : 0; if (old_replay_rate <= 0.f && gReplay_rate > 0.f) { - S3SetEffects(NULL, NULL); + S3RegisterSampleFilters(NULL, NULL); } else if (old_replay_rate >= 0.f && gReplay_rate < 0.f) { - S3SetEffects(ReverseSound, ReverseSound); + S3RegisterSampleFilters(ReverseSound, ReverseSound); } } // IDA: void __cdecl CheckReplayTurnOn() // FUNCTION: CARM95 0x0041c03b void CheckReplayTurnOn(void) { - if (!gAction_replay_mode) { - if (!KeyIsDown(KEYMAP_REPLAYMODE) || gEntering_message) { + if (KeyIsDown(KEYMAP_REPLAYMODE) && !gEntering_message) { + if (gKey_down == -1) { + ToggleReplay(); + } + } else { gKey_down = -1; - } else if (gKey_down == -1) { - ToggleReplay(); } } } @@ -647,10 +662,7 @@ void SynchronizeActionReplay(void) { // GLOBAL: CARM95 0x50a328 static tU32 gLast_synch_time; - while (gReplay_rate != 0.f) { - if (PDGetTotalTime() - gLast_synch_time >= gFrame_period / fabs(gReplay_rate)) { - break; - } + while (gReplay_rate != 0.f && PDGetTotalTime() - gLast_synch_time < gFrame_period / fabs(gReplay_rate)) { ServiceGameInRace(); } gLast_synch_time = PDGetTotalTime(); @@ -662,12 +674,11 @@ void SynchronizeActionReplay(void) { if (gSave_file) { PathCat(the_path, gApplication_path, "BMPFILES"); strcat(the_path, gDir_separator); - sprintf(&the_path[strlen(the_path)], "%03d_%04d.BMP", gSave_bunch_ID, gSave_frame_number); + sprintf(&the_path[strlen(the_path)], "%03d_%04d.BMP", gSave_bunch_ID, gSave_frame_number++); f = DRfopen(the_path, "wb"); if (f != NULL) { PrintScreenFile(f); fclose(f); } - gSave_frame_number++; } } diff --git a/src/DETHRACE/pc-all/allsys.c b/src/DETHRACE/pc-all/allsys.c index 2b9a83b2..457602b3 100644 --- a/src/DETHRACE/pc-all/allsys.c +++ b/src/DETHRACE/pc-all/allsys.c @@ -31,6 +31,8 @@ int gDOSGfx_initialized; int gExtra_mem; int gReplay_override; + +// GLOBAL: CARM95 0x0051D608 tGraf_spec gGraf_specs[2] = { { 8, 1, 0, 320, 200, 0, 0, "32X20X8", "MCGA,W:320,H:200,B:8", 320, 320, 200, NULL }, { 8, 1, 0, 640, 480, 0, 0, "64X48X8", "VESA,W:640,H:480,B:8", 640, 640, 480, NULL } diff --git a/src/S3/include/s3/s3.h b/src/S3/include/s3/s3.h index d18ff9cd..ccad6813 100644 --- a/src/S3/include/s3/s3.h +++ b/src/S3/include/s3/s3.h @@ -57,7 +57,7 @@ int S3StopOutletSound(tS3_outlet_ptr pOutlet); int S3SetOutletVolume(tS3_outlet_ptr pOutlet, tS3_volume pVolume); void S3UpdateSoundSource(tS3_outlet_ptr outlet, tS3_sound_tag tag, tS3_sound_source_ptr src, float pMax_distance_squared, int pPeriod, tS3_repeats pAmbient_repeats, tS3_volume pVolume, int pPitch, tS3_speed pSpeed); -int S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2); +int S3RegisterSampleFilters(tS3_sample_filter* filter1, tS3_sample_filter* filter2); // CDA int S3CDAEnabled(void); diff --git a/src/S3/s3sound.c b/src/S3/s3sound.c index 2e2edf37..07b3c58a 100644 --- a/src/S3/s3sound.c +++ b/src/S3/s3sound.c @@ -416,7 +416,8 @@ int S3SyncSampleRate(tS3_channel* chan) { return 1; } -int S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2) { +// FUNCTION: CARM95 0x004C946D +int S3RegisterSampleFilters(tS3_sample_filter* filter1, tS3_sample_filter* filter2) { STUB_ONCE(); return 0; } diff --git a/src/library_msvc.h b/src/library_msvc.h index 590d1ec0..ea297a6c 100644 --- a/src/library_msvc.h +++ b/src/library_msvc.h @@ -228,8 +228,14 @@ // GLOBAL: CARM95 0x004EAB82 // __CIpow +// GLOBAL: CARM95 0x004EABD9 +// __CItan + // GLOBAL: CARM95 0x004EA8DA // __CIatan2 // GLOBAL: CARM95 0x004EA8C2 // __CIasin + +// LIBRARY: CARM95 0x004EC160 +// _filbuf