From 20ad7dda1c4e50872615d4b0d816ad456fc717b3 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Wed, 4 Mar 2020 22:23:09 -0500 Subject: [PATCH] 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. --- .../UserInterfaceState.xcuserstate | Bin 61170 -> 64933 bytes a2bejwld/Makefile | 1 - a2bejwld/main.c | 12 - a2bejwld/mockingboard.c | 48 +++- a2bejwld/mockingboard.h | 6 +- a2bejwld/mockingboard_speech.h | 1 + a2bejwld/mockingboard_speech.s | 159 ++++++++++-- a2bejwld/sound.c | 38 ++- a2bejwld/sound.h | 2 +- a2bejwld/ui.c | 240 ++++++++---------- 10 files changed, 315 insertions(+), 192 deletions(-) diff --git a/a2bejwld.xcodeproj/project.xcworkspace/xcuserdata/jrand.xcuserdatad/UserInterfaceState.xcuserstate b/a2bejwld.xcodeproj/project.xcworkspace/xcuserdata/jrand.xcuserdatad/UserInterfaceState.xcuserstate index 1e69ad386b2c3e49317a42acc8c28ffb2977d0f1..42af319ba4923590fd3e597ee4712e5ae8d6c04d 100644 GIT binary patch delta 29300 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�sp>&C~T)I&TlftF7Qj`=c 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 + 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: lda zp80Backup sta $80 @@ -112,25 +203,53 @@ readChip: sta $81 lda zp82Backup sta $82 + lda irq1Backup + sta $3fe + lda irq2Backup + sta $3ff txa - and #$07 ldx #$00 + plp rts -timercheck: - lda ($80),y ; read 6522 timer low byte - sta $82 - lda ($80),y ; second time +@timercheck: sec - sbc $82 - cmp #$F8 ; looking for (-)8 cycles between reads + lda ($80),y ; read 6522 timer low byte + sbc ($80),y ; second time + cmp #5 ; looking for (-)8 cycles between reads beq :+ - cmp #$F7 ; FastChip //e clock is different + cmp #6 ; FastChip //e clock is different : 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 zp80Backup: .BYTE $00 zp81Backup: .BYTE $00 zp82Backup: .BYTE $00 +irq1Backup: .BYTE $00 +irq2Backup: .BYTE $00 .endproc diff --git a/a2bejwld/sound.c b/a2bejwld/sound.c index 52f5066..414944d 100644 --- a/a2bejwld/sound.c +++ b/a2bejwld/sound.c @@ -185,6 +185,7 @@ static uint8_t gSpeakIncredible[] = { static bool gSoundEnabled = false; +static bool gMockingBoardInitialized = false; static bool gMockingBoardEnabled = false; static bool gMockingBoardSpeechEnabled = false; @@ -194,35 +195,30 @@ static tMockingBoardSpeaker gMockingBoardSoundSpeaker = SPEAKER_BOTH; // Implementation -void soundInit(tSlot mockingBoardSlot, bool enableSpeechChip) +void soundInit(bool enableSounds, bool enableMockingBoard, bool enableSpeechChip) { - gSoundEnabled = true; - if (mockingBoardSlot > 0) { - mockingBoardInit(mockingBoardSlot, enableSpeechChip); - gMockingBoardEnabled = true; - gMockingBoardSpeechEnabled = enableSpeechChip; - // 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 - // off, then sound effects go to both speakers. - if (enableSpeechChip) { - gMockingBoardSoundSpeaker = SPEAKER_RIGHT; - } else { - gMockingBoardSoundSpeaker = SPEAKER_BOTH; - } + gMockingBoardInitialized = mockingBoardInit(); + gSoundEnabled = enableSounds; + + gMockingBoardEnabled = ((gSoundEnabled) && (gMockingBoardInitialized) && (enableMockingBoard)); + 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 + // off, then sound effects go to both speakers. + if (gMockingBoardSpeechEnabled) { + gMockingBoardSoundSpeaker = SPEAKER_RIGHT; } else { - if (gMockingBoardEnabled) { - mockingBoardShutdown(); - } - gMockingBoardEnabled = false; - gMockingBoardSpeechEnabled = false; + gMockingBoardSoundSpeaker = SPEAKER_BOTH; } } void soundShutdown(void) { - if (gMockingBoardEnabled) { + if (gMockingBoardInitialized) { mockingBoardShutdown(); + gMockingBoardInitialized = false; gMockingBoardEnabled = false; gMockingBoardSpeechEnabled = false; } @@ -367,6 +363,7 @@ void speakNoMoreMoves(void) mockingBoardSpeak(gSpeakNoMoreMoves, sizeof(gSpeakNoMoreMoves)); } + bool speakGood(void) { if (!gMockingBoardSpeechEnabled) @@ -392,6 +389,7 @@ bool speakExcellent(void) return true; } + bool speakIncredible(void) { if (!gMockingBoardSpeechEnabled) diff --git a/a2bejwld/sound.h b/a2bejwld/sound.h index 475bcc6..6ab2db2 100644 --- a/a2bejwld/sound.h +++ b/a2bejwld/sound.h @@ -16,7 +16,7 @@ #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 beginClearGemSound(void); diff --git a/a2bejwld/ui.c b/a2bejwld/ui.c index 1734a5e..5429f25 100644 --- a/a2bejwld/ui.c +++ b/a2bejwld/ui.c @@ -26,24 +26,20 @@ // Defines #define SAVE_OPTIONS_FILE "A2BEJWLD.OPTS" -#define BASE_VERSION "v2.3" - -#ifdef TOTAL_REPLAY_BUILD -#define VERSION BASE_VERSION ".tr" -#else -#define VERSION BASE_VERSION -#endif +#define VERSION "v2.4.a3" +#define OPTIONS_VERSION_UNSAVED 0 +#define OPTIONS_VERSION 2 // Typedefs typedef struct tGameOptions { - bool optionsSaved; + uint8_t optionsVersion; bool enableJoystick; bool enableMouse; bool enableSound; - tSlot mockingBoardSlot; - bool enableSpeechChip; + bool enableMockingboard; + bool enableMockingboardSpeech; } tGameOptions; @@ -107,12 +103,12 @@ static tMouseCallbacks gMouseCallbacks = { static bool gShouldSave = false; static tGameOptions gGameOptions = { - false, // optionsSaved - false, // enableJoystick - true, // enableMouse - true, // enableSound - 0, // mockingBoardSlot - false // enableSpeechChip + OPTIONS_VERSION_UNSAVED, // optionsVersion + false, // enableJoystick + true, // enableMouse + true, // enableSound + true, // enableMockingboard + true // enableMockingboardSpeech }; @@ -161,7 +157,7 @@ static void saveOptions(void) FILE *optionsFile = fopen(SAVE_OPTIONS_FILE, "wb"); if (optionsFile != NULL) { - gGameOptions.optionsSaved = true; + gGameOptions.optionsVersion = OPTIONS_VERSION; fwrite(&gGameOptions, sizeof(gGameOptions), 1, optionsFile); fclose(optionsFile); } @@ -183,6 +179,17 @@ static bool loadOptions(void) 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; } @@ -196,19 +203,17 @@ static void applyNewOptions(tGameOptions *newOptions) return; } + printString("\n\n\n Saving options..."); + if ((gGameOptions.enableSound != newOptions->enableSound) || - (gGameOptions.mockingBoardSlot != newOptions->mockingBoardSlot) || - (gGameOptions.enableSpeechChip != gGameOptions.enableSpeechChip)) { - // If the sound parameters have changed, then re-init or shutdown sounds - if (newOptions->enableSound) { - soundInit(newOptions->mockingBoardSlot, newOptions->enableSpeechChip); - } else { - soundShutdown(); - } + (gGameOptions.enableMockingboard != newOptions->enableMockingboard) || + (gGameOptions.enableMockingboardSpeech != newOptions->enableMockingboardSpeech)) { + // If the sound parameters have changed, then re-init sounds + soundInit(newOptions->enableSound, newOptions->enableMockingboard, newOptions->enableMockingboardSpeech); } memcpy(&gGameOptions, newOptions, sizeof(gGameOptions)); - gGameOptions.optionsSaved = false; + gGameOptions.optionsVersion = OPTIONS_VERSION_UNSAVED; if (oldEnableMouse != gGameOptions.enableMouse) { if (gGameOptions.enableMouse) { gGameOptions.enableMouse = initMouse(&gMouseCallbacks); @@ -231,67 +236,62 @@ static void replaceCursor(char ch) } -static void getSoundOptions(tGameOptions *newOptions) +static bool yorn(void) { 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) "); - showCursor(); - while (true) { - ch = cgetc(); - 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(); - } + newOptions->enableSound = yorn(); + if (!newOptions->enableSound) + return; - printString("\nMockingBoard slot number (0 for none) "); - showCursor(); - while (true) { - ch = cgetc(); - if (ch == '0') { - newOptions->mockingBoardSlot = 0; - newOptions->enableSpeechChip = false; - return; - } - if ((ch >= '1') && - (ch <= '7')) { - replaceCursor(ch); - newOptions->mockingBoardSlot = (ch - '0'); - break; - } - - badThingHappened(); - } + // If no mockingboard present, don't bother to ask whether to enable/disable it. + slot = mockingBoardSlot(); + if (slot == 0) + return; - printString("\nMockingBoard has a speech chip? (Y/N) "); - showCursor(); - while (true) { - ch = cgetc(); - if ((ch == 'N') || - (ch == 'n')) { - newOptions->enableSpeechChip = false; - break; - } - if ((ch == 'Y') || - (ch == 'y')) { - newOptions->enableSpeechChip = true; - break; - } - - badThingHappened(); - } + printString("\nEnable MockingBoard sound found in slot "); + printInteger(slot); + printString("? (Y/N) "); + newOptions->enableMockingboard = yorn(); + if (!newOptions->enableMockingboard) + return; + + // If the mockingboard does not have a speech chip, do not prompt whether to + // enable/disable it. + if (!mockingBoardHasSpeechChip()) + return; + + printString("\nEnable speech on the Mockingboard? (Y/N) "); + newOptions->enableMockingboardSpeech = yorn(); } @@ -314,29 +314,35 @@ static void selectOptions(void) " Options\n" "\n" " J - Joystick control - "); - printString(newOptions.enableJoystick ? "Enable\n" : "Disabled\n"); + printString(newOptions.enableJoystick ? "Enabled\n" : "Disabled\n"); printString( " M - Mouse control - "); - printString(newOptions.enableMouse ? "Enable\n" : "Disabled\n"); + printString(newOptions.enableMouse ? "Enabled\n" : "Disabled\n"); printString( " S - Sound - "); - printString(newOptions.enableSound ? "Enable\n" : "Disabled\n"); + printString(newOptions.enableSound ? "Enabled\n" : "Disabled\n"); if (newOptions.enableSound) { - if (newOptions.mockingBoardSlot > 0) { + tSlot slot = mockingBoardSlot(); + + if (slot != 0) { printString( // 0000000001111111111222222222233333333334444444444555555555566666666667 // 1234567890123456789012345678901234567890123456789012345678901234567890 - " MockingBoard - Slot "); - printInteger(newOptions.mockingBoardSlot); - printString("\n" - " Speech Chip - "); - printString(newOptions.enableSpeechChip ? "Enable\n" : "Disable\n"); - } else { - printString( - // 0000000001111111111222222222233333333334444444444555555555566666666667 - // 1234567890123456789012345678901234567890123456789012345678901234567890 - " MockingBoard - Disabled\n"); + " MockingBoard - "); + printString(newOptions.enableMockingboard ? "Enabled (Slot " : "Disabled (Slot "); + printInteger(slot); + printString(")\n"); + + if ((newOptions.enableMockingboard) && + (mockingBoardHasSpeechChip())) + { + printString( + // 0000000001111111111222222222233333333334444444444555555555566666666667 + // 1234567890123456789012345678901234567890123456789012345678901234567890 + " Speech - "); + printString(newOptions.enableMockingboardSpeech ? "Enabled\n" : "Disabled\n"); + } } } printString( @@ -716,6 +722,8 @@ void initUI(void) optionsLoaded = loadOptions(); + soundInit(gGameOptions.enableSound, gGameOptions.enableMockingboard, gGameOptions.enableMockingboardSpeech); + initGameEngine(&gCallbacks); mouseInitialized = initMouse(&gMouseCallbacks); @@ -723,19 +731,12 @@ void initUI(void) if ((!mouseInitialized) && (gGameOptions.enableMouse)) { gGameOptions.enableMouse = false; - gGameOptions.optionsSaved = false; + gGameOptions.optionsVersion = OPTIONS_VERSION_UNSAVED; } initJoystick(&gJoyCallbacks); - if (gGameOptions.enableSound) { - if (!optionsLoaded) { - gGameOptions.mockingBoardSlot = getMockingBoardSlot(); - } - soundInit(gGameOptions.mockingBoardSlot, gGameOptions.enableSpeechChip); - } - - if (!gGameOptions.optionsSaved) { + if (gGameOptions.optionsVersion == OPTIONS_VERSION_UNSAVED) { saveOptions(); } } @@ -957,33 +958,14 @@ void playGame(void) printString("\n\nChecking for a saved game..."); if (loadGame()) { - bool gotAnswer = false; + bool loadSavedGame = false; printString("\n\nYou have a saved game!\n Would you like to continue it (Y/N) "); - - showCursor(); - while (!gotAnswer) { - ch = cgetc(); - switch (ch) { - 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; - } + loadSavedGame = yorn(); + if (loadSavedGame) { + printString("\n\nLoading your saved puzzle"); + gShouldSave = true; + gameLoaded = true; } }