Add code from Total Replay to detect the sound chip automatically on startup. This then leads to a complete rethinking about how to save/load the options for the game. It used to ask what slot the mockingboard was in (if any) and whether it had a speech chip. Now, the game should just know this information. So, I turned the first boolean in the save file into an options file version byte and bumped it to "2". The boolean was always true and was kind of a very simple "magic number" to say that the contents was valid. Now it is a version number of the contents. The slot number and boolean for the speech chip is are now each turned into booleans - one to say whether to enable a mockingboard if found and the other to enable the speech chip if found.

This means there are three booleans in the options related to sound now.  The first one enables/disables sound entirely and is default on.  The second is only relevant if the sound is enabled and says "use a mockingboard if present".  Again this is true by default.  Finally, the this says "use a speech chip on the mockingboard if present" and is only relevant if the mockingboard is also enabled.

So, the basic approach now is to default the "best" sound options and auto-detect the sound HW at launch.  The user can then use the options to downgrade their sound all the way to basic Apple // sound or turn off the sound entirely.
This commit is contained in:
Jeremy Rand 2020-03-04 22:23:09 -05:00
parent 72fc265e5a
commit 20ad7dda1c
10 changed files with 315 additions and 192 deletions

View File

@ -71,7 +71,6 @@ SRCDIRS+=
# If you want to add arguments to the compile commandline, add them # If you want to add arguments to the compile commandline, add them
# to this variable: # to this variable:
# CFLAGS += -DTOTAL_REPLAY_BUILD
CFLAGS += -Os CFLAGS += -Os
# If you want to add arguments to the assembly commandline, add them # If you want to add arguments to the assembly commandline, add them

View File

