#include "options.h"
#include "brucetrk.h"
#include "controls.h"
#include "depth.h"
#include "displays.h"
#include "dr_types.h"
#include "drmem.h"
#include "errors.h"
#include "flicplay.h"
#include "globvars.h"
#include "grafdata.h"
#include "graphics.h"
#include "harness/config.h"
#include "harness/trace.h"
#include "input.h"
#include "intrface.h"
#include "loading.h"
#include "network.h"
#include "pd/sys.h"
#include "sound.h"
#include "spark.h"
#include "utility.h"
#include "world.h"
#include <brender/brender.h>
#include <stdlib.h>
#include <string.h>
int gKey_defns[18] = { 48, 49, 46, 47, 53, 44, 59, 57, 55, 45, 50, 51, 52, 56, 62, 63, 64, 66 };
tRadio_bastards gRadio_bastards__options[13] = {
// suffix added to avoid duplicate symbol
{ 4, 36, 0, { 132, 175, 221, 253, 0 } },
{ 3, 45, 0, { 132, 157, 217, 0, 0 } },
{ 3, 54, 0, { 132, 183, 236, 0, 0 } },
{ 3, 67, 0, { 132, 194, 234, 0, 0 } },
{ 3, 76, 0, { 132, 194, 234, 0, 0 } },
{ 4, 89, 0, { 132, 176, 204, 246, 0 } },
{ 4, 98, 0, { 132, 176, 204, 246, 0 } },
{ 2, 111, 0, { 132, 158, 0, 0, 0 } },
{ 2, 120, 0, { 132, 158, 0, 0, 0 } },
{ 2, 129, 0, { 132, 158, 0, 0, 0 } },
{ 2, 138, 0, { 132, 158, 0, 0, 0 } },
{ 3, 150, 0, { 132, 164, 207, 0, 0 } },
{ 4, 153, 0, { 177, 199, 220, 242, 0 } },
};
int gKey_count;
int gLast_graph_sel__options; // suffix added to avoid duplicate symbol
char* gKey_names[125];
int gPending_entry;
tInterface_spec* gThe_interface_spec__options; // suffix added to avoid duplicate symbol
int gOrig_key_mapping[67];
br_pixelmap* gDials_pix;
int gCurrent_key;
// IDA: void __usercall DrawDial(int pWhich_one@<EAX>, int pWhich_stage@<EDX>)
void DrawDial(int pWhich_one, int pWhich_stage) {
LOG_TRACE("(%d, %d)", pWhich_one, pWhich_stage);
RemoveTransientBitmaps(1);
DRPixelmapRectangleMaskedCopy(gBack_screen,
gCurrent_graf_data->dial__x[pWhich_one],
gCurrent_graf_data->dial__y[pWhich_one],
gDials_pix,
0,
pWhich_stage * 64,
gDials_pix->width,
64);
ProcessFlicQueue(gFrame_period);
DoMouseCursor();
PDScreenBufferSwap(0);
}
// IDA: void __usercall MoveDialFromTo(int pWhich_one@<EAX>, int pOld_stage@<EDX>, int pNew_stage@<EBX>)
void MoveDialFromTo(int pWhich_one, int pOld_stage, int pNew_stage) {
tS32 time_diff;
tU32 start_time;
LOG_TRACE("(%d, %d, %d)", pWhich_one, pOld_stage, pNew_stage);
DrawDial(pWhich_one, pOld_stage);
start_time = PDGetTotalTime();
while ((time_diff = PDGetTotalTime() - start_time) < 100) {
DrawDial(pWhich_one, pOld_stage + (pNew_stage - pOld_stage) * time_diff / 100);
}
DrawDial(pWhich_one, pNew_stage);
start_time = PDGetTotalTime();
DrawDial(pWhich_one, pNew_stage < 24 ? pNew_stage + 1 : 22);
while ((time_diff = PDGetTotalTime() - start_time) < 20) {
}
start_time = PDGetTotalTime();
DrawDial(pWhich_one, pNew_stage == 0 ? 2 : pNew_stage - 1);
while ((time_diff = PDGetTotalTime() - start_time) < 20) {
}
start_time = PDGetTotalTime();
DrawDial(pWhich_one, pNew_stage < 24 ? pNew_stage + 1 : 22);
while ((time_diff = PDGetTotalTime() - start_time) < 20) {
}
start_time = PDGetTotalTime();
DrawDial(pWhich_one, pNew_stage);
while ((time_diff = PDGetTotalTime() - start_time) < 20) {
}
start_time = PDGetTotalTime();
DrawDial(pWhich_one, pNew_stage == 0 ? 2 : pNew_stage - 1);
while ((time_diff = PDGetTotalTime() - start_time) < 20) {
}
DrawDial(pWhich_one, pNew_stage);
}
// IDA: void __cdecl SoundOptionsStart()
void SoundOptionsStart(void) {
LOG_TRACE("()");
DrawDial(0, 0);
DrawDial(1, 0);
MoveDialFromTo(0, 0, 4 * gProgram_state.music_volume);
MoveDialFromTo(1, 0, 4 * gProgram_state.music_volume);
}
// IDA: int __usercall SoundOptionsDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)
int SoundOptionsDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) {
LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out);
MoveDialFromTo(0, 4 * gProgram_state.music_volume, 0);
MoveDialFromTo(0, 4 * gProgram_state.effects_volume, 0);
return pCurrent_choice;
}
// IDA: int __usercall SoundOptionsLeft@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int SoundOptionsLeft(int* pCurrent_choice, int* pCurrent_mode) {
int old_value;
int* the_value;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (*pCurrent_choice == 2) {
return 0;
}
the_value = (*pCurrent_choice == 0) ? &gProgram_state.music_volume : &gProgram_state.effects_volume;
old_value = *the_value;
*the_value -= 1;
if (*the_value < 0) {
*the_value = 0;
}
SetSoundVolumes();
DRS3StartSound(gEffects_outlet, 3000);
MoveDialFromTo(*pCurrent_choice, 4 * old_value, 4 * *the_value);
return 0;
}
// IDA: int __usercall SoundOptionsRight@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int SoundOptionsRight(int* pCurrent_choice, int* pCurrent_mode) {
int old_value; // Pierre-Marie Baty -- unused variable
int* the_value; // Pierre-Marie Baty -- unused variable
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (*pCurrent_choice == 2) {
return 0;
}
the_value = (*pCurrent_choice == 0) ? &gProgram_state.music_volume : &gProgram_state.effects_volume;
old_value = *the_value;
*the_value += 1;
if (*the_value >= 6) {
*the_value = 6;
}
SetSoundVolumes();
DRS3StartSound(gEffects_outlet, 3000);
MoveDialFromTo(*pCurrent_choice, 4 * old_value, 4 * *the_value);
return 0;
}
// IDA: int __usercall SoundClick@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int SoundClick(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
float x_delta; // Pierre-Marie Baty -- unused variable
float y_delta; // Pierre-Marie Baty -- unused variable
float angle; // Pierre-Marie Baty -- unused variable
int old_value; // Pierre-Marie Baty -- unused variable
int* the_value; // Pierre-Marie Baty -- unused variable
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
#define ANGLE_RANGE_START (20 * PI / 360)
#define ANGLE_RANGE_END (340 * PI / 360)
x_delta = pX_offset - gCurrent_graf_data->dial__x_centre;
y_delta = gCurrent_graf_data->dial__y_centre - pY_offset;
if (y_delta <= 0.f) {
return 0;
}
angle = x_delta == 0.f ? PI / 2 : atanf(y_delta / x_delta);
if (angle < 0.f) {
angle += PI;
}
if (angle > ANGLE_RANGE_START && angle < ANGLE_RANGE_END) {
the_value = (*pCurrent_choice == 0) ? &gProgram_state.music_volume : &gProgram_state.effects_volume;
old_value = *the_value;
*the_value = (ANGLE_RANGE_END - angle + 0.233001455141243) / 0.4660029102824859;
if (*the_value > 6) {
*the_value = 6;
} else if (*the_value < 0) {
*the_value = 0;
}
if (*the_value != old_value) {
SetSoundVolumes();
if (old_value < *the_value) {
DRS3StartSound(gEffects_outlet, 3000);
} else {
DRS3StartSound(gEffects_outlet, 3000);
}
MoveDialFromTo(*pCurrent_choice, 4 * old_value, 4 * *the_value);
}
}
return 0;
}
// IDA: void __cdecl DoSoundOptions()
void DoSoundOptions(void) {
static tFlicette flicker_on[3] = {
{ 156, { 26, 52 }, { 21, 50 } },
{ 156, { 155, 310 }, { 88, 211 } },
{ 43, { 38, 76 }, { 153, 367 } },
};
static tFlicette flicker_off[3] = {
{ 155, { 26, 52 }, { 21, 50 } },
{ 155, { 155, 310 }, { 88, 211 } },
{ 42, { 38, 76 }, { 153, 367 } },
};
static tFlicette push[3] = {
{ 156, { 26, 52 }, { 21, 50 } },
{ 156, { 155, 310 }, { 88, 211 } },
{ 43, { 38, 76 }, { 153, 367 } },
};
static tMouse_area mouse_areas[3] = {
{ { 26, 52 }, { 21, 50 }, { 144, 288 }, { 97, 233 }, 0, 0, 0, SoundClick },
{ { 155, 310 }, { 88, 211 }, { 273, 546 }, { 164, 394 }, 1, 0, 0, SoundClick },
{ { 38, 76 }, { 153, 367 }, { 101, 202 }, { 173, 415 }, 2, 0, 0, NULL },
};
static tInterface_spec interface_spec = {
0,
150,
0,
0,
0,
0,
1,
{ -1, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ SoundOptionsLeft, NULL },
{ -1, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ SoundOptionsRight, NULL },
{ -1, 0 },
{ -1, 0 },
{ 0, 0 },
{ 2, 0 },
{ NULL, NULL },
{ -1, 0 },
{ 1, 0 },
{ 0, 0 },
{ 2, 0 },
{ NULL, NULL },
{ 1, 1 },
{ NULL, NULL },
{ 1, 1 },
{ NULL, NULL },
NULL,
NULL,
0,
NULL,
SoundOptionsStart,
SoundOptionsDone,
0,
{ 0, 0 },
NULL,
2,
1,
COUNT_OF(flicker_on),
flicker_on,
flicker_off,
push,
COUNT_OF(mouse_areas),
mouse_areas,
0,
NULL,
};
int result; // Pierre-Marie Baty -- unused variable
LOG_TRACE("()");
DoInterfaceScreen(&interface_spec, 0, 0);
if (!gProgram_state.racing) {
RunFlic(151);
} else {
FadePaletteDown();
}
}
// IDA: void __cdecl GetGraphicsOptions()
void GetGraphicsOptions(void) {
int value;
br_scalar br_value;
LOG_TRACE("()");
value = GetCarSimplificationLevel();
if (value > 1) {
value--;
}
gRadio_bastards__options[0].current_value = value;
switch (GetCarTexturingLevel()) {
case eCTL_none:
value = 2;
break;
case eCTL_transparent:
value = 1;
break;
case eCTL_full:
value = 0;
break;
case eCTL_count:
TELL_ME_IF_WE_PASS_THIS_WAY();
break;
}
gRadio_bastards__options[1].current_value = value;
switch (GetShadowLevel()) {
case eShadow_none:
value = 2;
break;
case eShadow_us_only:
value = 1;
break;
default:
value = 0;
break;
}
gRadio_bastards__options[2].current_value = value;
switch (GetWallTexturingLevel()) {
case eWTL_none:
value = 2;
break;
case eWTL_linear:
value = 1;
break;
case eWTL_full:
value = 0;
break;
case eWTL_count:
TELL_ME_IF_WE_PASS_THIS_WAY();
break;
}
gRadio_bastards__options[3].current_value = value;
switch (GetRoadTexturingLevel()) {
case eRTL_none:
value = 2;
break;
case eRTL_full:
value = 0;
break;
case eRTL_count:
TELL_ME_IF_WE_PASS_THIS_WAY();
break;
}
gRadio_bastards__options[4].current_value = value;
value = (int)((35.f - GetYon()) / 5.f);
gRadio_bastards__options[5].current_value = value;
br_value = GetYonFactor();
if (br_value < .5f) {
if (br_value < .25f) {
value = 3;
} else {
value = 2;
}
} else {
if (br_value < 1.f) {
value = 1;
} else {
value = 0;
}
}
gRadio_bastards__options[6].current_value = value;
value = !GetSkyTextureOn();
gRadio_bastards__options[7].current_value = value;
value = !GetDepthCueingOn();
gRadio_bastards__options[8].current_value = value;
value = !GetAccessoryRendering();
gRadio_bastards__options[9].current_value = value;
value = !GetSmokeOn();
gRadio_bastards__options[10].current_value = value;
value = 2 - GetSoundDetailLevel();
gRadio_bastards__options[11].current_value = value;
}
// IDA: void __cdecl SetGraphicsOptions()
void SetGraphicsOptions(void) {
LOG_TRACE("()");
if (gRadio_bastards__options[0].current_value < 2) {
SetCarSimplificationLevel(gRadio_bastards__options[0].current_value);
} else {
SetCarSimplificationLevel(gRadio_bastards__options[0].current_value + 1);
}
switch (gRadio_bastards__options[1].current_value) {
case 0:
SetCarTexturingLevel(eCTL_full);
break;
case 1:
SetCarTexturingLevel(eCTL_transparent);
break;
case 2:
SetCarTexturingLevel(eCTL_none);
break;
}
switch (gRadio_bastards__options[2].current_value) {
case 0:
SetShadowLevel(eShadow_everyone);
break;
case 1:
SetShadowLevel(eShadow_us_only);
break;
case 2:
SetShadowLevel(eShadow_none);
break;
}
switch (gRadio_bastards__options[3].current_value) {
case 0:
SetWallTexturingLevel(eWTL_full);
break;
case 1:
SetWallTexturingLevel(eWTL_linear);
break;
case 2:
SetWallTexturingLevel(eWTL_none);
break;
}
switch (gRadio_bastards__options[4].current_value) {
case 0:
SetRoadTexturingLevel(eRTL_full);
break;
case 2:
SetRoadTexturingLevel(eRTL_none);
break;
}
SetYon(35.f - gRadio_bastards__options[5].current_value * 5.f);
switch (gRadio_bastards__options[6].current_value) {
case 0:
SetYonFactor(1.f);
break;
case 1:
SetYonFactor(.5f);
break;
case 2:
SetYonFactor(.25f);
break;
case 3:
SetYonFactor(.125f);
break;
}
SetSkyTextureOn(1 - gRadio_bastards__options[7].current_value);
SetDepthCueingOn(1 - gRadio_bastards__options[8].current_value);
SetAccessoryRendering(1 - gRadio_bastards__options[9].current_value);
SetSmokeOn(1 - gRadio_bastards__options[10].current_value);
SetSoundDetailLevel(2 - gRadio_bastards__options[11].current_value);
SaveOptions();
}
// IDA: void __usercall PlayRadioOn2(int pIndex@<EAX>, int pValue@<EDX>)
void PlayRadioOn2(int pIndex, int pValue) {
LOG_TRACE("(%d, %d)", pIndex, pValue);
RunFlicAt(288,
gRadio_bastards__options[pIndex].left[pValue],
gRadio_bastards__options[pIndex].top);
}
// IDA: void __usercall PlayRadioOff2(int pIndex@<EAX>, int pValue@<EDX>)
void PlayRadioOff2(int pIndex, int pValue) {
LOG_TRACE("(%d, %d)", pIndex, pValue);
RunFlicAt(287,
gRadio_bastards__options[pIndex].left[pValue],
gRadio_bastards__options[pIndex].top);
}
// IDA: void __usercall PlayRadioOn(int pIndex@<EAX>, int pValue@<EDX>)
void PlayRadioOn__options(int pIndex, int pValue) {
LOG_TRACE("(%d, %d)", pIndex, pValue);
RemoveTransientBitmaps(1);
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
PlayRadioOn2(pIndex, pValue);
TurnFlicTransparencyOff();
LetFlicFuckWithPalettes();
}
// IDA: void __usercall PlayRadioOff(int pIndex@<EAX>, int pValue@<EDX>)
void PlayRadioOff__options(int pIndex, int pValue) {
LOG_TRACE("(%d, %d)", pIndex, pValue);
RemoveTransientBitmaps(1);
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
PlayRadioOff2(pIndex, pValue);
TurnFlicTransparencyOff();
LetFlicFuckWithPalettes();
}
// IDA: void __cdecl DrawInitialRadios()
void DrawInitialRadios(void) {
int i;
LOG_TRACE("()");
RemoveTransientBitmaps(1);
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
// FIXME: count of radio buttons does not agree with windows version
for (i = 0; i < COUNT_OF(gRadio_bastards__options) - 1; i++) {
PlayRadioOn2(i, gRadio_bastards__options[i].current_value);
}
TurnFlicTransparencyOff();
LetFlicFuckWithPalettes();
}
// IDA: void __usercall RadioChanged(int pIndex@<EAX>, int pNew_value@<EDX>)
void RadioChanged(int pIndex, int pNew_value) {
LOG_TRACE("(%d, %d)", pIndex, pNew_value);
PlayRadioOff__options(pIndex, gRadio_bastards__options[pIndex].current_value);
PlayRadioOn__options(pIndex, pNew_value);
gRadio_bastards__options[pIndex].current_value = pNew_value;
}
// IDA: int __usercall GraphOptLeft@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int GraphOptLeft(int* pCurrent_choice, int* pCurrent_mode) {
int new_value;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
DRS3StartSound(gEffects_outlet, 3000);
new_value = gRadio_bastards__options[*pCurrent_choice - 2].current_value - 1;
if (new_value < 0) {
new_value = gRadio_bastards__options[*pCurrent_choice - 2].count - 1;
}
RadioChanged(*pCurrent_choice - 2, new_value);
return 1;
}
// IDA: int __usercall GraphOptRight@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int GraphOptRight(int* pCurrent_choice, int* pCurrent_mode) {
int new_value;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
DRS3StartSound(gEffects_outlet, 3000);
new_value = gRadio_bastards__options[*pCurrent_choice + -2].current_value + 1;
if (new_value == gRadio_bastards__options[*pCurrent_choice - 2].count) {
new_value = 0;
}
RadioChanged(*pCurrent_choice - 2, new_value);
return 1;
}
// IDA: int __usercall GraphOptUp@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int GraphOptUp(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (*pCurrent_mode == 0) {
*pCurrent_mode = 1;
*pCurrent_choice = 13;
DRS3StartSound(gEffects_outlet, 3000);
return 1;
} else if (*pCurrent_choice == 1) {
*pCurrent_mode = 0;
*pCurrent_choice = 0;
DRS3StartSound(gEffects_outlet, 3000);
return 1;
} else {
return 0;
}
}
// IDA: int __usercall GraphOptDown@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int GraphOptDown(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (*pCurrent_mode == 0) {
*pCurrent_mode = 1;
*pCurrent_choice = 2;
DRS3StartSound(gEffects_outlet, 3000);
return 1;
} else if (*pCurrent_choice == 14) {
*pCurrent_mode = 0;
*pCurrent_choice = 0;
DRS3StartSound(gEffects_outlet, 3000);
return 1;
} else {
return 0;
}
}
// IDA: int __usercall RadioClick@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int RadioClick(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
int i;
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
for (i = gRadio_bastards__options[*pCurrent_choice - 2].count - 1; i >= 0; i--) {
if (gThe_interface_spec__options->mouse_areas[2].left[gGraf_data_index] + pX_offset + 3 >= gRadio_bastards__options[*pCurrent_choice - 2].left[i]) {
DRS3StartSound(gEffects_outlet, 3000);
RadioChanged(*pCurrent_choice - 2, i);
return 0;
}
}
return 0;
}
// IDA: int __usercall GraphOptGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int GraphOptGoAhead(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
GraphOptRight(pCurrent_choice, pCurrent_mode);
return 0;
}
// IDA: void __usercall PlotAGraphBox(int pIndex@<EAX>, int pColour_value@<EDX>)
// Suffix added to avoid duplicate symbol
void PlotAGraphBox__options(int pIndex, int pColour_value) {
LOG_TRACE("(%d, %d)", pIndex, pColour_value);
if (pIndex < 0) {
return;
}
DrawRRectangle(gBack_screen,
gThe_interface_spec__options->mouse_areas[2].left[gGraf_data_index] - 6,
gRadio_bastards__options[pIndex].top - 3,
gThe_interface_spec__options->mouse_areas[2].right[gGraf_data_index] + 3,
gRadio_bastards__options[pIndex].top + gFonts[kFont_GRYLIT].height + 2 - (TranslationMode() ? 2 : 0), pColour_value);
}
// IDA: void __usercall DrawAGraphBox(int pIndex@<EAX>)
// Suffix added to avoid duplicate symbol
void DrawAGraphBox__options(int pIndex) {
LOG_TRACE("(%d)", pIndex);
PlotAGraphBox__options(pIndex, 45);
}
// IDA: void __usercall EraseAGraphBox(int pIndex@<EAX>)
// Suffix added to avoid duplicate symbol
void EraseAGraphBox__options(int pIndex) {
LOG_TRACE("(%d)", pIndex);
PlotAGraphBox__options(pIndex, 0);
}
// IDA: void __usercall DrawGraphBox(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>)
void DrawGraphBox(int pCurrent_choice, int pCurrent_mode) {
LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode);
if (pCurrent_choice != gCurrent_key) {
EraseAGraphBox__options(gCurrent_key - 2);
DrawAGraphBox__options(pCurrent_choice - 2);
gCurrent_key = pCurrent_choice;
}
}
// IDA: void __cdecl DoGraphicsOptions()
void DoGraphicsOptions(void) {
static tFlicette flicker_on[14] = {
{ 43, { 45, 90 }, { 166, 398 } },
{ 43, { 220, 440 }, { 166, 398 } },
{ 238, { 49, 98 }, { 36, 86 } },
{ 239, { 49, 98 }, { 45, 108 } },
{ 240, { 49, 98 }, { 54, 130 } },
{ 241, { 49, 98 }, { 67, 161 } },
{ 242, { 49, 98 }, { 76, 182 } },
{ 243, { 49, 98 }, { 89, 214 } },
{ 244, { 49, 98 }, { 98, 235 } },
{ 245, { 49, 98 }, { 111, 266 } },
{ 246, { 49, 98 }, { 120, 288 } },
{ 247, { 49, 98 }, { 129, 310 } },
{ 248, { 49, 98 }, { 138, 331 } },
{ 249, { 49, 98 }, { 150, 360 } },
};
static tFlicette flicker_off[14] = {
{ 42, { 45, 90 }, { 166, 398 } },
{ 42, { 220, 440 }, { 166, 398 } },
{ 265, { 49, 98 }, { 36, 86 } },
{ 266, { 49, 98 }, { 45, 108 } },
{ 267, { 49, 98 }, { 54, 130 } },
{ 268, { 49, 98 }, { 67, 161 } },
{ 269, { 49, 98 }, { 76, 182 } },
{ 270, { 49, 98 }, { 89, 214 } },
{ 271, { 49, 98 }, { 98, 235 } },
{ 272, { 49, 98 }, { 111, 266 } },
{ 273, { 49, 98 }, { 120, 288 } },
{ 274, { 49, 98 }, { 129, 310 } },
{ 275, { 49, 98 }, { 138, 331 } },
{ 276, { 49, 98 }, { 150, 360 } },
};
static tFlicette push[14] = {
{ 154, { 45, 90 }, { 166, 398 } },
{ 45, { 220, 440 }, { 166, 398 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
{ 45, { 210, 440 }, { 170, 408 } },
};
static tMouse_area mouse_areas[14] = {
{ { 45, 90 }, { 165, 396 }, { 104, 214 }, { 185, 444 }, 0, 0, 0, NULL },
{ { 220, 440 }, { 165, 396 }, { 276, 552 }, { 185, 444 }, 1, 0, 0, NULL },
{ { 49, 98 }, { 35, 84 }, { 284, 568 }, { 43, 103 }, 2, 1, 0, RadioClick },
{ { 49, 98 }, { 44, 106 }, { 284, 568 }, { 52, 125 }, 3, 1, 0, RadioClick },
{ { 49, 98 }, { 53, 127 }, { 284, 568 }, { 61, 146 }, 4, 1, 0, RadioClick },
{ { 49, 98 }, { 66, 158 }, { 284, 568 }, { 74, 178 }, 5, 1, 0, RadioClick },
{ { 49, 98 }, { 75, 180 }, { 284, 568 }, { 83, 199 }, 6, 1, 0, RadioClick },
{ { 49, 98 }, { 88, 192 }, { 284, 568 }, { 96, 230 }, 7, 1, 0, RadioClick },
{ { 49, 98 }, { 97, 233 }, { 284, 568 }, { 105, 252 }, 8, 1, 0, RadioClick },
{ { 49, 98 }, { 110, 264 }, { 284, 568 }, { 118, 283 }, 9, 1, 0, RadioClick },
{ { 49, 98 }, { 119, 286 }, { 284, 568 }, { 127, 305 }, 10, 1, 0, RadioClick },
{ { 49, 98 }, { 128, 307 }, { 284, 322 }, { 136, 326 }, 11, 1, 0, RadioClick },
{ { 49, 98 }, { 137, 329 }, { 284, 322 }, { 145, 348 }, 12, 1, 0, RadioClick },
{ { 49, 98 }, { 149, 358 }, { 284, 322 }, { 157, 377 }, 13, 1, 0, RadioClick },
};
static tInterface_spec interface_spec = {
0,
160,
0,
0,
0,
0,
1,
{ -1, 0 },
{ -1, 0 },
{ 0, 2 },
{ 1, 2 },
{ NULL, GraphOptLeft },
{ -1, 0 },
{ 1, 0 },
{ 0, 2 },
{ 1, 13 },
{ NULL, GraphOptRight },
{ -1, -1 },
{ 0, -1 },
{ 0, 1 },
{ 0, 13 },
{ GraphOptUp, GraphOptUp },
{ -1, -1 },
{ 1, 1 },
{ 0, 2 },
{ 0, 14 },
{ GraphOptDown, GraphOptDown },
{ 1, 1 },
{ NULL, GraphOptGoAhead },
{ 1, 1 },
{ NULL, NULL },
NULL,
DrawGraphBox,
0,
NULL,
DrawInitialRadios,
NULL,
0,
{ 0, 0 },
NULL,
1,
1,
COUNT_OF(flicker_on),
flicker_on,
flicker_off,
push,
COUNT_OF(mouse_areas),
mouse_areas,
0,
NULL,
};
LOG_TRACE("()");
gThe_interface_spec__options = &interface_spec;
gCurrent_key = -1;
LoadFont(kFont_GRYLIT);
GetGraphicsOptions();
if (DoInterfaceScreen(&interface_spec, 0, 0) == 0) {
SetGraphicsOptions();
}
if (gProgram_state.racing) {
FadePaletteDown();
} else {
RunFlic(161);
}
DisposeFont(kFont_GRYLIT); // Pierre-Marie Baty -- replaced font number with symbol
}
// IDA: void __cdecl CalibrateJoysticks()
void CalibrateJoysticks(void) {
//tJoy_calib_stage stage; // Pierre-Marie Baty -- unused variable
//int escaped; // Pierre-Marie Baty -- unused variable
//int joy_value_x; // Pierre-Marie Baty -- unused variable
//int joy_value_y; // Pierre-Marie Baty -- unused variable
//int key; // Pierre-Marie Baty -- unused variable
//int top_left[2]; // Pierre-Marie Baty -- unused variable
//int bot_right[2]; // Pierre-Marie Baty -- unused variable
//int centre[2]; // Pierre-Marie Baty -- unused variable
//int range[2]; // Pierre-Marie Baty -- unused variable
//int min[2]; // Pierre-Marie Baty -- unused variable
//int i; // Pierre-Marie Baty -- unused variable
//int saved_1x; // Pierre-Marie Baty -- unused variable
//int saved_1y; // Pierre-Marie Baty -- unused variable
//int saved_2x; // Pierre-Marie Baty -- unused variable
//int saved_2y; // Pierre-Marie Baty -- unused variable
//int max; // Pierre-Marie Baty -- unused variable
//char s[256]; // Pierre-Marie Baty -- unused variable
LOG_TRACE("()");
#ifdef __DOS__
NOT_IMPLEMENTED();
#else
NetFullScreenMessage(229, 0);
#endif
}
// IDA: void __usercall StripControls(unsigned char *pStr@<EAX>)
void StripControls(unsigned char* pStr) {
int i;
int len;
LOG_TRACE("(%p)", pStr);
for (i = 0; i < len; i++) {
if (pStr[i] < ' ') {
memmove(&pStr
[i
], &pStr
[i
+ 1], (len
- i
) * sizeof(char));
len--;
#ifdef DETHRACE_FIX_BUGS
// correctly handle stripping multiple control characters
i--;
#endif
}
}
}
// IDA: void __cdecl LoadKeyNames()
void LoadKeyNames(void) {
int i;
FILE* f;
tPath_name the_path;
unsigned char s[256];
LOG_TRACE("()");
PathCat(the_path, gApplication_path, "KEYNAMES.TXT");
f = DRfopen(the_path, "rt");
if (f == NULL) {
FatalError(kFatalError_OpenKeyNamesFile);
}
for (i = 0; i < COUNT_OF(gKey_names); i++) {
fgets((char*)s
, sizeof(s
), f
);
StripControls(s);
gKey_names
[i
] = BrMemAllocate
(strlen((char*)s
) + 1, kMem_key_names
);
strcpy(gKey_names
[i
], (char*)s
);
}
}
// IDA: void __cdecl DisposeKeyNames()
void DisposeKeyNames(void) {
int i;
LOG_TRACE("()");
for (i = 0; i < COUNT_OF(gKey_names); i++) {
BrMemFree(gKey_names[i]);
}
}
// IDA: void __cdecl SaveOrigKeyMapping()
void SaveOrigKeyMapping(void) {
LOG_TRACE("()");
memcpy(gOrig_key_mapping
, gKey_mapping
, sizeof(gKey_mapping
));
}
// IDA: void __usercall GetKeyCoords(int pIndex@<EAX>, int *pY@<EDX>, int *pName_x@<EBX>, int *pKey_x@<ECX>, int *pEnd_box)
void GetKeyCoords(int pIndex, int* pY, int* pName_x, int* pKey_x, int* pEnd_box) {
int col;
LOG_TRACE("(%d, %p, %p, %p, %p)", pIndex, pY, pName_x, pKey_x, pEnd_box);
if (pIndex >= 0) {
col = gKey_count + 1;
*pY = (pIndex % ((gKey_count + 1) / 2)) * gCurrent_graf_data->key_assign_y_pitch + gCurrent_graf_data->key_assign_y;
if (pIndex < col / 2) {
*pName_x = gCurrent_graf_data->key_assign_col_1;
*pKey_x = gCurrent_graf_data->key_assign_col_1_a;
*pEnd_box = gCurrent_graf_data->key_assign_col_2 - 7;
} else {
*pName_x = gCurrent_graf_data->key_assign_col_2;
*pKey_x = gCurrent_graf_data->key_assign_col_2_a;
*pEnd_box = gCurrent_graf_data->key_assign_col_2 + gCurrent_graf_data->key_assign_col_2 - gCurrent_graf_data->key_assign_col_1 - 7;
}
} else {
*pName_x = gCurrent_graf_data->key_assign_col_1;
*pKey_x = 0;
*pEnd_box = gCurrent_graf_data->key_assign_col_2 + gCurrent_graf_data->key_assign_col_2 - gCurrent_graf_data->key_assign_col_1 - 7;
*pY = gCurrent_graf_data->key_assign_key_map_y;
}
}
// IDA: void __cdecl SetKeysToDefault()
void SetKeysToDefault(void) {
FILE* f;
tPath_name the_path;
int i;
LOG_TRACE("()");
PathCat(the_path, gApplication_path, "DKEYMAPX.TXT");
the_path
[strlen(the_path
) - 5] = '0' + gKey_map_index
;
f = DRfopen(the_path, "rt");
if (f == NULL) {
FatalError(kFatalError_OpenKeyMapFile);
}
for (i = 0; i < COUNT_OF(gKey_mapping); i++) {
fscanf(f
, "%d", &gKey_mapping
[i
]);
}
}
// IDA: void __cdecl SaveKeyMapping()
void SaveKeyMapping(void) {
FILE* f;
tPath_name the_path;
int i;
LOG_TRACE("()");
PathCat(the_path, gApplication_path, "KEYMAP_X.TXT");
the_path
[strlen(the_path
) - 5] = '0' + gKey_map_index
;
PDFileUnlock(the_path);
f = DRfopen(the_path, "wb");
if (f == NULL) {
FatalError(kFatalError_OpenKeyMapFile);
}
for (i = 0; i < COUNT_OF(gKey_mapping); i++) {
}
}
// IDA: void __usercall ChangeKeyMapIndex(int pNew_one@<EAX>)
void ChangeKeyMapIndex(int pNew_one) {
LOG_TRACE("(%d)", pNew_one);
SaveKeyMapping();
gKey_map_index = pNew_one;
LoadKeyMapping();
SaveOrigKeyMapping();
}
// IDA: void __usercall DrawKeyAssignments(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>)
void DrawKeyAssignments(int pCurrent_choice, int pCurrent_mode) {
int i;
int y;
int x_coord;
int y_coord;
int name_x;
int key_x;
int new_key;
int end_box;
tDR_font* font_n;
tDR_font* font_k;
static int on_radios_last_time;
LOG_TRACE("(%d, %d)", pCurrent_choice, pCurrent_mode);
#if defined(DETHRACE_FIX_BUGS)
font_k = &gFonts[kFont_GRYDK];
#endif
if (gMouse_in_use && pCurrent_choice == 4) {
GetMousePosition(&x_coord, &y_coord);
if (y_coord >= gCurrent_graf_data->key_assign_key_map_y
&& y_coord <= gCurrent_graf_data->key_assign_key_map_y + gFonts[kFont_GRYLIT].height + 5
&& x_coord > gCurrent_graf_data->key_assign_col_1
&& x_coord < gCurrent_graf_data->key_assign_col_2 + gCurrent_graf_data->key_assign_col_2 - gCurrent_graf_data->key_assign_col_1 - 7) {
gCurrent_key = -1;
} else {
if (x_coord > gCurrent_graf_data->key_assign_col_2) {
new_key = (gKey_count + 1) / 2;
} else {
new_key = 0;
}
if (y_coord >= gCurrent_graf_data->key_assign_y - 2
&& y_coord < gCurrent_graf_data->key_assign_y + gCurrent_graf_data->key_assign_y_pitch * (gKey_count + 1) / 2) {
new_key += (y_coord - gCurrent_graf_data->key_assign_y - 2) / gCurrent_graf_data->key_assign_y_pitch;
if (new_key >= 0 && new_key < gKey_count) {
gCurrent_key = new_key;
}
}
}
}
BrPixelmapRectangleFill(gBack_screen,
gCurrent_graf_data->key_assign_col_1 - 3,
gCurrent_graf_data->key_assign_y - 3,
2 * (gCurrent_graf_data->key_assign_col_2 - gCurrent_graf_data->key_assign_col_1) - 3,
gCurrent_graf_data->key_assign_y_pitch * gKey_count / 2 + 4,
0);
GetKeyCoords(-1, &y, &name_x, &key_x, &end_box);
DrawRRectangle(gBack_screen, name_x - 3, y - 3, end_box, gFonts[kFont_GRYLIT].height + y + 2 - (TranslationMode() ? 2 : 0), 0);
for (i = 0; i < gKey_count; i++) {
GetKeyCoords(i, &y, &name_x, &key_x, &end_box);
if (i == gCurrent_key && pCurrent_mode != 0) {
font_n = &gFonts[kFont_GRNLIT];
font_k = &gFonts[kFont_GRYLIT];
} else {
font_n = &gFonts[kFont_GRNDK];
font_k = &gFonts[kFont_GRYDK];
}
TransDRPixelmapText(gBack_screen, name_x, y, font_n, GetMiscString(kMiscString_InputOptions_START + i), 640);
TransDRPixelmapText(gBack_screen, key_x, y, font_k, gKey_names[gKey_mapping[gKey_defns[i]] + 2], 640);
if (i == gCurrent_key && pCurrent_mode != 0) {
DrawRRectangle(gBack_screen, name_x - 3, y - 3, end_box, font_k->height + y + 2 - (TranslationMode() ? 2 : 0), 45);
}
}
if (gCurrent_key < 0 && pCurrent_mode != 0) {
GetKeyCoords(-1, &y, &name_x, &key_x, &end_box);
DrawRRectangle(gBack_screen, name_x - 3, y - 3, end_box, font_k->height + y + 2 - (TranslationMode() ? 2 : 0), 45);
}
if (on_radios_last_time && (pCurrent_mode == 0 || gCurrent_key >= 0)) {
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
RunFlicAt(193, gCurrent_graf_data->key_assign_flic_x, gCurrent_graf_data->key_assign_flic_y);
TurnFlicTransparencyOff();
DontLetFlicFuckWithPalettes();
} else if (!on_radios_last_time && pCurrent_mode != 0 && gCurrent_key < 0) {
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
RunFlicAt(194, gCurrent_graf_data->key_assign_flic_x, gCurrent_graf_data->key_assign_flic_y);
TurnFlicTransparencyOff();
DontLetFlicFuckWithPalettes();
}
on_radios_last_time = pCurrent_mode != 0 && gCurrent_key < 0;
}
// IDA: int __usercall KeyAssignLeft@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int KeyAssignLeft(int* pCurrent_choice, int* pCurrent_mode) {
int new_index;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (gCurrent_key < 0) {
if (gKey_map_index == 0) {
new_index = 3;
} else {
new_index = gKey_map_index - 1;
}
ChangeKeyMapIndex(new_index);
RadioChanged(12, new_index);
DRS3StartSound(gEffects_outlet, 3000);
} else {
if (gCurrent_key >= (gKey_count + 1) / 2) {
gCurrent_key -= (gKey_count + 1) / 2;
} else {
gCurrent_key += (gKey_count + 1) / 2;
if (gCurrent_key >= gKey_count) {
gCurrent_key -= (gKey_count + 1) / 2;
}
}
DRS3StartSound(gEffects_outlet, 3000);
}
return 1;
}
// IDA: int __usercall KeyAssignRight@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int KeyAssignRight(int* pCurrent_choice, int* pCurrent_mode) {
int new_index;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (gCurrent_key < 0) {
if (gKey_map_index < 3) {
new_index = gKey_map_index + 1;
} else {
new_index = 0;
}
ChangeKeyMapIndex(new_index);
RadioChanged(12, new_index);
DRS3StartSound(gEffects_outlet, 3000);
} else {
if (gCurrent_key >= (gKey_count + 1) / 2) {
gCurrent_key -= (gKey_count + 1) / 2;
} else {
gCurrent_key += (gKey_count + 1) / 2;
if (gCurrent_key >= gKey_count) {
gCurrent_key -= (gKey_count + 1) / 2;
}
}
DRS3StartSound(gEffects_outlet, 3000);
}
return 1;
}
// IDA: int __usercall KeyAssignUp@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int KeyAssignUp(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (*pCurrent_mode == 0) {
gCurrent_key = -1;
*pCurrent_choice = 4;
*pCurrent_mode = 1;
DRS3StartSound(gEffects_outlet, 3000);
} else if (gCurrent_key < 0) {
gCurrent_key = (gKey_count + 1) / 2 - 1;
*pCurrent_choice = 4;
*pCurrent_mode = 1;
DRS3StartSound(gEffects_outlet, 3000);
} else if (gCurrent_key > (gKey_count + 1) / 2) {
gCurrent_key -= 1;
} else if (gCurrent_key == (gKey_count + 1) / 2) {
*pCurrent_choice = 0;
*pCurrent_mode = 0;
} else if (gCurrent_key == 0) {
*pCurrent_choice = 0;
*pCurrent_mode = 0;
} else {
gCurrent_key -= 1;
}
DRS3StartSound(gEffects_outlet, 3000);
return 1;
}
// IDA: int __usercall KeyAssignDown@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int KeyAssignDown(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
if (*pCurrent_mode == 0) {
if (*pCurrent_choice >= 2) {
gCurrent_key = (gKey_count + 1) / 2;
} else {
gCurrent_key = 0;
}
*pCurrent_choice = 4;
*pCurrent_mode = 1;
} else if (gCurrent_key < 0) {
*pCurrent_choice = 0;
*pCurrent_mode = 0;
} else if (gCurrent_key < (gKey_count + 1) / 2) {
if (gCurrent_key < ((gKey_count + 1) / 2 - 1)) {
gCurrent_key += 1;
} else {
gCurrent_key = -1;
}
} else if (gCurrent_key < gKey_count - 1) {
gCurrent_key += 1;
} else {
gCurrent_key = -1;
}
DRS3StartSound(gEffects_outlet, 3000);
return 1;
}
// IDA: int __usercall KeyAssignGoAhead@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int KeyAssignGoAhead(int* pCurrent_choice, int* pCurrent_mode) {
int key;
int i;
int j;
int y;
int new_index;
int disallowed;
int name_x;
int key_x;
int end_box;
tDR_font* font;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
RemoveTransientBitmaps(1);
if (*pCurrent_mode == 0) {
key = -1;
if (*pCurrent_choice == 0) {
for (i = 0; i < COUNT_OF(gKey_defns); i++) {
if (gKey_mapping[gKey_defns[i]] == -2) {
key = i;
break;
}
}
}
if (key < 0) {
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
RunFlicAt(
gThe_interface_spec__options->pushed_flics[*pCurrent_choice].flic_index,
gThe_interface_spec__options->pushed_flics[*pCurrent_choice].x[gGraf_data_index],
gThe_interface_spec__options->pushed_flics[*pCurrent_choice].y[gGraf_data_index]);
TurnFlicTransparencyOff();
LetFlicFuckWithPalettes();
}
switch (*pCurrent_choice) {
case 0:
if (key < 0) {
disallowed = 1;
} else {
*pCurrent_choice = key + 4;
*pCurrent_mode = 1;
gCurrent_key = key;
gMouse_in_use = 0;
DRS3StartSound(gEffects_outlet, 3100);
disallowed = 0;
}
break;
case 1:
*pCurrent_choice = -1;
disallowed = 1;
break;
case 2:
SetKeysToDefault();
disallowed = 0;
break;
case 3:
disallowed = 1;
break;
default:
disallowed = 0;
break;
}
return disallowed;
} else {
if (gCurrent_key < 0) {
if (gKey_map_index < 3) {
new_index = gKey_map_index + 1;
} else {
new_index = 0;
}
ChangeKeyMapIndex(new_index);
RadioChanged(12, new_index);
} else {
PDScreenBufferSwap(0);
CyclePollKeys();
PollKeys();
WaitForNoKeys();
GetKeyCoords(gCurrent_key, &y, &name_x, &key_x, &end_box);
font = &gFonts[kFont_GRYLIT];
gPending_entry = -1;
while (1) {
key = PDAnyKeyDown();
if (key != -1 && key != 63) {
for (i = 27; i < 65; i++) {
if (gKey_mapping[i] == key && gKey_defns[gCurrent_key] != i) {
for (j = 0; j < COUNT_OF(gKey_defns); j++) {
if (gKey_defns[j] == i) {
gKey_mapping[i] = -2;
gPending_entry = j;
break;
}
}
if (gPending_entry < 0) {
DRS3StartSound(gEffects_outlet, 3100);
key = -1;
break;
}
}
}
}
CyclePollKeys();
PollKeys();
if ((PDGetTotalTime() / 100) & 1) {
TransDRPixelmapText(gBack_screen, key_x, y, font, gKey_names[gKey_mapping[gKey_defns[gCurrent_key]] + 2], 640);
} else {
BrPixelmapRectangleFill(gBack_screen, key_x, y, end_box - key_x, font->height, 0);
}
PDScreenBufferSwap(0);
if (key != -1 || EitherMouseButtonDown()) {
break;
}
}
DRS3StartSound(gEffects_outlet, 3004);
WaitForNoKeys();
if (key != 63 && key != -1) {
gKey_mapping[gKey_defns[gCurrent_key]] = key;
}
if (gPending_entry >= 0) {
*pCurrent_choice = gPending_entry + 4;
gCurrent_key = gPending_entry;
}
}
return 0;
}
}
// IDA: int __usercall MouseyClickBastard@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>, int pX_offset@<EBX>, int pY_offset@<ECX>)
int MouseyClickBastard(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_offset) {
int i;
int x_coord;
int y_coord;
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
if (gCurrent_key < 0) {
GetMousePosition(&x_coord, &y_coord);
for (i = gRadio_bastards__options[12].count - 1; i >= 0; i--) {
if (x_coord + 3 >= gRadio_bastards__options[12].left[i]) {
DRS3StartSound(gEffects_outlet, 3000);
ChangeKeyMapIndex(i);
RadioChanged(12, i);
break;
}
}
return 0;
} else {
KeyAssignGoAhead(pCurrent_choice, pCurrent_mode);
}
return 0;
}
// IDA: void __cdecl DrawInitialKMRadios()
void DrawInitialKMRadios(void) {
//int i; // Pierre-Marie Baty -- unused variable
LOG_TRACE("()");
RemoveTransientBitmaps(1);
DontLetFlicFuckWithPalettes();
TurnFlicTransparencyOn();
PlayRadioOn2(12, gKey_map_index);
gRadio_bastards__options[12].current_value = gKey_map_index;
TurnFlicTransparencyOff();
DontLetFlicFuckWithPalettes();
}
// IDA: void __cdecl DoControlOptions()
void DoControlOptions(void) {
static tFlicette flicker_on[4] = {
{ 177, { 51, 102 }, { 166, 398 } },
{ 177, { 112, 224 }, { 166, 398 } },
{ 177, { 173, 346 }, { 166, 398 } },
{ 177, { 234, 468 }, { 166, 398 } },
};
static tFlicette flicker_off[4] = {
{ 176, { 51, 102 }, { 166, 398 } },
{ 176, { 112, 224 }, { 166, 398 } },
{ 176, { 173, 346 }, { 166, 398 } },
{ 176, { 234, 468 }, { 166, 398 } },
};
static tFlicette push[4] = {
{ 172, { 51, 102 }, { 166, 398 } },
{ 175, { 112, 224 }, { 166, 398 } },
{ 174, { 173, 346 }, { 166, 398 } },
{ 173, { 234, 468 }, { 166, 398 } },
};
static tMouse_area mouse_areas[5] = {
{ { 51, 102 }, { 166, 398 }, { 102, 204 }, { 187, 449 }, 0, 0, 0, NULL },
{ { 112, 224 }, { 166, 398 }, { 164, 328 }, { 187, 449 }, 1, 0, 0, NULL },
{ { 173, 346 }, { 166, 398 }, { 225, 450 }, { 187, 449 }, 2, 0, 0, NULL },
{ { 234, 468 }, { 166, 398 }, { 286, 572 }, { 187, 449 }, 3, 0, 0, NULL },
{ { 45, 90 }, { 33, 79 }, { 285, 570 }, { 159, 382 }, 4, 1, 0, MouseyClickBastard },
};
static tInterface_spec interface_spec = {
0, 170, 179, 0, 0, 0, 1,
{ -1, -1 }, { -1, 0 }, { 0, 4 }, { 3, 4 }, { NULL, KeyAssignLeft },
{ -1, -1 }, { 1, 0 }, { 0, 4 }, { 3, 4 }, { NULL, KeyAssignRight },
{ -1, -1 }, { 0, 0 }, { 0, 4 }, { 3, 4 }, { KeyAssignUp, KeyAssignUp },
{ -1, -1 }, { 0, 0 }, { 0, 4 }, { 3, 4 }, { KeyAssignDown, KeyAssignDown },
{ 1, 1 }, { KeyAssignGoAhead, KeyAssignGoAhead }, { 1, 1 },
{ 0, 0 }, NULL, DrawKeyAssignments, 0, NULL, DrawInitialKMRadios, NULL, 0,
{ 0, 0 }, NULL, 3, 1,
COUNT_OF(flicker_on), flicker_on, flicker_off, push,
COUNT_OF(mouse_areas), mouse_areas,
0, NULL
};
int result;
//int swap_font_1; // Pierre-Marie Baty -- unused variable
//int swap_font_2; // Pierre-Marie Baty -- unused variable
//int swap_font_3; // Pierre-Marie Baty -- unused variable
int second_time_around;
int orig_key_map_index;
LOG_TRACE("()");
orig_key_map_index = gKey_map_index;
second_time_around = 0;
gThe_interface_spec__options = &interface_spec;
SaveOrigKeyMapping();
LoadKeyNames();
LoadFont(kFont_GRNDK);
LoadFont(kFont_GRYDK);
LoadFont(kFont_GRNLIT);
LoadFont(kFont_GRYLIT);
gPending_entry = -1;
gKey_count = 18;
gCurrent_key = 8;
while ((result = DoInterfaceScreen(&interface_spec, second_time_around, 0)) < 0) {
FadePaletteDown();
CalibrateJoysticks();
FadePaletteDown();
second_time_around = 1;
}
if (result == 0) {
SaveKeyMapping();
} else {
gKey_map_index = orig_key_map_index;
memcpy(gKey_mapping
, gOrig_key_mapping
, sizeof(gKey_mapping
));
}
DisposeFont(kFont_GRNDK); // Pierre-Marie Baty -- replaced font number with symbol
DisposeFont(kFont_GRYDK); // Pierre-Marie Baty -- replaced font number with symbol
DisposeFont(kFont_GRNLIT); // Pierre-Marie Baty -- replaced font number with symbol
DisposeFont(kFont_GRYLIT); // Pierre-Marie Baty -- replaced font number with symbol
DisposeKeyNames();
if (gProgram_state.racing) {
FadePaletteDown();
} else {
RunFlic(171);
}
}
// IDA: void __cdecl LoadSoundOptionsData()
void LoadSoundOptionsData(void) {
LOG_TRACE("()");
gDials_pix = LoadPixelmap("DIALSTCK.PIX");
if (gDials_pix == NULL) {
FatalError(kFatalError_LoadDialsPix);
}
}
// IDA: void __cdecl FreeSoundOptionsData()
void FreeSoundOptionsData(void) {
LOG_TRACE("()");
BrPixelmapFree(gDials_pix);
}
// IDA: void __cdecl DrawDisabledOptions()
void DrawDisabledOptions(void) {
br_pixelmap* image;
LOG_TRACE("()");
PrintMemoryDump(0, "INSIDE OPTIONS");
if (!harness_game_config.sound_options) {
// Disable sound options menu
image = LoadPixelmap("NOSNDOPT.PIX");
DisableChoice(0);
if (image != NULL) {
DRPixelmapRectangleMaskedCopy(gBack_screen, gCurrent_graf_data->sound_opt_disable_x,
gCurrent_graf_data->sound_opt_disable_y, image, 0, 0, image->width, image->height);
BrPixelmapFree(image);
}
}
// Disable graphics options menu when in-game
if (gProgram_state.track_spec.the_actor != NULL) {
image = LoadPixelmap("NODETOPT.PIX");
DisableChoice(1);
if (image != NULL) {
DRPixelmapRectangleMaskedCopy(gBack_screen, gCurrent_graf_data->graph_opt_disable_x,
gCurrent_graf_data->graph_opt_disable_y, image, 0, 0, image->width, image->height);
BrPixelmapFree(image);
}
}
}
// IDA: void __cdecl DoOptions()
void DoOptions(void) {
static tFlicette flicker_on[4] = {
{ 43, { 57, 114 }, { 41, 98 } },
{ 43, { 57, 114 }, { 78, 187 } },
{ 43, { 57, 114 }, { 114, 274 } },
{ 43, { 57, 114 }, { 154, 370 } }
};
static tFlicette flicker_off[4] = {
{ 42, { 57, 114 }, { 41, 98 } },
{ 42, { 57, 114 }, { 78, 187 } },
{ 42, { 57, 114 }, { 114, 274 } },
{ 42, { 57, 114 }, { 154, 370 } },
};
static tFlicette push[4] = {
{ 144, { 57, 114 }, { 41, 98 } },
{ 146, { 57, 114 }, { 78, 187 } },
{ 145, { 57, 114 }, { 114, 274 } },
{ 45, { 57, 114 }, { 154, 370 } },
};
static tMouse_area mouse_areas[4] = {
{ { 57, 114 }, { 41, 98 }, { 123, 246 }, { 62, 149 }, 0, 0, 0, NULL },
{ { 57, 114 }, { 78, 187 }, { 123, 246 }, { 99, 238 }, 1, 0, 0, NULL },
{ { 57, 114 }, { 114, 274 }, { 123, 246 }, { 135, 324 }, 2, 0, 0, NULL },
{ { 57, 114 }, { 154, 370 }, { 123, 246 }, { 175, 420 }, 3, 0, 0, NULL },
};
static tInterface_spec interface_spec = {
0,
140,
0,
141,
141,
141,
1,
{ -1, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ NULL, NULL },
{ -1, 0 },
{ 0, 0 },
{ 0, 0 },
{ 0, 0 },
{ NULL, NULL },
{ -1, 0 },
{ -1, 0 },
{ 0, 0 },
{ 3, 0 },
{ NULL, NULL },
{ -1, 0 },
{ 1, 0 },
{ 0, 0 },
{ 3, 0 },
{ NULL, NULL },
{ 1, 1 },
{ NULL, NULL },
{ 1, 1 },
{ NULL, NULL },
NULL,
NULL,
0,
NULL,
DrawDisabledOptions,
NULL,
0,
{ 0, 0 },
NULL,
3,
1,
COUNT_OF(flicker_on),
flicker_on,
flicker_off,
push,
COUNT_OF(mouse_areas),
mouse_areas,
0,
NULL,
};
int result;
LOG_TRACE("()");
PrintMemoryDump(0, "BEFORE ENTERING OPTIONS");
PreloadBunchOfFlics(1);
result = DoInterfaceScreen(&interface_spec, 0, gProgram_state.track_spec.the_actor ? 2 : 1);
switch (result) {
case 0:
DoSoundOptions();
break;
case 1:
DoGraphicsOptions();
break;
case 2:
DoControlOptions();
break;
}
UnlockBunchOfFlics(1);
PrintMemoryDump(0, "AFTER ENTERING OPTIONS");
}