Skip to content

Commit

Permalink
Implement sound options menu (hidden behind --sound-options) (#359)
Browse files Browse the repository at this point in the history
* Implement sound options menu (hidden behind --sound-options

* Don't use M_PI*

* DoInterfaceScreen uses gEffects_outlet instead of gIndexed_outlets[0]
  • Loading branch information
madebr committed May 28, 2024
1 parent c76b766 commit e07b711
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/DETHRACE/common/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ void Init2DStuff(void) {
// IDA: void __usercall InitialiseApplication(int pArgc@<EAX>, char **pArgv@<EDX>)
void InitialiseApplication(int pArgc, char** pArgv) {

if (harness_game_config.dos_mode) {
if (harness_game_config.gore_check) {
gProgram_state.sausage_eater_mode = gSausage_override ? 1 : (PDGetGorePassword() ? 0 : 1);
PDDisplayGoreworthiness(!gProgram_state.sausage_eater_mode);
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/DETHRACE/common/intrface.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,21 +513,21 @@ int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice)
}
if (go_ahead) {
if (pSpec->end_flic_go_ahead > 0) {
DRS3StartSound(gIndexed_outlets[0], 3007);
DRS3StartSound(gEffects_outlet, 3007);
RunFlic(pSpec->end_flic_go_ahead);
} else if (pSpec->end_flic_go_ahead < 0) {
FadePaletteDown();
}
} else if (escaped) {
if (pSpec->end_flic_escaped > 0) {
DRS3StartSound(gIndexed_outlets[0], 3007);
DRS3StartSound(gEffects_outlet, 3007);
RunFlic(pSpec->end_flic_escaped);
} else if (pSpec->end_flic_escaped < 0) {
FadePaletteDown();
}
} else {
if (pSpec->end_flic_otherwise > 0) {
DRS3StartSound(gIndexed_outlets[0], 3007);
DRS3StartSound(gEffects_outlet, 3007);
RunFlic(pSpec->end_flic_otherwise);
} else if (pSpec->end_flic_otherwise < 0) {
FadePaletteDown();
Expand Down
225 changes: 205 additions & 20 deletions src/DETHRACE/common/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "globvars.h"
#include "grafdata.h"
#include "graphics.h"
#include "harness/config.h"
#include "harness/trace.h"
#include "input.h"
#include "intrface.h"
Expand Down Expand Up @@ -53,43 +54,120 @@ 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);
NOT_IMPLEMENTED();

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);
NOT_IMPLEMENTED();

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("()");
NOT_IMPLEMENTED();

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);
NOT_IMPLEMENTED();

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);
NOT_IMPLEMENTED();

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;
int* the_value;
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();

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>)
Expand All @@ -100,19 +178,124 @@ int SoundClick(int* pCurrent_choice, int* pCurrent_mode, int pX_offset, int pY_o
int old_value;
int* the_value;
LOG_TRACE("(%p, %p, %d, %d)", pCurrent_choice, pCurrent_mode, pX_offset, pY_offset);
NOT_IMPLEMENTED();

#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];
static tFlicette flicker_off[3];
static tFlicette push[3];
static tMouse_area mouse_areas[3];
static tInterface_spec interface_spec;
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;
LOG_TRACE("()");
NOT_IMPLEMENTED();

DoInterfaceScreen(&interface_spec, 0, 0);
if (!gProgram_state.racing) {
RunFlic(151);
} else {
FadePaletteDown();
}
}

// IDA: void __cdecl GetGraphicsOptions()
Expand Down Expand Up @@ -1262,13 +1445,15 @@ void DrawDisabledOptions(void) {

PrintMemoryDump(0, "INSIDE 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);
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
Expand Down
13 changes: 9 additions & 4 deletions src/harness/harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,10 @@ void Harness_Init(int* argc, char* argv[]) {
harness_game_config.volume_multiplier = 1.0f;
// start window in windowed mode
harness_game_config.start_full_screen = 0;
// Emulate DOS behavior
harness_game_config.dos_mode = 0;
// Emulate gore check
harness_game_config.gore_check = 0;
// Enable Sound Options menu
harness_game_config.sound_options = 0;
// Skip binding socket to allow local network testing
harness_game_config.no_bind = 0;

Expand Down Expand Up @@ -250,8 +252,11 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) {
} else if (strcasecmp(argv[i], "--full-screen") == 0) {
harness_game_config.start_full_screen = 1;
handled = 1;
} else if (strcasecmp(argv[i], "--dos-mode") == 0) {
harness_game_config.dos_mode = 1;
} else if (strcasecmp(argv[i], "--gore-check") == 0) {
harness_game_config.gore_check = 1;
handled = 1;
} else if (strcasecmp(argv[i], "--sound-options") == 0) {
harness_game_config.sound_options = 1;
handled = 1;
} else if (strcasecmp(argv[i], "--no-bind") == 0) {
harness_game_config.no_bind = 1;
Expand Down
3 changes: 2 additions & 1 deletion src/harness/include/harness/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ typedef struct tHarness_game_config {
int enable_diagnostics;
float volume_multiplier;
int start_full_screen;
int dos_mode;
int gore_check;
int sound_options;
int no_bind;

int install_signalhandler;
Expand Down

0 comments on commit e07b711

Please sign in to comment.