Add change car dialog (#102)

* Add 'change car' dialog

* Implement functions to support switching car

* When opening a file in brender fails, try all uppercase file before failing

* Some cars need GetFourScalars
This commit is contained in:
Anonymous Maarten 2022-03-10 02:32:09 +01:00 committed by GitHub
parent d4dc8d2013
commit 60102a37e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 499 additions and 31 deletions

View File

@ -6,6 +6,10 @@
#include "harness/trace.h"
#include <stdarg.h>
#include <stddef.h>
#ifdef BRENDER_FIX_BUGS
#include <ctype.h>
#include <string.h>
#endif
// IDA: void __cdecl _BrFileFree(void *res, br_uint_8 res_class, br_size_t size)
void _BrFileFree(void* res, br_uint_8 res_class, br_size_t size) {
@ -27,6 +31,9 @@ void* BrFileOpenRead(char* name, br_size_t n_magics, br_mode_test_cbfn* mode_tes
void* raw_file;
br_file* file;
int bin_mode;
#ifdef BRENDER_FIX_BUGS
char *s;
#endif
LOG_TRACE("(\"%s\", %d, %p, %p)", name, n_magics, mode_test, mode_result);
bin_mode = 0;
@ -36,6 +43,24 @@ void* BrFileOpenRead(char* name, br_size_t n_magics, br_mode_test_cbfn* mode_tes
raw_file = fw.fsys->open_read(name, n_magics, mode_test, &bin_mode);
}
#ifdef BRENDER_FIX_BUGS
// Try all-uppercase filename for case sensitive file systems
if (raw_file == NULL) {
for (s = name + strlen(name); s != name;) {
s--;
if (*s == '\\' || *s == '/') {
break;
}
*s = toupper(*s);
}
if (mode_result != NULL) {
raw_file = fw.fsys->open_read(name, n_magics, mode_test, mode_result);
} else {
raw_file = fw.fsys->open_read(name, n_magics, mode_test, &bin_mode);
}
}
#endif
if (raw_file == NULL) {
return NULL;
}

View File

@ -210,9 +210,9 @@ br_actor* BrActorAllocate(br_uint_8 type, void* type_data) {
// IDA: void __usercall InternalActorFree(br_actor *a@<EAX>)
void InternalActorFree(br_actor* a) {
while (a->children) {
BrSimpleRemove((br_simple_node*)a->children);
InternalActorFree(a);
while (a->children != NULL) {
InternalActorFree((br_actor*)BrSimpleRemove((br_simple_node*)a->children));
}
BrActorEnableCheck(a);
BrResFree(a);
@ -220,9 +220,9 @@ void InternalActorFree(br_actor* a) {
// IDA: void __cdecl BrActorFree(br_actor *a)
void BrActorFree(br_actor* a) {
while (a->children) {
BrSimpleRemove((br_simple_node*)a->children);
InternalActorFree(a);
while (a->children != NULL) {
InternalActorFree((br_actor*)BrSimpleRemove((br_simple_node*)a->children));
}
BrActorEnableCheck(a);
BrResFree(a);

View File

@ -2353,7 +2353,37 @@ void DrawDropImage(br_pixelmap* pImage, int pLeft, int pTop, int pTop_clip, int
int src_height;
int y_diff;
LOG_TRACE("(%p, %d, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip, pOffset);
NOT_IMPLEMENTED();
BrPixelmapRectangleFill(gBack_screen,
pLeft,
pTop_clip,
pImage->width,
pBottom_clip - pTop_clip,
0);
if (pOffset != 1000) {
src_y = 0;
src_height = pImage->height;
y = pOffset + pTop;
y_diff = pTop_clip - y;
if (y_diff > 0) {
src_height -= y_diff;
y += y_diff;
src_y = y_diff;
}
y_diff = pBottom_clip - y - pImage->height;
if (y_diff < 0) {
src_height += y_diff;
}
BrPixelmapRectangleCopy(gBack_screen,
pLeft,
y,
pImage,
0,
src_y,
pImage->width,
src_height);
PDScreenBufferSwap(0);
}
}
// IDA: void __usercall DropInImageFromTop(br_pixelmap *pImage@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pTop_clip@<ECX>, int pBottom_clip)
@ -2362,7 +2392,22 @@ void DropInImageFromTop(br_pixelmap* pImage, int pLeft, int pTop, int pTop_clip,
tS32 the_time;
int drop_distance;
LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip);
NOT_IMPLEMENTED();
start_time = PDGetTotalTime();
drop_distance = pImage->height - pTop_clip + pTop;
while (1) {
the_time = PDGetTotalTime();
if (the_time >= start_time + 100) {
break;
}
DrawDropImage(pImage,
pLeft,
pTop,
pTop_clip,
pBottom_clip,
(the_time - start_time - 100) * drop_distance / 100);
}
DrawDropImage(pImage, pLeft, pTop, pTop_clip, pBottom_clip, 0);
}
// IDA: void __usercall DropOutImageThruBottom(br_pixelmap *pImage@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pTop_clip@<ECX>, int pBottom_clip)
@ -2371,7 +2416,22 @@ void DropOutImageThruBottom(br_pixelmap* pImage, int pLeft, int pTop, int pTop_c
tS32 the_time;
int drop_distance;
LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip);
NOT_IMPLEMENTED();
start_time = PDGetTotalTime();
drop_distance = pBottom_clip - pTop;
while (1) {
the_time = PDGetTotalTime();
if (the_time >= start_time + 100) {
break;
}
DrawDropImage(pImage,
pLeft,
pTop,
pTop_clip,
pBottom_clip,
(the_time - start_time) * drop_distance / 100);
}
DrawDropImage(pImage, pLeft, pTop, pTop_clip, pBottom_clip, 1000);
}
// IDA: void __usercall DropInImageFromBottom(br_pixelmap *pImage@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pTop_clip@<ECX>, int pBottom_clip)
@ -2380,7 +2440,22 @@ void DropInImageFromBottom(br_pixelmap* pImage, int pLeft, int pTop, int pTop_cl
tS32 the_time;
int drop_distance;
LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip);
NOT_IMPLEMENTED();
start_time = PDGetTotalTime();
drop_distance = pBottom_clip - pTop;
while (1) {
the_time = PDGetTotalTime();
if (the_time >= start_time + 100) {
break;
}
DrawDropImage(pImage,
pLeft,
pTop,
pTop_clip,
pBottom_clip,
(100 - the_time + start_time) * drop_distance / 100);
}
DrawDropImage(pImage, pLeft, pTop, pTop_clip, pBottom_clip, 0);
}
// IDA: void __usercall DropOutImageThruTop(br_pixelmap *pImage@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pTop_clip@<ECX>, int pBottom_clip)
@ -2389,7 +2464,22 @@ void DropOutImageThruTop(br_pixelmap* pImage, int pLeft, int pTop, int pTop_clip
tS32 the_time;
int drop_distance;
LOG_TRACE("(%p, %d, %d, %d, %d)", pImage, pLeft, pTop, pTop_clip, pBottom_clip);
NOT_IMPLEMENTED();
start_time = PDGetTotalTime();
drop_distance = pImage->height - pTop_clip + pTop;
while (1) {
the_time = PDGetTotalTime();
if (the_time >= start_time + 100) {
break;
}
DrawDropImage(pImage,
pLeft,
pTop,
pTop_clip,
pBottom_clip,
(start_time - the_time) * drop_distance / 100);
}
DrawDropImage(pImage, pLeft, pTop, pTop_clip, pBottom_clip, 1000);
}
// IDA: void __usercall DrawTellyLine(br_pixelmap *pImage@<EAX>, int pLeft@<EDX>, int pTop@<EBX>, int pPercentage@<ECX>)

View File

@ -899,7 +899,95 @@ void DisposeCar(tCar_spec* pCar_spec, int pOwner) {
int i;
int j;
LOG_TRACE("(%p, %d)", pCar_spec, pOwner);
NOT_IMPLEMENTED();
if (pCar_spec->driver_name[0] == '\0') {
return;
}
gFunk_groove_flags[pCar_spec->fg_index] = 0;
pCar_spec->driver_name[0] = '\0';
if (pCar_spec->driver == eDriver_local_human) {
for (i = 0; i < COUNT_OF(pCar_spec->cockpit_images); i++) {
if (pCar_spec->cockpit_images[i] != NULL) {
BrMemFree(pCar_spec->cockpit_images[i]);
}
}
if (pCar_spec->speedo_image[0] != NULL) {
BrPixelmapFree(pCar_spec->speedo_image[0]);
}
if (pCar_spec->speedo_image[1] != NULL) {
BrPixelmapFree(pCar_spec->speedo_image[1]);
}
if (pCar_spec->tacho_image[0] != NULL) {
BrPixelmapFree(pCar_spec->tacho_image[0]);
}
if (pCar_spec->tacho_image[1] != NULL) {
BrPixelmapFree(pCar_spec->tacho_image[1]);
}
for (i = 0; i < pCar_spec->number_of_hands_images; i++) {
if (pCar_spec->lhands_images[i] != NULL) {
BrPixelmapFree(pCar_spec->lhands_images[i]);
}
if (pCar_spec->rhands_images[i] != NULL) {
BrPixelmapFree(pCar_spec->rhands_images[i]);
}
}
if (pCar_spec->prat_cam_left != NULL) {
BrPixelmapFree(pCar_spec->prat_cam_left);
}
if (pCar_spec->prat_cam_top != NULL) {
BrPixelmapFree(pCar_spec->prat_cam_top);
}
if (pCar_spec->prat_cam_right != NULL) {
BrPixelmapFree(pCar_spec->prat_cam_right);
}
if (pCar_spec->prat_cam_bottom != NULL) {
BrPixelmapFree(pCar_spec->prat_cam_bottom);
}
for (i = 0; i < COUNT_OF(pCar_spec->damage_units); i++) {
if (pCar_spec->damage_units[i].images != NULL) {
BrPixelmapFree(pCar_spec->damage_units[i].images);
}
}
if (pCar_spec->damage_background != NULL) {
BrPixelmapFree(pCar_spec->damage_background);
}
for (i = 0; i < COUNT_OF(pCar_spec->power_ups); i++) {
for (j = 0; j < pCar_spec->power_ups[i].number_of_parts; j++) {
if (pCar_spec->power_ups[i].info[j].data_ptr != NULL) {
BrMemFree(pCar_spec->power_ups[i].info[j].data_ptr);
}
}
}
gProgram_state.car_name[0] = '\0';
}
if (pCar_spec->screen_material != NULL) {
KillWindscreen(pCar_spec->car_model_actors[pCar_spec->principal_car_actor].actor->model,
pCar_spec->screen_material);
BrMaterialRemove(pCar_spec->screen_material);
BrMaterialFree(pCar_spec->screen_material);
}
for (i = 0; i < COUNT_OF(pCar_spec->damage_programs); i++) {
BrMemFree(pCar_spec->damage_programs[i].clauses);
}
DropOffDyingPeds(pCar_spec);
for (i = 0; i < pCar_spec->car_actor_count; i++) {
BrActorRemove(pCar_spec->car_model_actors[i].actor);
BrActorFree(pCar_spec->car_model_actors[i].actor);
}
if (pCar_spec->driver != eDriver_local_human) {
BrActorRemove(pCar_spec->car_master_actor);
BrActorFree(pCar_spec->car_master_actor);
}
DisposeFunkotronics(pOwner);
DisposeGroovidelics(pOwner);
for (i = 0; i < pCar_spec->car_actor_count; i++) {
if (pCar_spec->car_model_actors[i].crush_data.crush_points != NULL) {
DisposeCrushData(&pCar_spec->car_model_actors[i].crush_data);
}
if (pCar_spec->car_model_actors[i].undamaged_vertices != NULL) {
BrMemFree(pCar_spec->car_model_actors[i].undamaged_vertices);
}
}
}
// IDA: void __usercall AdjustCarCoordinates(tCar_spec *pCar@<EAX>)
@ -2799,7 +2887,20 @@ void GetFourScalars(FILE* pF, br_scalar* pF1, br_scalar* pF2, br_scalar* pF3, br
float f3;
float f4;
LOG_TRACE("(%p, %p, %p, %p, %p)", pF, pF1, pF2, pF3, pF4);
NOT_IMPLEMENTED();
GetALineAndDontArgue(pF, s);
str = strtok(s, "\t ,/");
sscanf(str, "%f", &f1);
str = strtok(NULL, "\t ,/");
sscanf(str, "%f", &f2);
str = strtok(NULL, "\t ,/");
sscanf(str, "%f", &f3);
str = strtok(NULL, "\t ,/");
sscanf(str, "%f", &f4);
*pF1 = f1;
*pF2 = f2;
*pF3 = f3;
*pF4 = f4;
}
// IDA: void __usercall GetFiveScalars(FILE *pF@<EAX>, br_scalar *pF1@<EDX>, br_scalar *pF2@<EBX>, br_scalar *pF3@<ECX>, br_scalar *pF4, br_scalar *pF5)

View File

@ -785,7 +785,10 @@ int PickARandomCar() {
// IDA: void __usercall PollCarDetails(tNet_game_details *pNet_game@<EAX>)
void PollCarDetails(tNet_game_details* pNet_game) {
LOG_TRACE("(%p)", pNet_game);
NOT_IMPLEMENTED();
if (gReceived_car_details != 0) {
RequestCarDetails(pNet_game);
}
}
// IDA: void __usercall SetNetAvailability(tNet_game_options *pOptions@<EAX>)

View File

@ -18,6 +18,10 @@
#define FLAG_WAVING_BASTARD_REF 99
#define FOURCC(A,B,C,D) (((A & 0xff) << 24) | ((B & 0xff) << 16)| ((C & 0xff) << 8)| ((D & 0xff) << 0))
#define PEDESTRIAN_MAGIC FOURCC('P', 'e', 'd', '!')
#define ActorToPedestrianData(ACTOR) ((tPedestrian_data*)((ACTOR)->type_data))
int gDetect_peds;
int gReally_stupid_ped_bug_enable;
int gPed_sound_disable;
@ -111,7 +115,14 @@ void PedModelUpdate(br_model* pModel, br_scalar x0, br_scalar y0, br_scalar x1,
// IDA: int __usercall ActorIsPedestrian@<EAX>(br_actor *pActor@<EAX>)
int ActorIsPedestrian(br_actor* pActor) {
LOG_TRACE("(%p)", pActor);
NOT_IMPLEMENTED();
if (pActor->model == NULL) {
return 0;
}
if (pActor->type_data == NULL) {
return 0;
}
return ActorToPedestrianData(pActor)->magic_number == PEDESTRIAN_MAGIC;
}
// IDA: br_scalar __usercall PedHeightFromActor@<ST0>(br_actor *pActor@<EAX>)

View File

@ -5,17 +5,20 @@
#include "errors.h"
#include "flicplay.h"
#include "globvars.h"
#include "globvrpb.h"
#include "grafdata.h"
#include "graphics.h"
#include "harness/trace.h"
#include "input.h"
#include "intrface.h"
#include "loading.h"
#include "newgame.h"
#include "opponent.h"
#include "pd/sys.h"
#include "sound.h"
#include "structur.h"
#include "utility.h"
#include "world.h"
#include <stdlib.h>
int gGrid_number_colour[4] = { 49u, 201u, 1u, 201u };
@ -327,63 +330,267 @@ void DrawCar(int pCurrent_choice, int pCurrent_mode) {
int text_x;
int text_width;
LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
PollCarDetails(gChoose_car_net_game);
if (gChange_race_net_mode == 0) {
if (gProgram_state.number_of_cars == 1) {
sprintf(s, GetMiscString(34));
} else if (gProgram_state.cars_available[gCurrent_car_index] == gProgram_state.frank_or_anniness) {
sprintf(s, GetMiscString(36));
} else {
sprintf(s, "%s %s", GetMiscString(35), gOpponents[gProgram_state.cars_available[gCurrent_car_index]].name);
}
} else if (gCar_details[gProgram_state.cars_available[gCurrent_car_index]].ownership == eCar_owner_someone) {
sprintf(s, "%s %s", GetMiscString(204), gCar_details[gProgram_state.cars_available[gCurrent_car_index]].name);
} else {
sprintf(s, GetMiscString(205));
}
text_width = BrPixelmapTextWidth(gBack_screen, gFont_7, s);
text_x = (gCurrent_graf_data->change_car_line_right + gCurrent_graf_data->change_car_line_left - text_width) / 2;
BrPixelmapRectangleFill(gBack_screen,
gCurrent_graf_data->change_car_line_left,
gCurrent_graf_data->change_car_text_y,
gCurrent_graf_data->change_car_line_right - gCurrent_graf_data->change_car_line_left,
gFont_7->glyph_y,
0);
TransBrPixelmapText(gBack_screen,
text_x,
gCurrent_graf_data->change_car_text_y,
3,
gFont_7,
(signed char*)s);
BrPixelmapLine(gBack_screen,
gCurrent_graf_data->change_car_line_left,
gCurrent_graf_data->change_car_line_y,
gCurrent_graf_data->change_car_line_right,
gCurrent_graf_data->change_car_line_y,
6);
if (gChange_race_net_mode && gCar_details[gProgram_state.cars_available[gCurrent_car_index]].ownership == eCar_owner_someone) {
DRPixelmapRectangleMaskedCopy(
gBack_screen,
(gCurrent_graf_data->change_car_panel_left + gCurrent_graf_data->change_car_panel_right - gTaken_image->width) / 2,
(gCurrent_graf_data->change_car_panel_bottom + gCurrent_graf_data->change_car_panel_bottom - gTaken_image->height) / 2,
gTaken_image,
0,
0,
gTaken_image->width,
gTaken_image->height);
}
}
// IDA: void __cdecl SetCarFlic()
void SetCarFlic() {
LOG_TRACE("()");
NOT_IMPLEMENTED();
ChangePanelFlic(0,
gOpponents[gProgram_state.cars_available[gCurrent_car_index]].stolen_car_image_data,
gOpponents[gProgram_state.cars_available[gCurrent_car_index]].stolen_car_image_data_length);
}
// IDA: int __usercall UpCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int UpCar(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
AddToFlicQueue(gStart_interface_spec->pushed_flics[2].flic_index,
gStart_interface_spec->pushed_flics[2].x[gGraf_data_index],
gStart_interface_spec->pushed_flics[2].y[gGraf_data_index],
1);
DRS3StartSound(gIndexed_outlets[0], 3000);
if (gCurrent_car_index != 0) {
RemoveTransientBitmaps(1);
DropOutImageThruBottom(GetPanelPixelmap(0),
gCurrent_graf_data->change_car_panel_left,
gCurrent_graf_data->change_car_panel_top,
gCurrent_graf_data->change_car_panel_top_clip,
gCurrent_graf_data->change_car_panel_bottom_clip);
gCurrent_car_index--;
SetCarFlic();
DropInImageFromTop(GetPanelPixelmap(0),
gCurrent_graf_data->change_car_panel_left,
gCurrent_graf_data->change_car_panel_top,
gCurrent_graf_data->change_car_panel_top_clip,
gCurrent_graf_data->change_car_panel_bottom_clip);
}
return 0;
}
// IDA: int __usercall DownCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int DownCar(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
AddToFlicQueue(gStart_interface_spec->pushed_flics[3].flic_index,
gStart_interface_spec->pushed_flics[3].x[gGraf_data_index],
gStart_interface_spec->pushed_flics[3].y[gGraf_data_index],
1);
DRS3StartSound(gIndexed_outlets[0], 3000);
if (gCurrent_car_index < gProgram_state.number_of_cars - 1) {
RemoveTransientBitmaps(1);
DropOutImageThruTop(GetPanelPixelmap(0),
gCurrent_graf_data->change_car_panel_left,
gCurrent_graf_data->change_car_panel_top,
gCurrent_graf_data->change_car_panel_top_clip,
gCurrent_graf_data->change_car_panel_bottom_clip);
gCurrent_car_index++;
SetCarFlic();
DropInImageFromBottom(GetPanelPixelmap(0),
gCurrent_graf_data->change_car_panel_left,
gCurrent_graf_data->change_car_panel_top,
gCurrent_graf_data->change_car_panel_top_clip,
gCurrent_graf_data->change_car_panel_bottom_clip);
}
return 0;
}
// IDA: int __usercall UpClickCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int UpClickCar(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
UpCar(pCurrent_choice, pCurrent_mode);
return 0;
}
// IDA: int __usercall DownClickCar@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int DownClickCar(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();
DownCar(pCurrent_choice, pCurrent_mode);
return 0;
}
// IDA: int __usercall ChangeCarGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int ChangeCarGoAhead(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
if (gChange_race_net_mode == 0 || gCar_details[gProgram_state.cars_available[gCurrent_car_index]].ownership != eCar_owner_someone) {
return 1;
} else {
DRS3StartSound(gIndexed_outlets[0], 3100);
return 0;
}
}
// IDA: int __usercall ChangeCar@<EAX>(int pNet_mode@<EAX>, int *pCar_index@<EDX>, tNet_game_details *pNet_game@<EBX>)
int ChangeCar(int pNet_mode, int* pCar_index, tNet_game_details* pNet_game) {
static tFlicette flicker_on[4];
static tFlicette flicker_off[4];
static tFlicette push[4];
static tMouse_area mouse_areas[4];
static tInterface_spec interface_spec;
static tFlicette flicker_on[4] = {
{ 43, { 60, 120 }, { 154, 370 } },
{ 43, { 221, 442 }, { 154, 370 } },
{ 221, { 30, 60 }, { 78, 187 } },
{ 221, { 30, 60 }, { 78, 187 } },
};
static tFlicette flicker_off[4] = {
{ 42, { 60, 120 }, { 154, 370 } },
{ 42, { 221, 442 }, { 154, 370 } },
{ 220, { 30, 60 }, { 78, 187 } },
{ 220, { 30, 60 }, { 78, 187 } },
};
static tFlicette push[4] = {
{ 154, { 60, 120 }, { 154, 370 } },
{ 45, { 221, 442 }, { 154, 370 } },
{ 222, { 30, 60 }, { 78, 187 } },
{ 225, { 30, 60 }, { 118, 283 } },
};
static tMouse_area mouse_areas[4] = {
{ { 60, 120 }, { 154, 370 }, { 125, 250 }, { 174, 418 }, 0, 0, 0, NULL },
{ { 221, 442 }, { 154, 370 }, { 286, 572 }, { 174, 418 }, 1, 0, 0, NULL },
{ { 30, 60 }, { 78, 187 }, { 45, 90 }, { 104, 250 }, -1, 0, 0, UpClickCar },
{ { 30, 60 }, { 118, 283 }, { 45, 90 }, { 145, 348 }, -1, 0, 0, DownClickCar },
};
static tInterface_spec interface_spec = {
0, 236, 62, 0, 0, 0, -1,
{ -1, 0 }, { -1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
{ -1, 0 }, { 1, 0 }, { 0, 0 }, { 1, 0 }, { NULL, NULL },
{ -1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { UpCar, NULL },
{ -1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { DownCar, NULL },
{ 1, 1 }, { ChangeCarGoAhead, NULL},
{ 1, 1 }, { NULL, NULL },
NULL, DrawCar, 0, NULL, NULL, NULL, 0, { 0, 0 }, NULL, 1, 1,
COUNT_OF(flicker_on), flicker_on, flicker_off, push,
COUNT_OF(mouse_areas), mouse_areas,
0, NULL,
};
int i;
int result;
int power_up_levels[3];
LOG_TRACE("(%d, %p, %p)", pNet_mode, pCar_index, pNet_game);
NOT_IMPLEMENTED();
gChoose_car_net_game = pNet_game;
gChange_race_net_mode = pNet_mode;
gStart_interface_spec = &interface_spec;
for (i = 0; i < gProgram_state.number_of_cars; i++) {
if (gProgram_state.cars_available[i] == *pCar_index) {
gCurrent_car_index = i;
break;
}
}
if (gProgram_state.game_completed) {
gProgram_state.number_of_cars = gNumber_of_racers;
for (i = 0; i < gProgram_state.number_of_cars; i++) {
gProgram_state.cars_available[i] = i;
}
}
for (i = 0; i < gProgram_state.number_of_cars; i++) {
if (gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data == NULL) {
LoadFlicData(gOpponents[gProgram_state.cars_available[i]].stolen_car_flic_name,
&gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data,
&gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data_length);
} else {
MAMSLock((void**)&gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data);
}
}
InitialiseFlicPanel(0,
gCurrent_graf_data->change_car_panel_left,
gCurrent_graf_data->change_car_panel_top,
gCurrent_graf_data->change_car_panel_right - gCurrent_graf_data->change_car_panel_left,
gCurrent_graf_data->change_car_panel_bottom - gCurrent_graf_data->change_car_panel_top);
SetCarFlic();
if (pNet_mode) {
gTaken_image = LoadPixelmap("TAKEN.PIX");
}
result = DoInterfaceScreen(&interface_spec, pNet_mode, 0);
if (pNet_mode) {
FadePaletteDown();
} else {
RunFlic(237);
}
for (i = 0; i < gProgram_state.number_of_cars; i++) {
MAMSUnlock((void**)&gOpponents[gProgram_state.cars_available[i]].stolen_car_image_data);
}
DisposeFlicPanel(0);
if (result == 0) {
if (pNet_mode) {
*pCar_index = gProgram_state.cars_available[gCurrent_race_index];
} else {
AboutToLoadFirstCar();
SwitchToRealResolution();
for (i = 0; i < COUNT_OF(power_up_levels); i++) {
power_up_levels[i] = gProgram_state.current_car.power_up_levels[i];
}
LoadCar(gOpponents[gProgram_state.cars_available[gCurrent_car_index]].car_file_name,
eDriver_local_human,
&gProgram_state.current_car,
gProgram_state.cars_available[gCurrent_car_index],
gProgram_state.player_name[gProgram_state.frank_or_anniness],
&gOur_car_storage_space);
for (i = 0; i < COUNT_OF(power_up_levels); i++) {
gProgram_state.current_car.power_up_levels[i] = power_up_levels[i];
}
SwitchToLoresMode();
SetCarStorageTexturingLevel(&gOur_car_storage_space, GetCarTexturingLevel(), eCTL_full);
DisposeRaceInfo(&gCurrent_race);
SelectOpponents(&gCurrent_race);
LoadRaceInfo(gProgram_state.current_race_index, &gCurrent_race);
}
return 1;
} else {
return 0;
}
}
// IDA: void __cdecl DoChangeCar()
void DoChangeCar() {
LOG_TRACE("()");
NOT_IMPLEMENTED();
ChangeCar(0, &gProgram_state.current_car.index, NULL);
}
// IDA: int __cdecl PartsShopRecommended()

View File

@ -867,7 +867,28 @@ void DisposeFunkotronics(int pOwner) {
int i;
tFunkotronic_spec* the_funk;
LOG_TRACE("(%d)", pOwner);
NOT_IMPLEMENTED();
if (gFunkotronics_array == NULL) {
return;
}
for (i = 0; i < gFunkotronics_array_size; i++) {
the_funk = &gFunkotronics_array[i];
PossibleService();
if (the_funk->owner == pOwner) {
the_funk->owner = -999;
if (the_funk->proximity_array != NULL) {
BrMemFree(the_funk->proximity_array);
}
if (the_funk->texture_animation_type == eTexture_animation_flic) {
BrMemFree(the_funk->texture_animation_data.flic_info.flic_data);
EndFlic(&the_funk->texture_animation_data.flic_info.flic_descriptor);
BrMemFree(the_funk->material->colour_map->pixels);
the_funk->material->colour_map->pixels = NULL;
BrPixelmapFree(the_funk->material->colour_map);
the_funk->material->colour_map = NULL;
}
}
}
}
// IDA: void __usercall AddProximityVertex(br_vector3 *pV@<EAX>, tFunkotronic_spec *pThe_funk@<EDX>)
@ -1257,7 +1278,17 @@ void DisposeGroovidelics(int pOwner) {
int i;
tGroovidelic_spec* the_groove;
LOG_TRACE("(%d)", pOwner);
NOT_IMPLEMENTED();
if (gGroovidelics_array == NULL) {
return;
}
for (i = 0; i < gGroovidelics_array_size; i++) {
the_groove = &gGroovidelics_array[i];
PossibleService();
if (the_groove->owner == pOwner) {
the_groove->owner = -999;
}
}
}
// IDA: tGroovidelic_spec* __cdecl AddNewGroovidelic()