@ -16,20 +16,8 @@
// Implementation // Implementation
#ifdef TOTAL_REPLAY_BUILD
void totalReplayQuit(void)
{
__asm__ ("BIT $C082");
__asm__ ("JMP $100");
}
#endif
int main(void) int main(void)
{ {
#ifdef TOTAL_REPLAY_BUILD
atexit(totalReplayQuit);
#endif
initUI(); initUI();
printInstructions(); printInstructions();

View File

@ -46,6 +46,9 @@ static uint8_t *gMockDataDirA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc003, (uint8_t *
static uint8_t gMockingBoardInitialized = false; static uint8_t gMockingBoardInitialized = false;
static uint8_t gMockingBoardSpeechInitialized = false; static uint8_t gMockingBoardSpeechInitialized = false;
static uint8_t gMockingBoardSearchDone = false;
static tSlot gMockingBoardSlot = 0;
static bool gMockingBoardHasSpeech = false;
// Implementation // Implementation
@ -64,29 +67,47 @@ static uint8_t *mapIOPointer(tSlot slot, uint8_t *ptr)
} }
void mockingBoardInit(tSlot slot, bool hasSpeechChip) bool mockingBoardInit(void)
{ {
tMockingBoardSoundChip soundChip; tMockingBoardSoundChip soundChip;
if (!gMockingBoardSearchDone)
{
gMockingBoardSlot = getMockingBoardSlot();
if ((gMockingBoardSlot & 0x80) != 0)
gMockingBoardHasSpeech = true;
gMockingBoardSlot &= 0x7;
gMockingBoardSearchDone = true;
}
if (gMockingBoardSlot == 0)
return false;
if (gMockingBoardInitialized)
return true;
if (sizeof(tMockingSoundRegisters) != 16) { if (sizeof(tMockingSoundRegisters) != 16) {
printf("The sound registers must be 16 bytes long!\n"); printf("The sound registers must be 16 bytes long!\n");
} }
for (soundChip = SOUND_CHIP_1; soundChip < NUM_SOUND_CHIPS; soundChip++) { for (soundChip = SOUND_CHIP_1; soundChip < NUM_SOUND_CHIPS; soundChip++) {
gMockPortB[soundChip] = mapIOPointer(slot, gMockPortB[soundChip]); gMockPortB[soundChip] = mapIOPointer(gMockingBoardSlot, gMockPortB[soundChip]);
gMockPortA[soundChip] = mapIOPointer(slot, gMockPortA[soundChip]); gMockPortA[soundChip] = mapIOPointer(gMockingBoardSlot, gMockPortA[soundChip]);
gMockDataDirB[soundChip] = mapIOPointer(slot, gMockDataDirB[soundChip]); gMockDataDirB[soundChip] = mapIOPointer(gMockingBoardSlot, gMockDataDirB[soundChip]);
gMockDataDirA[soundChip] = mapIOPointer(slot, gMockDataDirA[soundChip]); gMockDataDirA[soundChip] = mapIOPointer(gMockingBoardSlot, gMockDataDirA[soundChip]);
*(gMockDataDirA[soundChip]) = 0xff; // Set port A for output *(gMockDataDirA[soundChip]) = 0xff; // Set port A for output
*(gMockDataDirB[soundChip]) = 0x7; // Set port B for output *(gMockDataDirB[soundChip]) = 0x7; // Set port B for output
} }
if (hasSpeechChip) { if (gMockingBoardHasSpeech) {
if (gMockingBoardSpeechInitialized) { if (gMockingBoardSpeechInitialized) {
mockingBoardSpeechShutdown(); mockingBoardSpeechShutdown();
} }
mockingBoardSpeechInit(slot); mockingBoardSpeechInit(gMockingBoardSlot);
gMockingBoardSpeechInitialized = true; gMockingBoardSpeechInitialized = true;
} else if (gMockingBoardSpeechInitialized) { } else if (gMockingBoardSpeechInitialized) {
mockingBoardSpeechShutdown(); mockingBoardSpeechShutdown();
@ -94,6 +115,7 @@ void mockingBoardInit(tSlot slot, bool hasSpeechChip)
} }
gMockingBoardInitialized = true; gMockingBoardInitialized = true;
return true;
} }
@ -108,6 +130,18 @@ void mockingBoardShutdown(void)
} }
tSlot mockingBoardSlot(void)
{
return gMockingBoardSlot;
}
bool mockingBoardHasSpeechChip(void)
{
return gMockingBoardHasSpeech;
}
static void writeCommand(tMockingBoardSoundChip soundChip, uint8_t command) static void writeCommand(tMockingBoardSoundChip soundChip, uint8_t command)
{ {
volatile uint8_t *ptr = gMockPortB[soundChip]; volatile uint8_t *ptr = gMockPortB[soundChip];

View File

@ -117,13 +117,15 @@ typedef struct tMockingSoundRegisters {
// API // API
extern uint8_t getMockingBoardSlot(void); extern bool mockingBoardInit(void);
extern void mockingBoardInit(tSlot slot, bool hasSpeechChip);
extern void mockingBoardShutdown(void); extern void mockingBoardShutdown(void);
extern tSlot mockingBoardSlot(void);
extern void mockingBoardPlaySound(tMockingBoardSpeaker speaker, tMockingSoundRegisters *registers); extern void mockingBoardPlaySound(tMockingBoardSpeaker speaker, tMockingSoundRegisters *registers);
extern void mockingBoardStopSound(tMockingBoardSpeaker speaker); extern void mockingBoardStopSound(tMockingBoardSpeaker speaker);
extern bool mockingBoardHasSpeechChip(void);
extern bool mockingBoardSpeechIsBusy(void); extern bool mockingBoardSpeechIsBusy(void);
extern bool mockingBoardSpeechIsPlaying(void); extern bool mockingBoardSpeechIsPlaying(void);
extern bool mockingBoardSpeak(uint8_t *data, uint16_t dataLen); extern bool mockingBoardSpeak(uint8_t *data, uint16_t dataLen);

View File

@ -18,6 +18,7 @@ extern uint16_t mockingBoardSpeechLen;
extern uint8_t mockingBoardSpeechBusy; extern uint8_t mockingBoardSpeechBusy;
extern uint8_t mockingBoardSpeechPlaying; extern uint8_t mockingBoardSpeechPlaying;
extern uint8_t getMockingBoardSlot(void);
extern void mockingBoardSpeechInit(uint8_t slot); extern void mockingBoardSpeechInit(uint8_t slot);
extern void mockingBoardSpeechShutdown(void); extern void mockingBoardSpeechShutdown(void);
extern void mockingBoardSpeakPriv(void); extern void mockingBoardSpeakPriv(void);

View File

@ -74,37 +74,128 @@ readChip:
; in: none ; in: none
; accelerators should be off ; accelerators should be off
; out: ; out:
; if card was found, A = #$n where n is the slot number of the card, otherwise #$00 ; if card was found, A = #$?n where n is the slot number of the card, otherwise #$00
; and bit 6 = 0 if Mockingboard Sound I found
; or bit 6 = 1 if Mockingboard Sound II or "A" found
; and bit 7 = 1 if Mockingboard Sound/Speech I or "C" found
; flags clobbered ; flags clobbered
; zp $80-$82 clobbered ; zp $80-$82 clobbered
; (jrand - and then restored because I am chicken and afraid of breaking cc65 runtime) ; (jrand - and then restored because I am chicken and afraid of breaking cc65 runtime)
; X/Y clobbered ; X/Y clobbered
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
.proc _getMockingBoardSlot .proc _getMockingBoardSlot
php
lda $80 lda $80
sta zp80Backup sta zp80Backup
lda $81 lda $81
sta zp81Backup sta zp81Backup
lda $82 lda $82
sta zp82Backup sta zp82Backup
lda $3fe
sta irq1Backup
lda $3ff
sta irq2Backup
lda #$00 lda #$00
sta $80 sta $80
ldx #$C7 sta $82 ; type
ldx #$C1
@slotLoop: @slotLoop:
stx $81 stx $81
ldy #$04 ; 6522 #1 $Cx04 ldy #$04 ; 6522 #1 $Cx04
jsr timercheck jsr @timercheck
bne @nextSlot beq @foundI
ldy #$84 ; 6522 #2 $Cx84 inx
jsr timercheck cpx #$C8
bne @nextSlot
beq @cleanup
@nextSlot:
dex
cpx #$C0
bne @slotLoop bne @slotLoop
ldx #$00 ; not found ldx #00 ; not found
jmp @cleanup
@foundI: ; sound I or better
ldy #$84 ; 6522 #2 $Cx84
jsr @timercheck
beq @foundII
ldy #$0C
sty @mb_smc3 + 1
iny
sty @mb_smc8 + 1
iny
sty @mb_smc7 + 1
sty @mb_smc11 + 1
.BYTE $2C ; Hide next 2 bytes using a BIT opcode
@foundII: ; stereo
ror $82
lda $81
sta @mb_smc1 + 2
sta @mb_smc2 + 2
sta @mb_smc3 + 2
sta @mb_smc4 + 2
sta @mb_smc5 + 2
sta @mb_smc6 + 2
sta @mb_smc7 + 2
sta @mb_smc8 + 2
sta @mb_smc9 + 2
sta @mb_smc10 + 2
sta @mb_smc11 + 2
sta @mb_smc12 + 2
sta @mb_smc13 + 2
; detect speech chip
sei
lda #<@mb_irq
sta $3fe
lda #>@mb_irq
sta $3ff
lda #0
@mb_smc1:
sta $c403
@mb_smc2:
sta $c402
lda #$0c
@mb_smc3:
sta $c48c
lda #$80
@mb_smc4:
sta $c443
lda #$c0
@mb_smc5:
sta $c440
lda #$70
@mb_smc6:
sta $c443
lda #$82
@mb_smc7:
sta $c48e
ldx #0
ldy #0
sec
cli
@wait_irq:
lda $80
bne @got_irq
iny
bne @wait_irq
inx
bne @wait_irq
clc
@got_irq:
sei
ror $82
lda $81
and #7
ora $82
tax
@cleanup: @cleanup:
lda zp80Backup lda zp80Backup
sta $80 sta $80
@ -112,25 +203,53 @@ readChip:
sta $81 sta $81
lda zp82Backup lda zp82Backup
sta $82 sta $82
lda irq1Backup
sta $3fe
lda irq2Backup
sta $3ff
txa txa
and #$07
ldx #$00 ldx #$00
plp
rts rts
timercheck: @timercheck:
lda ($80),y ; read 6522 timer low byte
sta $82
lda ($80),y ; second time
sec sec
sbc $82 lda ($80),y ; read 6522 timer low byte
cmp #$F8 ; looking for (-)8 cycles between reads sbc ($80),y ; second time
cmp #5 ; looking for (-)8 cycles between reads
beq :+ beq :+
cmp #$F7 ; FastChip //e clock is different cmp #6 ; FastChip //e clock is different
: rts : rts
@mb_irq:
lda #2
@mb_smc8:
sta $c48d
lda #0
@mb_smc9:
sta $c440
lda #$70
@mb_smc10:
sta $c443
sta $80
lda #2
@mb_smc11:
sta $c48e
lda #$ff
@mb_smc12:
sta $c403
lda #7
@mb_smc13:
sta $c402
lda $45
rti
; Locals ; Locals
zp80Backup: .BYTE $00 zp80Backup: .BYTE $00
zp81Backup: .BYTE $00 zp81Backup: .BYTE $00
zp82Backup: .BYTE $00 zp82Backup: .BYTE $00
irq1Backup: .BYTE $00
irq2Backup: .BYTE $00
.endproc .endproc

View File

@ -185,6 +185,7 @@ static uint8_t gSpeakIncredible[] = {
static bool gSoundEnabled = false; static bool gSoundEnabled = false;
static bool gMockingBoardInitialized = false;
static bool gMockingBoardEnabled = false; static bool gMockingBoardEnabled = false;
static bool gMockingBoardSpeechEnabled = false; static bool gMockingBoardSpeechEnabled = false;
@ -194,35 +195,30 @@ static tMockingBoardSpeaker gMockingBoardSoundSpeaker = SPEAKER_BOTH;
// Implementation // Implementation
void soundInit(tSlot mockingBoardSlot, bool enableSpeechChip) void soundInit(bool enableSounds, bool enableMockingBoard, bool enableSpeechChip)
{ {
gSoundEnabled = true; gMockingBoardInitialized = mockingBoardInit();
if (mockingBoardSlot > 0) { gSoundEnabled = enableSounds;
mockingBoardInit(mockingBoardSlot, enableSpeechChip);
gMockingBoardEnabled = true; gMockingBoardEnabled = ((gSoundEnabled) && (gMockingBoardInitialized) && (enableMockingBoard));
gMockingBoardSpeechEnabled = enableSpeechChip; gMockingBoardSpeechEnabled = ((enableSpeechChip) && (gMockingBoardEnabled) && (mockingBoardHasSpeechChip()));
// When the speech chip is on, sound effects go out the right speaker
// only and the left speaker is used for speech. If the speech chip is // When the speech chip is on, sound effects go out the right speaker
// off, then sound effects go to both speakers. // only and the left speaker is used for speech. If the speech chip is
if (enableSpeechChip) { // off, then sound effects go to both speakers.
gMockingBoardSoundSpeaker = SPEAKER_RIGHT; if (gMockingBoardSpeechEnabled) {
} else { gMockingBoardSoundSpeaker = SPEAKER_RIGHT;
gMockingBoardSoundSpeaker = SPEAKER_BOTH;
}
} else { } else {
if (gMockingBoardEnabled) { gMockingBoardSoundSpeaker = SPEAKER_BOTH;
mockingBoardShutdown();
}
gMockingBoardEnabled = false;
gMockingBoardSpeechEnabled = false;
} }
} }
void soundShutdown(void) void soundShutdown(void)
{ {
if (gMockingBoardEnabled) { if (gMockingBoardInitialized) {
mockingBoardShutdown(); mockingBoardShutdown();
gMockingBoardInitialized = false;
gMockingBoardEnabled = false; gMockingBoardEnabled = false;
gMockingBoardSpeechEnabled = false; gMockingBoardSpeechEnabled = false;
} }
@ -367,6 +363,7 @@ void speakNoMoreMoves(void)
mockingBoardSpeak(gSpeakNoMoreMoves, sizeof(gSpeakNoMoreMoves)); mockingBoardSpeak(gSpeakNoMoreMoves, sizeof(gSpeakNoMoreMoves));
} }
bool speakGood(void) bool speakGood(void)
{ {
if (!gMockingBoardSpeechEnabled) if (!gMockingBoardSpeechEnabled)
@ -392,6 +389,7 @@ bool speakExcellent(void)
return true; return true;
} }
bool speakIncredible(void) bool speakIncredible(void)
{ {
if (!gMockingBoardSpeechEnabled) if (!gMockingBoardSpeechEnabled)

View File

@ -16,7 +16,7 @@
#include "mockingboard.h" #include "mockingboard.h"
extern void soundInit(tSlot mockingBoardSlot, bool enableSpeechChip); extern void soundInit(bool enableSounds, bool enableMockingBoard, bool enableSpeechChip);
extern void soundShutdown(void); extern void soundShutdown(void);
extern void beginClearGemSound(void); extern void beginClearGemSound(void);

View File

@ -26,24 +26,20 @@
// Defines // Defines
#define SAVE_OPTIONS_FILE "A2BEJWLD.OPTS" #define SAVE_OPTIONS_FILE "A2BEJWLD.OPTS"
#define BASE_VERSION "v2.3" #define VERSION "v2.4.a3"
#ifdef TOTAL_REPLAY_BUILD
#define VERSION BASE_VERSION ".tr"
#else
#define VERSION BASE_VERSION
#endif
#define OPTIONS_VERSION_UNSAVED 0
#define OPTIONS_VERSION 2
// Typedefs // Typedefs
typedef struct tGameOptions { typedef struct tGameOptions {
bool optionsSaved; uint8_t optionsVersion;
bool enableJoystick; bool enableJoystick;
bool enableMouse; bool enableMouse;
bool enableSound; bool enableSound;
tSlot mockingBoardSlot; bool enableMockingboard;
bool enableSpeechChip; bool enableMockingboardSpeech;
} tGameOptions; } tGameOptions;
@ -107,12 +103,12 @@ static tMouseCallbacks gMouseCallbacks = {
static bool gShouldSave = false; static bool gShouldSave = false;
static tGameOptions gGameOptions = { static tGameOptions gGameOptions = {
false, // optionsSaved OPTIONS_VERSION_UNSAVED, // optionsVersion
false, // enableJoystick false, // enableJoystick
true, // enableMouse true, // enableMouse
true, // enableSound true, // enableSound
0, // mockingBoardSlot true, // enableMockingboard
false // enableSpeechChip true // enableMockingboardSpeech
}; };
@ -161,7 +157,7 @@ static void saveOptions(void)
FILE *optionsFile = fopen(SAVE_OPTIONS_FILE, "wb"); FILE *optionsFile = fopen(SAVE_OPTIONS_FILE, "wb");
if (optionsFile != NULL) { if (optionsFile != NULL) {
gGameOptions.optionsSaved = true; gGameOptions.optionsVersion = OPTIONS_VERSION;
fwrite(&gGameOptions, sizeof(gGameOptions), 1, optionsFile); fwrite(&gGameOptions, sizeof(gGameOptions), 1, optionsFile);
fclose(optionsFile); fclose(optionsFile);
} }
@ -183,6 +179,17 @@ static bool loadOptions(void)
fclose(optionsFile); fclose(optionsFile);
// If we are upgrading from v1 of the options file, then:
// - There used to be a tSlot of the mockingboard where we now have the enableMockingboard boolean.
// Overwrite it with true, forcing mockingboard sound to be on if one is detected.
// - There used to be a boolean to enable/disable the speech chip on the mockingboard. It was only
// true if the user enabled it. Now that we can detect the speech chip, the value is default true
// and the user can disable speech if they want.
if (gGameOptions < OPTIONS_VERSION) {
gGameOptions.enableMockingboard = true;
gGameOptions.enableMockingboardSpeech = true;
}
return true; return true;
} }
@ -196,19 +203,17 @@ static void applyNewOptions(tGameOptions *newOptions)
return; return;
} }
printString("\n\n\n Saving options...");
if ((gGameOptions.enableSound != newOptions->enableSound) || if ((gGameOptions.enableSound != newOptions->enableSound) ||
(gGameOptions.mockingBoardSlot != newOptions->mockingBoardSlot) || (gGameOptions.enableMockingboard != newOptions->enableMockingboard) ||
(gGameOptions.enableSpeechChip != gGameOptions.enableSpeechChip)) { (gGameOptions.enableMockingboardSpeech != newOptions->enableMockingboardSpeech)) {
// If the sound parameters have changed, then re-init or shutdown sounds // If the sound parameters have changed, then re-init sounds
if (newOptions->enableSound) { soundInit(newOptions->enableSound, newOptions->enableMockingboard, newOptions->enableMockingboardSpeech);
soundInit(newOptions->mockingBoardSlot, newOptions->enableSpeechChip);
} else {
soundShutdown();
}
} }
memcpy(&gGameOptions, newOptions, sizeof(gGameOptions)); memcpy(&gGameOptions, newOptions, sizeof(gGameOptions));
gGameOptions.optionsSaved = false; gGameOptions.optionsVersion = OPTIONS_VERSION_UNSAVED;
if (oldEnableMouse != gGameOptions.enableMouse) { if (oldEnableMouse != gGameOptions.enableMouse) {
if (gGameOptions.enableMouse) { if (gGameOptions.enableMouse) {
gGameOptions.enableMouse = initMouse(&gMouseCallbacks); gGameOptions.enableMouse = initMouse(&gMouseCallbacks);
@ -231,67 +236,62 @@ static void replaceCursor(char ch)
} }
static void getSoundOptions(tGameOptions *newOptions) static bool yorn(void)
{ {
char ch; char ch;
bool result = true;
showCursor();
while (true) {
ch = cgetc();
if ((ch == 'N') ||
(ch == 'n')) {
result = false;
break;
}
if ((ch == 'Y') ||
(ch == 'y'))
break;
badThingHappened();
}
replaceCursor(ch);
return result;
}
static void getSoundOptions(tGameOptions *newOptions)
{
tSlot slot;
printString("\n\nEnable sounds? (Y/N) "); printString("\n\nEnable sounds? (Y/N) ");
showCursor(); newOptions->enableSound = yorn();
while (true) { if (!newOptions->enableSound)
ch = cgetc(); return;
if ((ch == 'N') ||
(ch == 'n')) {
newOptions->enableSound = false;
newOptions->mockingBoardSlot = 0;
newOptions->enableSpeechChip = false;
return;
}
if ((ch == 'Y') ||
(ch == 'y')) {
replaceCursor(ch);
newOptions->enableSound = true;
break;
}
badThingHappened();
}
printString("\nMockingBoard slot number (0 for none) "); // If no mockingboard present, don't bother to ask whether to enable/disable it.
showCursor(); slot = mockingBoardSlot();
while (true) { if (slot == 0)
ch = cgetc(); return;
if (ch == '0') {
newOptions->mockingBoardSlot = 0;
newOptions->enableSpeechChip = false;
return;
}
if ((ch >= '1') &&
(ch <= '7')) {
replaceCursor(ch);
newOptions->mockingBoardSlot = (ch - '0');
break;
}
badThingHappened();
}
printString("\nMockingBoard has a speech chip? (Y/N) "); printString("\nEnable MockingBoard sound found in slot ");
showCursor(); printInteger(slot);
while (true) { printString("? (Y/N) ");
ch = cgetc(); newOptions->enableMockingboard = yorn();
if ((ch == 'N') || if (!newOptions->enableMockingboard)
(ch == 'n')) { return;
newOptions->enableSpeechChip = false;
break; // If the mockingboard does not have a speech chip, do not prompt whether to
} // enable/disable it.
if ((ch == 'Y') || if (!mockingBoardHasSpeechChip())
(ch == 'y')) { return;
newOptions->enableSpeechChip = true;
break; printString("\nEnable speech on the Mockingboard? (Y/N) ");
} newOptions->enableMockingboardSpeech = yorn();
badThingHappened();
}
} }
@ -314,29 +314,35 @@ static void selectOptions(void)
" Options\n" " Options\n"
"\n" "\n"
" J - Joystick control - "); " J - Joystick control - ");
printString(newOptions.enableJoystick ? "Enable\n" : "Disabled\n"); printString(newOptions.enableJoystick ? "Enabled\n" : "Disabled\n");
printString( printString(
" M - Mouse control - "); " M - Mouse control - ");
printString(newOptions.enableMouse ? "Enable\n" : "Disabled\n"); printString(newOptions.enableMouse ? "Enabled\n" : "Disabled\n");
printString( printString(
" S - Sound - "); " S - Sound - ");
printString(newOptions.enableSound ? "Enable\n" : "Disabled\n"); printString(newOptions.enableSound ? "Enabled\n" : "Disabled\n");
if (newOptions.enableSound) { if (newOptions.enableSound) {
if (newOptions.mockingBoardSlot > 0) { tSlot slot = mockingBoardSlot();
if (slot != 0) {
printString( printString(
// 0000000001111111111222222222233333333334444444444555555555566666666667 // 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890 // 1234567890123456789012345678901234567890123456789012345678901234567890
" MockingBoard - Slot "); " MockingBoard - ");
printInteger(newOptions.mockingBoardSlot); printString(newOptions.enableMockingboard ? "Enabled (Slot " : "Disabled (Slot ");
printString("\n" printInteger(slot);
" Speech Chip - "); printString(")\n");
printString(newOptions.enableSpeechChip ? "Enable\n" : "Disable\n");
} else { if ((newOptions.enableMockingboard) &&
printString( (mockingBoardHasSpeechChip()))
// 0000000001111111111222222222233333333334444444444555555555566666666667 {
// 1234567890123456789012345678901234567890123456789012345678901234567890 printString(
" MockingBoard - Disabled\n"); // 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890
" Speech - ");
printString(newOptions.enableMockingboardSpeech ? "Enabled\n" : "Disabled\n");
}
} }
} }
printString( printString(
@ -716,6 +722,8 @@ void initUI(void)
optionsLoaded = loadOptions(); optionsLoaded = loadOptions();
soundInit(gGameOptions.enableSound, gGameOptions.enableMockingboard, gGameOptions.enableMockingboardSpeech);
initGameEngine(&gCallbacks); initGameEngine(&gCallbacks);
mouseInitialized = initMouse(&gMouseCallbacks); mouseInitialized = initMouse(&gMouseCallbacks);
@ -723,19 +731,12 @@ void initUI(void)
if ((!mouseInitialized) && if ((!mouseInitialized) &&
(gGameOptions.enableMouse)) { (gGameOptions.enableMouse)) {
gGameOptions.enableMouse = false; gGameOptions.enableMouse = false;
gGameOptions.optionsSaved = false; gGameOptions.optionsVersion = OPTIONS_VERSION_UNSAVED;
} }
initJoystick(&gJoyCallbacks); initJoystick(&gJoyCallbacks);
if (gGameOptions.enableSound) { if (gGameOptions.optionsVersion == OPTIONS_VERSION_UNSAVED) {
if (!optionsLoaded) {
gGameOptions.mockingBoardSlot = getMockingBoardSlot();
}
soundInit(gGameOptions.mockingBoardSlot, gGameOptions.enableSpeechChip);
}
if (!gGameOptions.optionsSaved) {
saveOptions(); saveOptions();
} }
} }
@ -957,33 +958,14 @@ void playGame(void)
printString("\n\nChecking for a saved game..."); printString("\n\nChecking for a saved game...");
if (loadGame()) { if (loadGame()) {
bool gotAnswer = false; bool loadSavedGame = false;
printString("\n\nYou have a saved game!\n Would you like to continue it (Y/N) "); printString("\n\nYou have a saved game!\n Would you like to continue it (Y/N) ");
loadSavedGame = yorn();
showCursor(); if (loadSavedGame) {
while (!gotAnswer) { printString("\n\nLoading your saved puzzle");
ch = cgetc(); gShouldSave = true;
switch (ch) { gameLoaded = true;
case 'y':
case 'Y':
replaceCursor(ch);
printString("\n\nLoading your saved puzzle");
gotAnswer = true;
gShouldSave = true;
gameLoaded = true;
break;
case 'n':
case 'N':
replaceCursor(ch);
gotAnswer = true;
break;
default:
badThingHappened();
break;
}
} }
} }