diff options
Diffstat (limited to 'engines/kyra')
29 files changed, 745 insertions, 602 deletions
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index dfc2a9f868..35b4d8ba7f 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -32,9 +32,10 @@ namespace Kyra { Debugger::Debugger(KyraEngine_v1 *vm) - : ::GUI::Debugger() { - _vm = vm; + : ::GUI::Debugger(), _vm(vm) { +} +void Debugger::initialize() { DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); DCmd_Register("screen_debug_mode", WRAP_METHOD(Debugger, cmd_setScreenDebug)); DCmd_Register("load_palette", WRAP_METHOD(Debugger, cmd_loadPalette)); @@ -196,6 +197,9 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) { Debugger_LoK::Debugger_LoK(KyraEngine_LoK *vm) : Debugger(vm), _vm(vm) { +} + +void Debugger_LoK::initialize() { DCmd_Register("enter", WRAP_METHOD(Debugger_LoK, cmd_enterRoom)); DCmd_Register("scenes", WRAP_METHOD(Debugger_LoK, cmd_listScenes)); DCmd_Register("give", WRAP_METHOD(Debugger_LoK, cmd_giveItem)); @@ -281,6 +285,9 @@ bool Debugger_LoK::cmd_listBirthstones(int argc, const char **argv) { #pragma mark - Debugger_v2::Debugger_v2(KyraEngine_v2 *vm) : Debugger(vm), _vm(vm) { +} + +void Debugger_v2::initialize() { DCmd_Register("character_info", WRAP_METHOD(Debugger_v2, cmd_characterInfo)); DCmd_Register("enter", WRAP_METHOD(Debugger_v2, cmd_enterScene)); DCmd_Register("scenes", WRAP_METHOD(Debugger_v2, cmd_listScenes)); @@ -433,6 +440,9 @@ bool Debugger_v2::cmd_giveItem(int argc, const char **argv) { #pragma mark - Debugger_HoF::Debugger_HoF(KyraEngine_HoF *vm) : Debugger_v2(vm), _vm(vm) { +} + +void Debugger_HoF::initialize() { DCmd_Register("pass_codes", WRAP_METHOD(Debugger_HoF, cmd_passcodes)); } diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h index 09ddd89a7a..e9c0a6a98a 100644 --- a/engines/kyra/debugger.h +++ b/engines/kyra/debugger.h @@ -37,6 +37,8 @@ public: Debugger(KyraEngine_v1 *vm); virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + virtual void initialize(); + protected: KyraEngine_v1 *_vm; @@ -56,6 +58,7 @@ public: Debugger_LoK(KyraEngine_LoK *vm); virtual ~Debugger_LoK() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + virtual void initialize(); protected: KyraEngine_LoK *_vm; @@ -70,6 +73,7 @@ public: Debugger_v2(KyraEngine_v2 *vm); virtual ~Debugger_v2() {} + virtual void initialize(); protected: KyraEngine_v2 *_vm; @@ -85,6 +89,7 @@ class Debugger_HoF : public Debugger_v2 { public: Debugger_HoF(KyraEngine_HoF *vm); + virtual void initialize(); protected: KyraEngine_HoF *_vm; diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h index c224c8f46d..ebf7c8eee7 100644 --- a/engines/kyra/detection_tables.h +++ b/engines/kyra/detection_tables.h @@ -67,7 +67,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_CMP_FLAGS }, @@ -80,7 +80,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_CMP_FLAGS }, @@ -94,7 +94,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -107,7 +107,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -119,7 +119,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -131,7 +131,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -143,7 +143,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -155,7 +155,7 @@ const KYRAGameDescription adGameDescs[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_OLDFLOPPY_FLAGS }, @@ -167,7 +167,7 @@ const KYRAGameDescription adGameDescs[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -179,7 +179,7 @@ const KYRAGameDescription adGameDescs[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -191,7 +191,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_FLOPPY_FLAGS }, @@ -208,7 +208,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformAmiga, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIAMIGA + GUIO2(GUIO_NOSPEECH, GUIO_MIDIAMIGA) }, KYRA1_AMIGA_FLAGS }, @@ -225,7 +225,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformAmiga, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIAMIGA + GUIO2(GUIO_NOSPEECH, GUIO_MIDIAMIGA) }, KYRA1_AMIGA_FLAGS }, @@ -242,7 +242,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIGM + GUIO2(GUIO_NOSPEECH, GUIO_MIDIGM) }, KYRA1_FLOPPY_FLAGS }, @@ -259,7 +259,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformFMTowns, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDITOWNS + GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS) }, KYRA1_TOWNS_FLAGS }, @@ -275,7 +275,7 @@ const KYRAGameDescription adGameDescs[] = { Common::JA_JPN, Common::kPlatformFMTowns, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDITOWNS + GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS) }, KYRA1_TOWNS_SJIS_FLAGS }, @@ -294,7 +294,7 @@ const KYRAGameDescription adGameDescs[] = { Common::JA_JPN, Common::kPlatformPC98, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIPC98 + GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98) }, KYRA1_TOWNS_SJIS_FLAGS }, @@ -307,7 +307,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_CD_FLAGS }, @@ -319,7 +319,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_CD_FLAGS }, @@ -331,7 +331,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_CD_FLAGS }, @@ -344,7 +344,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_CD_FLAGS }, @@ -361,7 +361,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_CD, - Common::GUIO_NONE + GUIO0() }, KYRA1_CD_FLAGS }, @@ -377,7 +377,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformMacintosh, ADGF_CD, - Common::GUIO_NONE + GUIO0() }, KYRA1_CD_FLAGS }, @@ -393,7 +393,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformMacintosh, ADGF_CD, - Common::GUIO_NONE + GUIO0() }, KYRA1_CD_FLAGS }, @@ -406,7 +406,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_DEMO_FLAGS }, @@ -419,7 +419,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIPCSPK + GUIO3(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIPCSPK) }, KYRA1_DEMO_CD_FLAGS }, @@ -432,7 +432,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_CMP_FLAGS }, @@ -445,7 +445,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_CMP_FLAGS }, @@ -458,7 +458,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_FLAGS }, @@ -471,7 +471,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_FLAGS }, @@ -484,7 +484,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_FLAGS }, @@ -497,7 +497,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_FLAGS }, @@ -510,7 +510,7 @@ const KYRAGameDescription adGameDescs[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY) }, @@ -523,7 +523,7 @@ const KYRAGameDescription adGameDescs[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY) }, @@ -536,7 +536,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FLAGS }, @@ -548,7 +548,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FLAGS }, @@ -560,7 +560,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FLAGS }, @@ -574,7 +574,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -586,7 +586,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -598,7 +598,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -611,7 +611,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -624,7 +624,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -637,7 +637,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -650,7 +650,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD | ADGF_DEMO, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_DEMO_FLAGS }, @@ -663,7 +663,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD | ADGF_DEMO, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_DEMO_FLAGS }, @@ -676,7 +676,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD | ADGF_DEMO, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_CD_DEMO_FLAGS }, @@ -689,7 +689,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, KYRA2_DEMO_FLAGS }, @@ -702,7 +702,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformFMTowns, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDITOWNS + GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS) }, KYRA2_TOWNS_FLAGS }, @@ -714,7 +714,7 @@ const KYRAGameDescription adGameDescs[] = { Common::JA_JPN, Common::kPlatformFMTowns, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDITOWNS + GUIO2(GUIO_NOSPEECH, GUIO_MIDITOWNS) }, KYRA2_TOWNS_SJIS_FLAGS }, @@ -726,7 +726,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC98, ADGF_CD, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIPC98 + GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98) }, KYRA2_TOWNS_FLAGS }, @@ -738,7 +738,7 @@ const KYRAGameDescription adGameDescs[] = { Common::JA_JPN, Common::kPlatformPC98, ADGF_CD, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIPC98 + GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98) }, KYRA2_TOWNS_SJIS_FLAGS }, @@ -758,7 +758,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FLAGS }, @@ -774,7 +774,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FLAGS }, @@ -790,7 +790,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FLAGS }, @@ -808,7 +808,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_INS_FLAGS }, @@ -824,7 +824,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_INS_FLAGS }, @@ -840,7 +840,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_INS_FLAGS }, @@ -858,7 +858,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_INS_FLAGS }, @@ -874,7 +874,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformMacintosh, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_INS_FLAGS }, @@ -890,7 +890,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformMacintosh, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_INS_FLAGS }, @@ -908,7 +908,7 @@ const KYRAGameDescription adGameDescs[] = { Common::ES_ESP, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY) }, @@ -924,7 +924,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY) }, @@ -940,7 +940,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY) }, @@ -958,7 +958,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA) }, @@ -974,7 +974,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA) }, @@ -990,7 +990,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE, - Common::GUIO_NOMIDI + GUIO1(GUIO_NOMIDI) }, KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA) }, @@ -1009,7 +1009,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FLAGS }, @@ -1026,7 +1026,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FLAGS }, @@ -1043,7 +1043,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FLAGS }, @@ -1060,7 +1060,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FLAGS }, @@ -1077,7 +1077,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FLAGS }, @@ -1094,7 +1094,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FLAGS }, @@ -1112,7 +1112,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU) }, @@ -1130,7 +1130,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU) }, @@ -1147,7 +1147,7 @@ const KYRAGameDescription adGameDescs[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU) }, @@ -1165,7 +1165,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -1182,7 +1182,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -1199,7 +1199,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -1216,7 +1216,7 @@ const KYRAGameDescription adGameDescs[] = { Common::IT_ITA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -1233,7 +1233,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -1250,7 +1250,7 @@ const KYRAGameDescription adGameDescs[] = { Common::FR_FRA, Common::kPlatformPC, ADGF_DROPLANGUAGE | ADGF_CD, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, @@ -1266,7 +1266,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_CMP_FLAGS }, @@ -1282,7 +1282,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_CMP_FLAGS }, @@ -1298,7 +1298,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_CMP_FLAGS }, @@ -1315,7 +1315,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_FLAGS }, @@ -1332,7 +1332,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_FLAGS }, @@ -1349,7 +1349,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_FLAGS }, @@ -1366,7 +1366,7 @@ const KYRAGameDescription adGameDescs[] = { Common::DE_DEU, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_FLAGS }, @@ -1384,7 +1384,7 @@ const KYRAGameDescription adGameDescs[] = { Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO5(GUIO_NOSPEECH, GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_FLOPPY_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY) }, @@ -1401,7 +1401,7 @@ const KYRAGameDescription adGameDescs[] = { Common::JA_JPN, Common::kPlatformPC98, ADGF_NO_FLAGS, - Common::GUIO_NOSPEECH | Common::GUIO_MIDIPC98 + GUIO2(GUIO_NOSPEECH, GUIO_MIDIPC98) }, LOL_PC98_SJIS_FLAGS }, @@ -1418,7 +1418,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_DEMO_FLAGS }, @@ -1434,7 +1434,7 @@ const KYRAGameDescription adGameDescs[] = { Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, - Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK + GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK) }, LOL_KYRA2_DEMO_FLAGS }, diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index 7fd9880dce..27f09b645e 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -388,6 +388,10 @@ void GUI::updateSaveList(bool excludeQuickSaves) { if (_saveSlots.begin() == _saveSlots.end()) return; + sortSaveSlots(); +} + +void GUI::sortSaveSlots() { Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Less<int>()); if (_saveSlots.size() > 2) Common::sort(_saveSlots.begin()+1, _saveSlots.end(), Common::Greater<int>()); diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index 1efbdde394..6e9606f1de 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -200,10 +200,15 @@ protected: void redrawText(const Menu &menu); void redrawHighlight(const Menu &menu); + // The engine expects a list of contiguous savegame indices. + // Since ScummVM's savegame indices aren't, we re-index them. + // The integers stored in _saveSlots are ScummVM savegame indices. Common::Array<int> _saveSlots; void updateSaveList(bool excludeQuickSaves = false); int getNextSavegameSlot(); + virtual void sortSaveSlots(); + uint32 _lastScreenUpdate; Common::KeyState _keyPressed; void checkTextfieldInput(); diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index 3ab52b9940..5bef3cd5b5 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -184,7 +184,7 @@ void LoLEngine::gui_displayCharInventory(int charNum) { static const uint16 statusFlags[] = { 0x0080, 0x0000, 0x1000, 0x0002, 0x100, 0x0001, 0x0000, 0x0000 }; - memset(_charStatusFlags, 0xffff, sizeof(_charStatusFlags)); + memset(_charStatusFlags, 0xFF, sizeof(_charStatusFlags)); int x = 0; int32 c = 0; @@ -2572,11 +2572,11 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) { slotOffs = 1; } - int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W'); - + int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W'); + for (int i = startSlot; i < num && _savegameOffset + i - slotOffs < _savegameListSize; ++i) { - if (_savegameList[_saveSlots[i + _savegameOffset - slotOffs]]) { - Common::strlcpy(s, _savegameList[_saveSlots[i + _savegameOffset - slotOffs]], 80); + if (_savegameList[i + _savegameOffset - slotOffs]) { + Common::strlcpy(s, _savegameList[i + _savegameOffset - slotOffs], 80); // Trim long GMM save descriptions to fit our save slots int fC = _screen->getTextWidth(s); @@ -2618,15 +2618,13 @@ void GUI_LoL::updateSavegameList() { _savegameListSize = _saveSlots.size(); if (_savegameListSize) { - Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>()); - LoLEngine::SaveHeader header; Common::InSaveFile *in; _savegameList = new char *[_savegameListSize]; for (int i = 0; i < _savegameListSize; i++) { - in = _vm->openSaveForReading(_vm->getSavegameFilename(i), header); + in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i]), header); if (in) { _savegameList[i] = new char[header.description.size() + 1]; Common::strlcpy(_savegameList[i], header.description.c_str(), header.description.size() + 1); @@ -2634,15 +2632,18 @@ void GUI_LoL::updateSavegameList() { delete in; } else { _savegameList[i] = 0; - error("GUI_LoL::updateSavegameList(): Unexpected missing save file for slot: %d.", i); + warning("GUI_LoL::updateSavegameList(): Unexpected missing save file for slot: %d.", _saveSlots[i]); } } - } else { _savegameList = 0; } } +void GUI_LoL::sortSaveSlots() { + Common::sort(_saveSlots.begin(), _saveSlots.end(), Common::Greater<int>()); +} + void GUI_LoL::printMenuText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 flags) { _screen->fprintString("%s", x, y, c0, c1, _vm->gameFlags().use16ColorMode ? (flags & 3) : flags , str); } diff --git a/engines/kyra/gui_lol.h b/engines/kyra/gui_lol.h index 0686926534..af487402f6 100644 --- a/engines/kyra/gui_lol.h +++ b/engines/kyra/gui_lol.h @@ -175,6 +175,8 @@ private: char **_savegameList; int _savegameListSize; bool _savegameListUpdateNeeded; + + virtual void sortSaveSlots(); }; } // End of namespace Kyra diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp index 7e9ae439fc..0d6e99a696 100644 --- a/engines/kyra/items_lol.cpp +++ b/engines/kyra/items_lol.cpp @@ -127,14 +127,8 @@ Item LoLEngine::makeItem(int itemType, int curFrame, int flags) { continue; bool t = false; - Item ii = i; - while (ii && !t) { - t = testUnkItemFlags(ii); - if (t) - break; - else - ii = _itemsInPlay[ii - 1].nextAssignedObject; - } + for (Item ii = i; ii && !t; ii = _itemsInPlay[ii].nextAssignedObject) + t = isItemMoveable(ii); if (t) { cnt = diff; @@ -144,24 +138,20 @@ Item LoLEngine::makeItem(int itemType, int curFrame, int flags) { Item slot = i; if (cnt) { - slot = r; - if (testUnkItemFlags(r)) { + slot = 0; + if (isItemMoveable(r)) { if (_itemsInPlay[r].nextAssignedObject) _itemsInPlay[_itemsInPlay[r].nextAssignedObject].level = _itemsInPlay[r].level; deleteItem(r); slot = r; } else { - uint16 ii = _itemsInPlay[slot].nextAssignedObject; - while (ii) { - if (testUnkItemFlags(ii)) { - _itemsInPlay[slot].nextAssignedObject = _itemsInPlay[ii].nextAssignedObject; - deleteItem(ii); - slot = ii; - break; - } else { - slot = ii; - } - ii = _itemsInPlay[slot].nextAssignedObject; + for (uint16 ii = _itemsInPlay[r].nextAssignedObject; ii; ii = _itemsInPlay[ii].nextAssignedObject) { + if (!isItemMoveable(ii)) + continue; + _itemsInPlay[r].nextAssignedObject = _itemsInPlay[ii].nextAssignedObject; + deleteItem(ii); + slot = ii; + break; } } } @@ -219,7 +209,7 @@ bool LoLEngine::addItemToInventory(Item itemIndex) { return true; } -bool LoLEngine::testUnkItemFlags(Item itemIndex) { +bool LoLEngine::isItemMoveable(Item itemIndex) { if (!(_itemsInPlay[itemIndex].shpCurFrame_flg & 0x4000)) return false; @@ -304,7 +294,7 @@ bool LoLEngine::itemEquipped(int charNum, uint16 itemType) { return false; } -void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b) { +void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int moveable) { if (!flyingHeight) { x = (x & 0xffc0) | 0x40; y = (y & 0xffc0) | 0x40; @@ -316,7 +306,7 @@ void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, _itemsInPlay[item].block = block; _itemsInPlay[item].flyingHeight = flyingHeight; - if (b) + if (moveable) _itemsInPlay[item].shpCurFrame_flg |= 0x4000; else _itemsInPlay[item].shpCurFrame_flg &= 0xbfff; @@ -325,7 +315,7 @@ void LoLEngine::setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, assignItemToBlock(&_levelBlockProperties[block].assignedObjects, item); reassignDrawObjects(_currentDirection, item, &_levelBlockProperties[block], false); - if (b) + if (moveable) runLevelScriptCustom(block, 0x80, -1, item, 0, 0); checkSceneUpdateNeed(block); diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index 4497ab8019..34bde7fe5c 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -223,11 +223,12 @@ Common::Error KyraEngine_HoF::init() { assert(_screen); _screen->setResolution(); + _debugger = new Debugger_HoF(this); + assert(_debugger); + KyraEngine_v1::init(); initStaticResource(); - _debugger = new Debugger_HoF(this); - assert(_debugger); _text = new TextDisplayer_HoF(this, _screen); assert(_text); _gui = new GUI_HoF(this); @@ -455,6 +456,9 @@ void KyraEngine_HoF::startup() { } void KyraEngine_HoF::runLoop() { + // Initialize debugger since how it should be fully usable + _debugger->initialize(); + _screen->updateScreen(); _runFlag = true; @@ -1083,7 +1087,7 @@ void KyraEngine_HoF::loadNPCScript() { #pragma mark - void KyraEngine_HoF::resetScaleTable() { - Common::set_to(_scaleTable, ARRAYEND(_scaleTable), 0x100); + Common::fill(_scaleTable, ARRAYEND(_scaleTable), 0x100); } void KyraEngine_HoF::setScaleTableItem(int item, int data) { @@ -1473,7 +1477,7 @@ void KyraEngine_HoF::snd_playVoiceFile(int id) { char vocFile[9]; assert(id >= 0 && id <= 9999999); sprintf(vocFile, "%07d", id); - if (_sound->voiceFileIsPresent(vocFile)) { + if (_sound->isVoicePresent(vocFile)) { snd_stopVoice(); while (!_sound->voicePlay(vocFile, &_speechHandle)) { @@ -1673,7 +1677,7 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) { } void KyraEngine_HoF::clearCauldronTable() { - Common::set_to(_cauldronTable, ARRAYEND(_cauldronTable), -1); + Common::fill(_cauldronTable, ARRAYEND(_cauldronTable), -1); } void KyraEngine_HoF::addFrontCauldronTable(int item) { diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index 27d0849e5f..84990bcfb8 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -174,6 +174,9 @@ Common::Error KyraEngine_LoK::init() { assert(_screen); _screen->setResolution(); + _debugger = new Debugger_LoK(this); + assert(_debugger); + KyraEngine_v1::init(); _sprites = new Sprites(this, _system); @@ -229,8 +232,6 @@ Common::Error KyraEngine_LoK::init() { memset(&_scriptMain, 0, sizeof(EMCState)); memset(&_scriptClick, 0, sizeof(EMCState)); - _debugger = new Debugger_LoK(this); - assert(_debugger); memset(_shapes, 0, sizeof(_shapes)); for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) @@ -254,7 +255,7 @@ Common::Error KyraEngine_LoK::init() { _poisonDeathCounter = 0; memset(_itemHtDat, 0, sizeof(_itemHtDat)); - memset(_exitList, 0xFFFF, sizeof(_exitList)); + memset(_exitList, 0xFF, sizeof(_exitList)); _exitListPtr = 0; _pathfinderFlag = _pathfinderFlag2 = 0; _lastFindWayRet = 0; @@ -436,6 +437,9 @@ void KyraEngine_LoK::startup() { } void KyraEngine_LoK::mainLoop() { + // Initialize debugger since how it should be fully usable + _debugger->initialize(); + _eventList.clear(); while (!shouldQuit()) { diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h index 57e6bd39ab..e5fb3cddca 100644 --- a/engines/kyra/kyra_lok.h +++ b/engines/kyra/kyra_lok.h @@ -29,10 +29,6 @@ #include "kyra/gui_lok.h" #include "kyra/item.h" -namespace Graphics { -struct Surface; -} - namespace Kyra { class Movie; @@ -416,7 +412,7 @@ protected: Movie *_movieObjects[10]; - uint16 _entranceMouseCursorTracks[8]; + uint16 _entranceMouseCursorTracks[5]; uint16 _walkBlockNorth; uint16 _walkBlockEast; uint16 _walkBlockSouth; diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index 5798e99a1f..39ed0d038a 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -205,12 +205,12 @@ Common::Error KyraEngine_MR::init() { assert(_screen); _screen->setResolution(); - KyraEngine_v1::init(); - initStaticResource(); - _debugger = new Debugger_v2(this); assert(_debugger); + KyraEngine_v1::init(); + initStaticResource(); + _soundDigital = new SoundDigital(this, _mixer); assert(_soundDigital); if (!_soundDigital->init()) @@ -887,6 +887,9 @@ bool KyraEngine_MR::checkCharCollision(int x, int y) { #pragma mark - void KyraEngine_MR::runLoop() { + // Initialize debugger since how it should be fully usable + _debugger->initialize(); + _eventList.clear(); _runFlag = true; diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index c950612a42..dbdcda22d5 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -85,8 +85,9 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) void KyraEngine_v1::pauseEngineIntern(bool pause) { Engine::pauseEngineIntern(pause); if (_sound) - _sound->pause(pause); - _timer->pause(pause); + _sound->pause(pause); + if (_timer) + _timer->pause(pause); } Common::Error KyraEngine_v1::init() { @@ -183,6 +184,7 @@ Common::Error KyraEngine_v1::init() { assert(_staticres); if (!_staticres->init()) error("_staticres->init() failed"); + assert(screen()); if (!screen()->init()) error("screen()->init() failed"); _timer = new TimerManager(this, _system); diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 584176e08c..5a9feb0054 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -52,14 +52,16 @@ class KyraMetaEngine; * * Status of this engine: * - * The KYRA engine supports all three Kyrandia games by Westwood. It also supports Westwood's - * Lands of Lore. There are various platform ports of the different games, almost all of them are - * fully supported. Only the Macintosh port of Kyrandia 1 makes a difference here, which lacks - * support for sound effects and music. + * The KYRA engine supports all three Kyrandia games by Westwood. It also + * supports Westwood's Lands of Lore. There are various platform ports of + * the different games, almost all of them are fully supported. Only the + * Macintosh port of Kyrandia 1 makes a difference here, which lacks support + * for sound effects and music. * - * The different translations of the games are mostly supported, since every translation - * requires some work for kyra.dat for example, it is almost impossible to support translations, - * without owning them. There a currently a few reported unsupported translations: + * The different translations of the games are mostly supported, since every + * translation requires some work for kyra.dat for example, it is almost + * impossible to support translations, without owning them. There a currently + * a few reported unsupported translations: * * - Official translations * None known. @@ -69,24 +71,30 @@ class KyraMetaEngine; * Kyrandia 1 Korean (feature request #1758252 "KYRA1: Add support for Korean/DOS version") * Kyrandia 2 Polish (feature request #2146192 "KYRA2: Add support for Polish floppy version") * - Fan translations: - * Kyrandia 1 Russian (no feature request) - * Kyrandia 2 Russian (no feature request) * Kyrandia 3 Russian (feature request #2812792 "Kyrandia3 Russian") * - * The engine is maintained by _athrxx. + * The primary maintainer for the engine is LordHoto, although some parts are + * maintained by _athrxx. If you have questions about parts of the code, the + * following rough description might help in determining who you should ask: + * _athrxx is the maintainer for the Lands of Lore subengine, he also + * maintains most of the FM-TOWNS and PC98 specific code (especially the sound + * code, also some ingame code) and the Kyrandia 2 sequence player code. + * LordHoto is responsible for the rest of the codebase, he also worked on the + * graphics output for 16 color PC98 games. * - * Other people who worked on this engine include cyx, who initially started to work on Kyrandia 1 - * support, vinterstum, who did various things for Kyrandia 1 and started to work on the Kyrandia 2 - * sequence player code and also on the TIM script code, and eriktorbjorn, who helped out naming - * our AdLib player code and also contributed a work around for a music bug in the "Pool of Sorrow" - * scene of Kyrandia 1, which is also present in the original. LordHoto worked on Kyrandia 1 to 3 - * support and graphics output for 16 color PC98 games and was a maintainer of the Kyrandia part. - * All mentioned developers are not actively working on KYRA anymore. + * Other people who worked on this engine include cyx, who initially started + * to work on Kyrandia 1 support. Vinterstum, who did various things for + * Kyrandia 1 and started to work on the Kyrandia 2 sequence player code and + * also on the TIM script code. Eriktorbjorn, who helped out naming our AdLib + * player code and also contributed a work around for a music bug in the + * "Pool of Sorrow" scene of Kyrandia 1, which is also present in the original. + * He also contributed the VQA player for Kyrandia 3. * - * The engine is mostly finished code wise. A possible remaining task is proper refactoring, - * which might help in reducing binary size and along with it runtime memory use, but of course - * might lead to regressions (since the current code makes no problems on our low end ports, it - * is pretty minor priority though, since the benefit would be mostly nicer code). The biggest + * The engine is mostly finished code wise. A possible remaining task is + * proper refactoring, which might help in reducing binary size and along with + * it runtime memory use, but of course might lead to regressions (since the + * current code makes no problems on our low end ports, it is pretty minor + * priority though, since the benefit would be mostly nicer code). The biggest * task left is the kyra.dat handling. * * Games using this engine: diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 5aba264ceb..538e88aa90 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -34,9 +34,14 @@ #include "common/config-manager.h" #include "common/system.h" +#include "common/translation.h" + +#include "backends/keymapper/keymapper.h" namespace Kyra { +const char *const LoLEngine::kKeymapName = "lol"; + LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) { _screen = 0; _gui = 0; @@ -246,6 +251,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy LoLEngine::~LoLEngine() { setupPrologueData(false); +#ifdef ENABLE_KEYMAPPER + _eventMan->getKeymapper()->cleanupGameKeymaps(); +#endif + delete[] _landsFile; delete[] _levelLangFile; @@ -425,6 +434,9 @@ Common::Error LoLEngine::init() { assert(_screen); _screen->setResolution(); + _debugger = new Debugger_LoL(this); + assert(_debugger); + KyraEngine_v1::init(); initStaticResource(); @@ -538,12 +550,67 @@ Common::Error LoLEngine::init() { _spellProcs.push_back(new SpellProc(this, 0)); _spellProcs.push_back(new SpellProc(this, &LoLEngine::castGuardian)); - _debugger = new Debugger_LoL(this); - assert(_debugger); + initKeymap(); return Common::kNoError; } +void LoLEngine::initKeymap() { +#ifdef ENABLE_KEYMAPPER + + bool tmp; + Common::Keymapper *mapper = _eventMan->getKeymapper(); + + // Do not try to recreate same keymap over again + if (mapper->getKeymap(kKeymapName, tmp) != 0) + return; + + Common::Action *act; + Common::Keymap *engineKeyMap = new Common::Keymap(kKeymapName); + + act = new Common::Action(engineKeyMap, "AT1", _("Attack 1"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_F1, Common::ASCII_F1 , 0)); + + act = new Common::Action(engineKeyMap, "AT2", _("Attack 2"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_F2, Common::ASCII_F2 , 0)); + + act = new Common::Action(engineKeyMap, "AT3", _("Attack 3"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_F3, Common::ASCII_F3 , 0)); + + act = new Common::Action(engineKeyMap, "MVF", _("Move Forward"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_UP)); + + act = new Common::Action(engineKeyMap, "MVB", _("Move Back"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_DOWN)); + + act = new Common::Action(engineKeyMap, "SLL", _("Slide Left"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_LEFT)); + + act = new Common::Action(engineKeyMap, "SLR", _("Slide Right"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_RIGHT)); + + act = new Common::Action(engineKeyMap, "TL", _("Turn Left"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_HOME)); + + act = new Common::Action(engineKeyMap, "TR", _("Turn Right"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_PAGEUP)); + + act = new Common::Action(engineKeyMap, "RST", _("Rest"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_r)); + + act = new Common::Action(engineKeyMap, "OPT", _("Options"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_o)); + + act = new Common::Action(engineKeyMap, "SPL", _("Choose Spell"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_SLASH)); + + mapper->addGameKeymap(engineKeyMap); + + mapper->pushKeymap(kKeymapName, true); + +#endif +} + Common::Error LoLEngine::go() { int action = -1; @@ -896,7 +963,7 @@ void LoLEngine::startupNew() { _availableSpells[0] = 0; setupScreenDims(); - memset(_globalScriptVars2, 0x100, 8); + Common::fill(_globalScriptVars2, ARRAYEND(_globalScriptVars2), 0x100); static const int selectIds[] = { -9, -1, -8, -5 }; assert(_charSelection >= 0); @@ -911,6 +978,9 @@ void LoLEngine::startupNew() { } void LoLEngine::runLoop() { + // Initialize debugger since how it should be fully usable + _debugger->initialize(); + enableSysTimer(2); bool _runFlag = true; @@ -993,6 +1063,10 @@ void LoLEngine::writeSettings() { void LoLEngine::readSettings() { _monsterDifficulty = ConfMan.getInt("monster_difficulty"); + if (_monsterDifficulty < 0 || _monsterDifficulty > 2) { + _monsterDifficulty = CLIP(_monsterDifficulty, 0, 2); + warning("LoLEngine: Config file contains invalid difficulty setting."); + } _smoothScrollingEnabled = ConfMan.getBool("smooth_scrolling"); _floatingCursorsEnabled = ConfMan.getBool("floating_cursors"); @@ -1922,8 +1996,7 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int restorePortrait stopPortraitSpeechAnim(); if (charId < 0) { - charId = ch = (_rnd.getRandomNumber(0x7fff) * countActiveCharacters()) / 0x8000; - ch = _rnd.getRandomNumber(countActiveCharacters() - 1); + charId = ch = _rnd.getRandomNumber(countActiveCharacters() - 1); } else if (charId > 0) { int i = 0; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 164f030a1d..eb2f6cf2d7 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -307,6 +307,8 @@ public: LoLEngine(OSystem *system, const GameFlags &flags); ~LoLEngine(); + virtual void initKeymap(); + Screen *screen(); GUI *gui() const; @@ -333,6 +335,8 @@ private: void writeSettings(); void readSettings(); + static const char *const kKeymapName; + const char *const *_pakFileList; int _pakFileListSize; @@ -759,7 +763,7 @@ private: int olol_distanceAttack(EMCState *script); int olol_removeCharacterEffects(EMCState *script); int olol_checkInventoryFull(EMCState *script); - int olol_objectLeavesLevel(EMCState *script); + int olol_moveBlockObjects(EMCState *script); int olol_addSpellToScroll(EMCState *script); int olol_playDialogueText(EMCState *script); int olol_playDialogueTalkText(EMCState *script); @@ -1206,14 +1210,14 @@ private: Item makeItem(int itemType, int curFrame, int flags); void placeMoveLevelItem(Item itemIndex, int level, int block, int xOffs, int yOffs, int flyingHeight); bool addItemToInventory(Item itemIndex); - bool testUnkItemFlags(Item itemIndex); + bool isItemMoveable(Item itemIndex); void deleteItem(Item itemIndex); ItemInPlay *findObject(uint16 index); void runItemScript(int charNum, Item item, int flags, int next, int reg4); void setHandItem(Item itemIndex); bool itemEquipped(int charNum, uint16 itemType); - void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b); + void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int moveable); void removeLevelItem(Item item, int block); bool launchObject(int objectType, Item item, int startX, int startY, int flyingHeight, int direction, int, int attackerId, int c); void endObjectFlight(FlyingObject *t, int x, int y, int collisionObject); diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp index a926f8493f..ab1670ea6e 100644 --- a/engines/kyra/scene_lok.cpp +++ b/engines/kyra/scene_lok.cpp @@ -131,7 +131,7 @@ void KyraEngine_LoK::enterNewScene(int sceneId, int facing, int unk1, int unk2, _emc->run(&_scriptClick); } - memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); + memset(_entranceMouseCursorTracks, 0xFF, sizeof(_entranceMouseCursorTracks)); _currentCharacter->sceneId = sceneId; assert(sceneId < _roomTableSize); diff --git a/engines/kyra/scene_mr.cpp b/engines/kyra/scene_mr.cpp index 74d2e89e6e..d6df523f82 100644 --- a/engines/kyra/scene_mr.cpp +++ b/engines/kyra/scene_mr.cpp @@ -83,7 +83,7 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2 } _specialExitCount = 0; - Common::set_to(_specialExitTable, ARRAYEND(_specialExitTable), 0xFFFF); + Common::fill(_specialExitTable, ARRAYEND(_specialExitTable), 0xFFFF); _mainCharacter.sceneId = sceneId; _sceneList[sceneId].flags &= ~1; @@ -388,7 +388,7 @@ void KyraEngine_MR::initSceneScript(int unk1) { strcat(filename, ".CPS"); _screen->loadBitmap(filename, 3, 3, 0); - Common::set_to(_specialSceneScriptState, ARRAYEND(_specialSceneScriptState), false); + Common::fill(_specialSceneScriptState, ARRAYEND(_specialSceneScriptState), false); _sceneEnterX1 = 160; _sceneEnterY1 = 0; _sceneEnterX2 = 296; diff --git a/engines/kyra/scene_v1.cpp b/engines/kyra/scene_v1.cpp index 5319d4e657..bc90f49002 100644 --- a/engines/kyra/scene_v1.cpp +++ b/engines/kyra/scene_v1.cpp @@ -277,7 +277,7 @@ void KyraEngine_v1::changePosTowardsFacing(int &x, int &y, int facing) { } int KyraEngine_v1::getMoveTableSize(int *moveTable) { - int retValue = 0; + int tableSize = 0; if (moveTable[0] == 8) return 0; @@ -298,11 +298,11 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) { int *oldPosition = moveTable; int *tempPosition = moveTable; int *curPosition = moveTable + 1; - retValue = 1; + tableSize = 1; while (*curPosition != 8) { if (*oldPosition == facingTable[*curPosition]) { - retValue -= 2; + tableSize -= 2; *oldPosition = 9; *curPosition = 9; @@ -313,7 +313,7 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) { } if (tempPosition == moveTable && *tempPosition == 9) { - while (*tempPosition != 8 && *tempPosition == 9) + while (*tempPosition == 9) ++tempPosition; if (*tempPosition == 8) @@ -321,53 +321,40 @@ int KyraEngine_v1::getMoveTableSize(int *moveTable) { } oldPosition = tempPosition; - curPosition = oldPosition+1; + curPosition = oldPosition + 1; - while (*curPosition != 8 && *curPosition == 9) + while (*curPosition == 9) ++curPosition; - - continue; - } - - if (unkTable[*curPosition+((*oldPosition)*8)] != -1) { - --retValue; - *oldPosition = unkTable[*curPosition+((*oldPosition)*8)]; + } else if (unkTable[*curPosition + *oldPosition * 8] != -1) { + --tableSize; + *oldPosition = unkTable[*curPosition + *oldPosition * 8]; *curPosition = 9; if (tempPosition != oldPosition) { curPosition = oldPosition; oldPosition = tempPosition; - while (true) { - if (tempPosition == moveTable) - break; - + while (tempPosition != moveTable) { --tempPosition; if (*tempPosition != 9) break; - } } else { - while (true) { + do { ++curPosition; - if (*curPosition != 9) - break; - } + } while (*curPosition == 9); } - continue; - } - - tempPosition = oldPosition; - oldPosition = curPosition; - ++retValue; + } else { + tempPosition = oldPosition; + oldPosition = curPosition; + ++tableSize; - while (true) { - ++curPosition; - if (*curPosition != 9) - break; + do { + ++curPosition; + } while (*curPosition == 9); } } - return retValue; + return tableSize; } } // End of namespace Kyra diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp index 296cd4002b..b80b8105a1 100644 --- a/engines/kyra/script_hof.cpp +++ b/engines/kyra/script_hof.cpp @@ -1397,7 +1397,6 @@ int KyraEngine_HoF::o2_demoFinale(EMCState *script) { _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0); _screen->_curPage = 0; - _screen->setFont(Screen::FID_6_FNT); int y = _lang == 1 ? 70 : 65; for (int i = 0; i < 6; i++) _text->printText(strings[i], _text->getCenterStringX(strings[i], 1, 319), y + i * 10, 255, 207, 0); @@ -1406,7 +1405,7 @@ int KyraEngine_HoF::o2_demoFinale(EMCState *script) { _screen->updateScreen(); _eventList.clear(); - while (!skipFlag()) + while (!skipFlag() && !shouldQuit()) delay(10); _sound->beginFadeOut(); diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index b4b8f00022..d8ba32ce09 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -124,7 +124,7 @@ int LoLEngine::olol_setWallType(EMCState *script) { int LoLEngine::olol_getWallType(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getWallType(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - return _levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3]; + return (int8)_levelBlockProperties[stackPos(0)].walls[stackPos(1) & 3]; } int LoLEngine::olol_drawScene(EMCState *script) { @@ -286,13 +286,13 @@ int LoLEngine::olol_makeItem(EMCState *script) { } int LoLEngine::olol_placeMoveLevelItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeMoveLevelItem(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); placeMoveLevelItem(stackPos(0), stackPos(1), stackPos(2), stackPos(3) & 0xff, stackPos(4) & 0xff, stackPos(5)); return 1; } int LoLEngine::olol_createLevelItem(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setItemProperty(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_createLevelItem(%p) (%d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7)); int item = makeItem(stackPos(0), stackPos(1), stackPos(2)); if (item == -1) return item; @@ -676,6 +676,8 @@ int LoLEngine::olol_getGlobalVar(EMCState *script) { return _drainMagic; case 13: return getVolume(kVolumeSpeech) - 2; + case 14: + return _tim->_abortFlag; default: break; } @@ -842,7 +844,7 @@ int LoLEngine::olol_initMonster(EMCState *script) { l->direction = l->facing << 1; l->hitPoints = (l->properties->hitPoints * _monsterModifiers[_monsterDifficulty]) >> 8; - if (_currentLevel == 12 && l->type == 2) + if (_currentLevel != 12 || l->type != 2) l->hitPoints = (l->hitPoints * (rollDice(1, 128) + 192)) >> 8; l->numDistAttacks = l->properties->numDistAttacks; @@ -859,7 +861,7 @@ int LoLEngine::olol_initMonster(EMCState *script) { l->destDirection = l->direction; for (int ii = 0; ii < 4; ii++) - l->equipmentShapes[ii] = stackPos(7 + ii); + l->equipmentShapes[ii] = stackPos(7 + ii) & 0xff; checkSceneUpdateNeed(l->block); return i; @@ -1538,12 +1540,12 @@ int LoLEngine::olol_checkInventoryFull(EMCState *script) { return 1; } -int LoLEngine::olol_objectLeavesLevel(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_objectLeavesLevel(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); +int LoLEngine::olol_moveBlockObjects(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveBlockObjects(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int o = _levelBlockProperties[stackPos(0)].assignedObjects; int res = 0; int level = stackPos(2); - int block = stackPos(1); + int destBlock = stackPos(1); int runScript = stackPos(4); int includeMonsters = stackPos(3); int includeItems = stackPos(5); @@ -1551,9 +1553,9 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) { // WORKAROUND for script bug // Items would vanish when thrown towards the stairs // in white tower level 3. - if (_currentLevel == 21 && level == 21 && block == 0x3e0) { + if (_currentLevel == 21 && level == 21 && destBlock == 0x3e0) { level = 20; - block = 0x0247; + destBlock = 0x0247; } while (o) { @@ -1577,15 +1579,13 @@ int LoLEngine::olol_objectLeavesLevel(EMCState *script) { if (!(_itemsInPlay[l].shpCurFrame_flg & 0x4000) || !includeItems) continue; - placeMoveLevelItem(l, level, block, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight); + placeMoveLevelItem(l, level, destBlock, _itemsInPlay[l].x & 0xff, _itemsInPlay[l].y & 0xff, _itemsInPlay[l].flyingHeight); + res = 1; - if (!runScript || level != _currentLevel) { - res = 1; - continue; - } + if (!runScript || level != _currentLevel) + continue; - runLevelScriptCustom(block, 0x80, -1, l, 0, 0); - res = 1; + runLevelScriptCustom(destBlock, 0x80, -1, l, 0, 0); } } @@ -2056,17 +2056,16 @@ int LoLEngine::olol_changeItemTypeOrFlag(EMCState *script) { return 0; ItemInPlay *i = &_itemsInPlay[stackPos(0)]; - int r = stackPos(2) & 0x1fff; + int16 val = stackPos(2); - if (stackPos(1) == 4) { - i->itemPropertyIndex = r; - return r; - } else if (stackPos(1) == 15) { - i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xe000) | r; - return r; - } + if (stackPos(1) == 4) + i->itemPropertyIndex = val; + else if (stackPos(1) == 15) + i->shpCurFrame_flg = (i->shpCurFrame_flg & 0xe000) | (val & 0x1fff); + else + val = -1; - return -1; + return val; } int LoLEngine::olol_placeInventoryItemInHand(EMCState *script) { @@ -2881,7 +2880,7 @@ void LoLEngine::setupOpcodeTable() { // 0x74 Opcode(olol_checkInventoryFull); - Opcode(olol_objectLeavesLevel); + Opcode(olol_moveBlockObjects); OpcodeUnImpl(); OpcodeUnImpl(); diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp index 8ab094ac0c..afe11aba02 100644 --- a/engines/kyra/script_mr.cpp +++ b/engines/kyra/script_mr.cpp @@ -405,7 +405,7 @@ int KyraEngine_MR::o3_updateConversations(EMCState *script) { } int convs[4]; - Common::set_to(convs, convs+4, -1); + Common::fill(convs, convs+4, -1); if (_currentChapter == 1) { switch (_mainCharacter.dlgIndex) { diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index 2de0565a74..99ae2ad7b3 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -1322,7 +1322,7 @@ void KyraEngine_LoK::seq_playCredits() { _screen->copyRegion(0, 32, 0, 32, 320, 128, 4, 2, Screen::CR_NO_P_CHECK); bottom = 0; - for (CreditsLineList::iterator it = lines.begin(); it != lines.end(); ++it) { + for (CreditsLineList::iterator it = lines.begin(); it != lines.end();) { if (it->y < 0) { it = lines.erase(it); continue; @@ -1338,6 +1338,8 @@ void KyraEngine_LoK::seq_playCredits() { it->y--; if (it->y > bottom) bottom = it->y; + + ++it; } _screen->copyRegion(0, 32, 0, 32, 320, 128, 2, 0, Screen::CR_NO_P_CHECK); diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp index 83d525d400..01db92c225 100644 --- a/engines/kyra/sequences_lol.cpp +++ b/engines/kyra/sequences_lol.cpp @@ -788,7 +788,7 @@ void HistoryPlayer::play() { for (; voiceFilename[3] <= '9' && !_vm->shouldQuit() && !_vm->skipFlag(); ++voiceFilename[3], voiceFilename[4] = 'a') { while (!_vm->shouldQuit() && !_vm->skipFlag()) { - if (!sound->voiceFileIsPresent(voiceFilename)) + if (!sound->isVoicePresent(voiceFilename)) break; if (data[part * 15] == voiceFilename[3] && data[part * 15 + 1] == voiceFilename[4]) { diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index b4fcea784e..a1af1ad6f8 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -43,25 +43,30 @@ Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer) Sound::~Sound() { } -bool Sound::voiceFileIsPresent(const char *file) { - for (int i = 0; _supportedCodecs[i].fileext; ++i) { - Common::String f = file; - f += _supportedCodecs[i].fileext; - if (_vm->resource()->getFileSize(f.c_str()) > 0) - return true; - } +Sound::kType Sound::getSfxType() const { + return getMusicType(); +} + +void Sound::setSoundList(const AudioDataStruct *list) { + _soundDataList = list; +} + +bool Sound::hasSoundFile(uint file) const { + return (fileListEntry(file) != 0); +} +bool Sound::isPlaying() const { return false; } -bool Sound::isVoicePresent(const char *file) { - char filenamebuffer[25]; +bool Sound::isVoicePresent(const char *file) const { + Common::String filename; for (int i = 0; _supportedCodecs[i].fileext; ++i) { - strcpy(filenamebuffer, file); - strcat(filenamebuffer, _supportedCodecs[i].fileext); + filename = file; + filename += _supportedCodecs[i].fileext; - if (_vm->resource()->exists(filenamebuffer)) + if (_vm->resource()->exists(filename.c_str())) return true; } @@ -80,15 +85,15 @@ int32 Sound::voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volum return playTime; } -Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) { - char filenamebuffer[25]; +Audio::SeekableAudioStream *Sound::getVoiceStream(const char *file) const { + Common::String filename; Audio::SeekableAudioStream *audioStream = 0; for (int i = 0; _supportedCodecs[i].fileext; ++i) { - strcpy(filenamebuffer, file); - strcat(filenamebuffer, _supportedCodecs[i].fileext); + filename = file; + filename += _supportedCodecs[i].fileext; - Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filenamebuffer); + Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename); if (!stream) continue; @@ -109,8 +114,14 @@ bool Sound::playVoiceStream(Audio::AudioStream *stream, Audio::SoundHandle *hand while (h < kNumChannelHandles && _mixer->isSoundHandleActive(_soundChannels[h])) ++h; - if (h >= kNumChannelHandles) + if (h >= kNumChannelHandles) { + // When we run out of handles we need to destroy the stream object, + // this is to avoid memory leaks in some scenes where too many sfx + // are started. + // See bug #3427240 "LOL-CD: Memory leak in caves level 3". + delete stream; return false; + } _mixer->playStream(isSfx ? Audio::Mixer::kSFXSoundType : Audio::Mixer::kSpeechSoundType, &_soundChannels[h], stream, -1, volume); if (handle) @@ -130,7 +141,7 @@ void Sound::voiceStop(const Audio::SoundHandle *handle) { } } -bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) { +bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) const { if (!handle) { for (int h = 0; h < kNumChannelHandles; ++h) { if (_mixer->isSoundHandleActive(_soundChannels[h])) @@ -143,7 +154,7 @@ bool Sound::voiceIsPlaying(const Audio::SoundHandle *handle) { return false; } -bool Sound::allVoiceChannelsPlaying() { +bool Sound::allVoiceChannelsPlaying() const { for (int i = 0; i < kNumChannelHandles; ++i) if (!_mixer->isSoundHandleActive(_soundChannels[i])) return false; @@ -152,6 +163,91 @@ bool Sound::allVoiceChannelsPlaying() { #pragma mark - +MixedSoundDriver::MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) + : Sound(vm, mixer), _music(music), _sfx(sfx) { +} + +MixedSoundDriver::~MixedSoundDriver() { + delete _music; + delete _sfx; +} + +Sound::kType MixedSoundDriver::getMusicType() const { + return _music->getMusicType(); +} + +Sound::kType MixedSoundDriver::getSfxType() const { + return _sfx->getSfxType(); +} + +bool MixedSoundDriver::init() { + return (_music->init() && _sfx->init()); +} + +void MixedSoundDriver::process() { + _music->process(); + _sfx->process(); +} + +void MixedSoundDriver::updateVolumeSettings() { + _music->updateVolumeSettings(); + _sfx->updateVolumeSettings(); +} + +void MixedSoundDriver::setSoundList(const AudioDataStruct *list) { + _music->setSoundList(list); + _sfx->setSoundList(list); +} + +bool MixedSoundDriver::hasSoundFile(uint file) const { + return _music->hasSoundFile(file) && _sfx->hasSoundFile(file); +} + +void MixedSoundDriver::loadSoundFile(uint file) { + _music->loadSoundFile(file); + _sfx->loadSoundFile(file); +} + +void MixedSoundDriver::loadSoundFile(Common::String file) { + _music->loadSoundFile(file); + _sfx->loadSoundFile(file); +} + +void MixedSoundDriver::loadSfxFile(Common::String file) { + _sfx->loadSoundFile(file); +} + +void MixedSoundDriver::playTrack(uint8 track) { + _music->playTrack(track); +} + +void MixedSoundDriver::haltTrack() { + _music->haltTrack(); +} + +bool MixedSoundDriver::isPlaying() const { + return _music->isPlaying() | _sfx->isPlaying(); +} + +void MixedSoundDriver::playSoundEffect(uint8 track) { + _sfx->playSoundEffect(track); +} + +void MixedSoundDriver::stopAllSoundEffects() { + _sfx->stopAllSoundEffects(); +} + +void MixedSoundDriver::beginFadeOut() { + _music->beginFadeOut(); +} + +void MixedSoundDriver::pause(bool paused) { + _music->pause(paused); + _sfx->pause(paused); +} + +#pragma mark - + void KyraEngine_v1::snd_playTheme(int file, int track) { if (_curMusicTheme == file) return; @@ -238,16 +334,7 @@ namespace { // A simple wrapper to create VOC streams the way like creating MP3, OGG/Vorbis and FLAC streams. // Possible TODO: Think of making this complete and moving it to sound/voc.cpp ? Audio::SeekableAudioStream *makeVOCStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse) { - -#ifdef STREAM_AUDIO_FROM_DISK Audio::SeekableAudioStream *as = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, disposeAfterUse); -#else - Audio::SeekableAudioStream *as = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO); - - if (disposeAfterUse) - delete stream; -#endif - return as; } diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h index c3c32331be..f3de56520e 100644 --- a/engines/kyra/sound.h +++ b/engines/kyra/sound.h @@ -58,7 +58,7 @@ public: }; virtual kType getMusicType() const = 0; - virtual kType getSfxType() const { return getMusicType(); } + virtual kType getSfxType() const; /** * Initializes the output device. @@ -83,7 +83,7 @@ public: * * @param list soundfile list */ - virtual void setSoundList(const AudioDataStruct *list) { _soundDataList = list; } + virtual void setSoundList(const AudioDataStruct *list); /** * Checks if a given sound file is present. @@ -91,7 +91,7 @@ public: * @param track track number * @return true if available, false otherwise */ - virtual bool hasSoundFile(uint file) const { return (fileListEntry(file) != 0); } + virtual bool hasSoundFile(uint file) const; /** * Load a specifc sound file for use of @@ -140,7 +140,7 @@ public: * * @return true if playing, false otherwise */ - virtual bool isPlaying() const { return false; } + virtual bool isPlaying() const; /** * Starts fading out the volume. @@ -163,15 +163,13 @@ public: void enableSFX(bool enable) { _sfxEnabled = enable; } bool sfxEnabled() const { return _sfxEnabled; } - virtual bool voiceFileIsPresent(const char *file); - /** * Checks whether a voice file with the given name is present * * @param file file name * @return true if available, false otherwise */ - bool isVoicePresent(const char *file); + bool isVoicePresent(const char *file) const; /** * Plays the specified voice file. @@ -188,7 +186,7 @@ public: */ virtual int32 voicePlay(const char *file, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false); - Audio::SeekableAudioStream *getVoiceStream(const char *file); + Audio::SeekableAudioStream *getVoiceStream(const char *file) const; bool playVoiceStream(Audio::AudioStream *stream, Audio::SoundHandle *handle = 0, uint8 volume = 255, bool isSfx = false); @@ -197,21 +195,21 @@ public: * * @return true when playing, else false */ - bool voiceIsPlaying(const Audio::SoundHandle *handle = 0); + bool voiceIsPlaying(const Audio::SoundHandle *handle = 0) const; /** * Checks if all voice handles are used. * * @return false when a handle is free, else true */ - bool allVoiceChannelsPlaying(); + bool allVoiceChannelsPlaying() const; /** * Checks how long a voice has been playing * * @return time in milliseconds */ - uint32 voicePlayedTime(const Audio::SoundHandle &handle) { + uint32 voicePlayedTime(const Audio::SoundHandle &handle) const { return _mixer->getSoundElapsedTime(handle); } @@ -253,34 +251,34 @@ private: class MixedSoundDriver : public Sound { public: - MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx) : Sound(vm, mixer), _music(music), _sfx(sfx) {} - ~MixedSoundDriver() { delete _music; delete _sfx; } + MixedSoundDriver(KyraEngine_v1 *vm, Audio::Mixer *mixer, Sound *music, Sound *sfx); + ~MixedSoundDriver(); - kType getMusicType() const { return _music->getMusicType(); } - kType getSfxType() const { return _sfx->getSfxType(); } + virtual kType getMusicType() const; + virtual kType getSfxType() const; - bool init() { return (_music->init() && _sfx->init()); } - void process() { _music->process(); _sfx->process(); } + virtual bool init(); + virtual void process(); - void updateVolumeSettings() { _music->updateVolumeSettings(); _sfx->updateVolumeSettings(); } + virtual void updateVolumeSettings(); - void setSoundList(const AudioDataStruct * list) { _music->setSoundList(list); _sfx->setSoundList(list); } - bool hasSoundFile(uint file) const { return _music->hasSoundFile(file) && _sfx->hasSoundFile(file); } - void loadSoundFile(uint file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); } - void loadSoundFile(Common::String file) { _music->loadSoundFile(file); _sfx->loadSoundFile(file); } + virtual void setSoundList(const AudioDataStruct *list); + virtual bool hasSoundFile(uint file) const; + virtual void loadSoundFile(uint file); + virtual void loadSoundFile(Common::String file); - void loadSfxFile(Common::String file) { _sfx->loadSoundFile(file); } + virtual void loadSfxFile(Common::String file); - void playTrack(uint8 track) { _music->playTrack(track); } - void haltTrack() { _music->haltTrack(); } - bool isPlaying() const { return _music->isPlaying() | _sfx->isPlaying(); } + virtual void playTrack(uint8 track); + virtual void haltTrack(); + virtual bool isPlaying() const; - void playSoundEffect(uint8 track) { _sfx->playSoundEffect(track); } + virtual void playSoundEffect(uint8 track); - void stopAllSoundEffects() { _sfx->stopAllSoundEffects(); } + virtual void stopAllSoundEffects(); - void beginFadeOut() { _music->beginFadeOut(); } - void pause(bool paused) { _music->pause(paused); _sfx->pause(paused); } + virtual void beginFadeOut(); + virtual void pause(bool paused); private: Sound *_music, *_sfx; }; diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index 8976eba99c..b04abea080 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -42,6 +42,7 @@ #include "common/system.h" #include "common/mutex.h" +#include "common/config-manager.h" #include "audio/mixer.h" #include "audio/fmopl.h" @@ -59,7 +60,13 @@ public: AdLibDriver(Audio::Mixer *mixer, bool v2); ~AdLibDriver(); - int callback(int opcode, ...); + void initDriver(); + void setSoundData(uint8 *data); + void queueTrack(int track); + bool isChannelPlaying(int channel) const; + void stopAllChannels(); + int getSoundTrigger() const { return _soundTrigger; } + void callback(); // AudioStream API @@ -92,36 +99,10 @@ public: void setSyncJumpMask(uint16 mask) { _syncJumpMask = mask; } -private: - struct OpcodeEntry { - typedef int (AdLibDriver::*DriverOpcode)(va_list &list); - DriverOpcode function; - const char *name; - }; - - void setupOpcodeList(); - const OpcodeEntry *_opcodeList; - int _opcodesEntries; - - int snd_ret0x100(va_list &list); - int snd_ret0x1983(va_list &list); - int snd_initDriver(va_list &list); - int snd_deinitDriver(va_list &list); - int snd_setSoundData(va_list &list); - int snd_unkOpcode1(va_list &list); - int snd_startSong(va_list &list); - int snd_isChannelPlaying(va_list &list); - int snd_stopChannel(va_list &list); - int snd_readByte(va_list &list); - int snd_writeByte(va_list &list); - int snd_getSoundTrigger(va_list &list); - int snd_unkOpcode4(va_list &list); - int snd_dummy(va_list &list); - int snd_getNullvar4(va_list &list); - int snd_setNullvar3(va_list &list); - int snd_setFlag(va_list &list); - int snd_clearFlag(va_list &list); + void setMusicVolume(uint8 volume); + void setSfxVolume(uint8 volume); +private: // These variables have not yet been named, but some of them are partly // known nevertheless: // @@ -195,6 +176,7 @@ private: uint8 tempoReset; uint8 rawNote; int8 unk16; + uint8 volumeModifier; }; void primaryEffect1(Channel &channel); @@ -346,11 +328,8 @@ private: int32 _samplesTillCallback; int32 _samplesTillCallbackRemainder; - int _lastProcessed; - int8 _flagTrigger; int _curChannel; uint8 _soundTrigger; - int _soundsPlaying; uint16 _rnd; @@ -375,12 +354,19 @@ private: uint8 _unkValue19; uint8 _unkValue20; - int _flags; FM_OPL *_adlib; uint8 *_soundData; - uint8 _soundIdTable[0x10]; + int _programStartTimeout; + uint8 *_programQueue[16]; + int _programQueueStart, _programQueueEnd; + + void adjustSfxData(uint8 *data); + uint8 *_sfxPointer; + int _sfxPriority; + int _sfxVelocity; + Channel _channels[10]; uint8 _vibratoAndAMDepthBits; @@ -406,18 +392,18 @@ private: Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; + uint8 _musicVolume, _sfxVolume; + bool _v2; }; AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { - setupOpcodeList(); setupParserOpcodeTable(); _v2 = v2; _mixer = mixer; - _flags = 0; _adlib = makeAdLibOPL(getRate()); assert(_adlib); @@ -426,12 +412,12 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { _vibratoAndAMDepthBits = _curRegOffset = 0; - _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0; - _soundsPlaying = 0; + _curChannel = _rhythmSectionBits = 0; _rnd = 0x1234; _tempo = 0; _soundTrigger = 0; + _programStartTimeout = 0; _callbackTimer = 0xFF; _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0; @@ -441,14 +427,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { _tablePtr1 = _tablePtr2 = 0; - // HACK: We use MusicSoundType here for now so we can adjust the volume in the launcher dialog. - // This affects SFX too, but if we want to support different volumes for SFX and music we would - // have to change our player implementation, currently we setup the volume for an AdLib channel - // in AdLibDriver::adjustVolume, so if that would be called, we would have to know if the channel - // is used by SFX or music, and then adjust the volume accordingly. Since Kyrandia 2 supports - // different volumes for SFX and music, looking at the disasm and checking how the original does it - // would be a good idea. - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND; _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND; @@ -456,6 +435,13 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, bool v2) { _samplesTillCallbackRemainder = 0; _syncJumpMask = 0; + + _musicVolume = 0; + _sfxVolume = 0; + + _sfxPointer = 0; + + _programQueueStart = _programQueueEnd = 0; } AdLibDriver::~AdLibDriver() { @@ -464,100 +450,108 @@ AdLibDriver::~AdLibDriver() { _adlib = 0; } -int AdLibDriver::callback(int opcode, ...) { +void AdLibDriver::setMusicVolume(uint8 volume) { Common::StackLock lock(_mutex); - if (opcode >= _opcodesEntries || opcode < 0) { - warning("AdLibDriver: calling unknown opcode '%d'", opcode); - return 0; + + _musicVolume = volume; + + for (uint i = 0; i < 6; ++i) { + Channel &chan = _channels[i]; + chan.volumeModifier = volume; + + const uint8 regOffset = _regOffset[i]; + + // Level Key Scaling / Total Level + writeOPL(0x40 + regOffset, calculateOpLevel1(chan)); + writeOPL(0x43 + regOffset, calculateOpLevel2(chan)); } - debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode); + // For now we use the music volume for both sfx and music in Kyra1. + if (!_v2) { + _sfxVolume = volume; - va_list args; - va_start(args, opcode); - int returnValue = (this->*(_opcodeList[opcode].function))(args); - va_end(args); - return returnValue; -} + for (uint i = 6; i < 9; ++i) { + Channel &chan = _channels[i]; + chan.volumeModifier = volume; -// Opcodes + const uint8 regOffset = _regOffset[i]; -int AdLibDriver::snd_ret0x100(va_list &list) { - return 0x100; + // Level Key Scaling / Total Level + writeOPL(0x40 + regOffset, calculateOpLevel1(chan)); + writeOPL(0x43 + regOffset, calculateOpLevel2(chan)); + } + } } -int AdLibDriver::snd_ret0x1983(va_list &list) { - return 0x1983; -} +void AdLibDriver::setSfxVolume(uint8 volume) { + // We only support sfx volume in v2 games. + if (!_v2) + return; -int AdLibDriver::snd_initDriver(va_list &list) { - _lastProcessed = _soundsPlaying = 0; - resetAdLibState(); - return 0; + Common::StackLock lock(_mutex); + + _sfxVolume = volume; + + for (uint i = 6; i < 9; ++i) { + Channel &chan = _channels[i]; + chan.volumeModifier = volume; + + const uint8 regOffset = _regOffset[i]; + + // Level Key Scaling / Total Level + writeOPL(0x40 + regOffset, calculateOpLevel1(chan)); + writeOPL(0x43 + regOffset, calculateOpLevel2(chan)); + } } -int AdLibDriver::snd_deinitDriver(va_list &list) { +void AdLibDriver::initDriver() { + Common::StackLock lock(_mutex); resetAdLibState(); - return 0; } -int AdLibDriver::snd_setSoundData(va_list &list) { +void AdLibDriver::setSoundData(uint8 *data) { + Common::StackLock lock(_mutex); + + // Drop all tracks that are still queued. These would point to the old + // sound data. + _programQueueStart = _programQueueEnd = 0; + memset(_programQueue, 0, sizeof(_programQueue)); + if (_soundData) { delete[] _soundData; _soundData = 0; } - _soundData = va_arg(list, uint8 *); - return 0; -} -int AdLibDriver::snd_unkOpcode1(va_list &list) { - warning("unimplemented snd_unkOpcode1"); - return 0; + _soundData = data; } -int AdLibDriver::snd_startSong(va_list &list) { - int songId = va_arg(list, int); - _flags |= 8; - _flagTrigger = 1; +void AdLibDriver::queueTrack(int track) { + Common::StackLock lock(_mutex); - uint8 *ptr = getProgram(songId); - assert(ptr); - uint8 chan = *ptr; + uint8 *trackData = getProgram(track); + if (!trackData) + return; - if ((songId << 1) != 0) { - if (chan == 9) { - if (_flags & 2) - return 0; - } else { - if (_flags & 1) - return 0; - } + if (_programQueueEnd == _programQueueStart && _programQueue[_programQueueEnd] != 0) { + warning("AdLibDriver: Program queue full, dropping track %d", track); + return; } - _soundIdTable[_soundsPlaying++] = songId; - _soundsPlaying &= 0x0F; - - return 0; + _programQueue[_programQueueEnd++] = trackData; + _programQueueEnd &= 15; } -int AdLibDriver::snd_isChannelPlaying(va_list &list) { - int channel = va_arg(list, int); +bool AdLibDriver::isChannelPlaying(int channel) const { + Common::StackLock lock(_mutex); + assert(channel >= 0 && channel <= 9); - return (_channels[channel].dataptr != 0) ? 1 : 0; + return (_channels[channel].dataptr != 0); } -int AdLibDriver::snd_stopChannel(va_list &list) { - int channel = va_arg(list, int); - - int maxChannel; - if (channel < 0) { - channel = 0; - maxChannel = 9; - } else { - maxChannel = channel; - } +void AdLibDriver::stopAllChannels() { + Common::StackLock lock(_mutex); - for (; channel <= maxChannel; ++channel) { + for (int channel = 0; channel <= 9; ++channel) { _curChannel = channel; Channel &chan = _channels[_curChannel]; @@ -567,71 +561,16 @@ int AdLibDriver::snd_stopChannel(va_list &list) { if (channel != 9) noteOff(chan); } - - return 0; -} - -int AdLibDriver::snd_readByte(va_list &list) { - int a = va_arg(list, int); - int b = va_arg(list, int); - uint8 *ptr = getProgram(a) + b; - assert(ptr); - return *ptr; -} - -int AdLibDriver::snd_writeByte(va_list &list) { - int a = va_arg(list, int); - int b = va_arg(list, int); - uint8 value = va_arg(list, int); - uint8 *ptr = getProgram(a) + b; - assert(ptr); - SWAP(*ptr, value); - return value; -} - -int AdLibDriver::snd_getSoundTrigger(va_list &list) { - return _soundTrigger; -} - -int AdLibDriver::snd_unkOpcode4(va_list &list) { - warning("unimplemented snd_unkOpcode4"); - return 0; -} - -int AdLibDriver::snd_dummy(va_list &list) { - return 0; -} - -int AdLibDriver::snd_getNullvar4(va_list &list) { - warning("unimplemented snd_getNullvar4"); - return 0; -} - -int AdLibDriver::snd_setNullvar3(va_list &list) { - warning("unimplemented snd_setNullvar3"); - return 0; -} - -int AdLibDriver::snd_setFlag(va_list &list) { - int oldFlags = _flags; - _flags |= va_arg(list, int); - return oldFlags; -} - -int AdLibDriver::snd_clearFlag(va_list &list) { - int oldFlags = _flags; - _flags &= ~(va_arg(list, int)); - return oldFlags; } // timer callback void AdLibDriver::callback() { Common::StackLock lock(_mutex); - --_flagTrigger; - if (_flagTrigger < 0) - _flags &= ~8; - setupPrograms(); + if (_programStartTimeout) + --_programStartTimeout; + else + setupPrograms(); executePrograms(); uint8 temp = _callbackTimer; @@ -645,36 +584,86 @@ void AdLibDriver::callback() { } void AdLibDriver::setupPrograms() { - while (_lastProcessed != _soundsPlaying) { - uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]); - uint8 chan = *ptr++; - uint8 priority = *ptr++; - - // Only start this sound if its priority is higher than the one - // already playing. - - Channel &channel = _channels[chan]; - - if (priority >= channel.priority) { - initChannel(channel); - channel.priority = priority; - channel.dataptr = ptr; - channel.tempo = 0xFF; - channel.position = 0xFF; - channel.duration = 1; - unkOutput2(chan); - } + // If there is no program queued, we skip this. + if (_programQueueStart == _programQueueEnd) + return; + + uint8 *ptr = _programQueue[_programQueueStart]; + // Clear the queue entry + _programQueue[_programQueueStart] = 0; + _programQueueStart = (_programQueueStart + 1) & 15; + + // Adjust data in case we hit a sound effect. + adjustSfxData(ptr); + + const int chan = *ptr++; + const int priority = *ptr++; + + // Only start this sound if its priority is higher than the one + // already playing. + + Channel &channel = _channels[chan]; - // What we have set up now is, probably, the controlling - // channel for the sound. It is assumed that this program will - // set up all the other channels it needs, clearing their locks - // along the way. + if (priority >= channel.priority) { + initChannel(channel); + channel.priority = priority; + channel.dataptr = ptr; + channel.tempo = 0xFF; + channel.position = 0xFF; + channel.duration = 1; - ++_lastProcessed; - _lastProcessed &= 0x0F; + if (chan <= 5) + channel.volumeModifier = _musicVolume; + else + channel.volumeModifier = _sfxVolume; + + unkOutput2(chan); + + // We need to wait two callback calls till we can start another track. + // This is (probably) required to assure that the sfx are started with + // the correct priority and velocity. + _programStartTimeout = 2; } } +void AdLibDriver::adjustSfxData(uint8 *ptr) { + // Check whether we need to reset the data of an old sfx which has been + // started. + if (_sfxPointer) { + _sfxPointer[1] = _sfxPriority; + _sfxPointer[3] = _sfxVelocity; + _sfxPointer = 0; + } + + // Only music tracks are started on channel 9, thus we need to make sure + // we do not have a music track here. + if (*ptr == 9) + return; + + // Store the pointer so we can reset the data when a new program is started. + _sfxPointer = ptr; + + // Store the old values. + _sfxPriority = ptr[1]; + _sfxVelocity = ptr[3]; + + // In the cases I've seen, the mysterious fourth byte has been + // the parameter for the update_setExtraLevel3() callback. + // + // The extra level is part of the channels "total level", which + // is a six-bit value where larger values means softer volume. + // + // So what seems to be happening here is that sounds which are + // started by this function are given a slightly lower priority + // and a slightly higher (i.e. softer) extra level 3 than they + // would have if they were started from anywhere else. Strange. + + // Adjust the values. + int newVal = ((((ptr[3]) + 63) * 0xFF) >> 8) & 0xFF; + ptr[3] = -newVal + 63; + ptr[1] = ((ptr[1] * 0xFF) >> 8) & 0xFF; +} + // A few words on opcode parsing and timing: // // First of all, We simulate a timer callback 72 times per second. Each timeout @@ -1273,9 +1262,21 @@ uint8 AdLibDriver::calculateOpLevel1(Channel &channel) { if (channel.twoChan) { value += channel.opExtraLevel1; value += channel.opExtraLevel2; - value += channel.opExtraLevel3; + + uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier; + if (level3) { + level3 += 0x3F; + level3 >>= 8; + } + + value += level3 ^ 0x3F; } + value = CLIP<int8>(value, 0, 0x3F); + + if (!channel.volumeModifier) + value = 0x3F; + // Preserve the scaling level bits from opLevel1 return checkValue(value) | (channel.opLevel1 & 0xC0); @@ -1286,7 +1287,19 @@ uint8 AdLibDriver::calculateOpLevel2(Channel &channel) { value += channel.opExtraLevel1; value += channel.opExtraLevel2; - value += channel.opExtraLevel3; + + uint16 level3 = (channel.opExtraLevel3 ^ 0x3F) * channel.volumeModifier; + if (level3) { + level3 += 0x3F; + level3 >>= 8; + } + + value += level3 ^ 0x3F; + + value = CLIP<int8>(value, 0, 0x3F); + + if (!channel.volumeModifier) + value = 0x3F; // Preserve the scaling level bits from opLevel2 @@ -1323,14 +1336,22 @@ int AdLibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 va Channel &channel2 = _channels[chan]; if (priority >= channel2.priority) { - _flagTrigger = 1; - _flags |= 8; + // We keep new tracks from being started for two further iterations of + // the callback. This assures the correct velocity is used for this + // program. + _programStartTimeout = 2; initChannel(channel2); channel2.priority = priority; channel2.dataptr = ptr; channel2.tempo = 0xFF; channel2.position = 0xFF; channel2.duration = 1; + + if (chan <= 5) + channel2.volumeModifier = _musicVolume; + else + channel2.volumeModifier = _sfxVolume; + unkOutput2(chan); } @@ -1911,32 +1932,6 @@ int AdLibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value #define COMMAND(x) { &AdLibDriver::x, #x } -void AdLibDriver::setupOpcodeList() { - static const OpcodeEntry opcodeList[] = { - COMMAND(snd_ret0x100), - COMMAND(snd_ret0x1983), - COMMAND(snd_initDriver), - COMMAND(snd_deinitDriver), - COMMAND(snd_setSoundData), - COMMAND(snd_unkOpcode1), - COMMAND(snd_startSong), - COMMAND(snd_isChannelPlaying), - COMMAND(snd_stopChannel), - COMMAND(snd_readByte), - COMMAND(snd_writeByte), - COMMAND(snd_getSoundTrigger), - COMMAND(snd_unkOpcode4), - COMMAND(snd_dummy), - COMMAND(snd_getNullvar4), - COMMAND(snd_setNullvar3), - COMMAND(snd_setFlag), - COMMAND(snd_clearFlag) - }; - - _opcodeList = opcodeList; - _opcodesEntries = ARRAYSIZE(opcodeList); -} - void AdLibDriver::setupParserOpcodeTable() { static const ParserOpcode parserOpcodeTable[] = { // 0 @@ -2266,13 +2261,12 @@ SoundAdLibPC::~SoundAdLibPC() { } bool SoundAdLibPC::init() { - _driver->callback(2); - _driver->callback(16, int(4)); + _driver->initDriver(); return true; } void SoundAdLibPC::process() { - uint8 trigger = _driver->callback(11); + int trigger = _driver->getSoundTrigger(); if (trigger < _numSoundTriggers) { int soundId = _soundTriggers[trigger]; @@ -2285,6 +2279,23 @@ void SoundAdLibPC::process() { } } +void SoundAdLibPC::updateVolumeSettings() { + bool mute = false; + if (ConfMan.hasKey("mute")) + mute = ConfMan.getBool("mute"); + + int newMusicVolume = mute ? 0 : ConfMan.getInt("music_volume"); + //newMusicVolume = (newMusicVolume * 145) / Audio::Mixer::kMaxMixerVolume + 110; + newMusicVolume = CLIP(newMusicVolume, 0, 255); + + int newSfxVolume = mute ? 0 : ConfMan.getInt("sfx_volume"); + //newSfxVolume = (newSfxVolume * 200) / Audio::Mixer::kMaxMixerVolume + 55; + newSfxVolume = CLIP(newSfxVolume, 0, 255); + + _driver->setMusicVolume(newMusicVolume); + _driver->setSfxVolume(newSfxVolume); +} + void SoundAdLibPC::playTrack(uint8 track) { if (_musicEnabled) { // WORKAROUND: There is a bug in the Kyra 1 "Pool of Sorrow" @@ -2301,13 +2312,13 @@ void SoundAdLibPC::playTrack(uint8 track) { } void SoundAdLibPC::haltTrack() { - playSoundEffect(0); - playSoundEffect(0); + play(0); + play(0); //_vm->_system->delayMillis(3 * 60); } bool SoundAdLibPC::isPlaying() const { - return _driver->callback(7, int(0)) != 0; + return _driver->isChannelPlaying(0); } void SoundAdLibPC::playSoundEffect(uint8 track) { @@ -2326,60 +2337,11 @@ void SoundAdLibPC::play(uint8 track) { if ((soundId == 0xFFFF && _v2) || (soundId == 0xFF && !_v2) || !_soundDataPtr) return; - // HACK: Since we might call this when the engines is paused (on game load via GMM) - // we must unpause the engine here, so this will work properly - - int pauseCount = 0; - while (_vm->isPaused()) { - ++pauseCount; - _vm->pauseEngine(false); - } - - while ((_driver->callback(16, 0) & 8)) { - // We call the system delay and not the game delay to avoid concurrency issues. - _vm->_system->delayMillis(10); - } - - while (pauseCount--) - _vm->pauseEngine(true); - - if (_sfxPlayingSound != -1) { - // Restore the sounds's normal values. - _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority)); - _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong)); - _sfxPlayingSound = -1; - } - - int chan = _driver->callback(9, soundId, int(0)); - - if (chan != 9) { - _sfxPlayingSound = soundId; - _sfxPriority = _driver->callback(9, soundId, int(1)); - _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3)); - - // In the cases I've seen, the mysterious fourth byte has been - // the parameter for the update_setExtraLevel3() callback. - // - // The extra level is part of the channels "total level", which - // is a six-bit value where larger values means softer volume. - // - // So what seems to be happening here is that sounds which are - // started by this function are given a slightly lower priority - // and a slightly higher (i.e. softer) extra level 3 than they - // would have if they were started from anywhere else. Strange. - - int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF; - newVal = -newVal + 63; - _driver->callback(10, soundId, int(3), newVal); - newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF; - _driver->callback(10, soundId, int(1), newVal); - } - - _driver->callback(6, soundId); + _driver->queueTrack(soundId); } void SoundAdLibPC::beginFadeOut() { - playSoundEffect(1); + play(1); } void SoundAdLibPC::loadSoundFile(uint file) { @@ -2409,7 +2371,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) { playSoundEffect(0); playSoundEffect(0); - _driver->callback(8, int(-1)); + _driver->stopAllChannels(); _soundDataPtr = 0; int soundDataSize = fileSize; @@ -2434,7 +2396,7 @@ void SoundAdLibPC::internalLoadFile(Common::String file) { fileData = p = 0; fileSize = 0; - _driver->callback(4, _soundDataPtr); + _driver->setSoundData(_soundDataPtr); _soundFileLoaded = file; } diff --git a/engines/kyra/sound_adlib.h b/engines/kyra/sound_adlib.h index c09fec997e..923a4cb75f 100644 --- a/engines/kyra/sound_adlib.h +++ b/engines/kyra/sound_adlib.h @@ -62,22 +62,23 @@ public: SoundAdLibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer); ~SoundAdLibPC(); - kType getMusicType() const { return kAdLib; } + virtual kType getMusicType() const { return kAdLib; } - bool init(); - void process(); + virtual bool init(); + virtual void process(); - void loadSoundFile(uint file); - void loadSoundFile(Common::String file); - void loadSoundFile(const uint8 *soundData, int dataSize) {} + virtual void updateVolumeSettings(); - void playTrack(uint8 track); - void haltTrack(); - bool isPlaying() const; + virtual void loadSoundFile(uint file); + virtual void loadSoundFile(Common::String file); - void playSoundEffect(uint8 track); + virtual void playTrack(uint8 track); + virtual void haltTrack(); + virtual bool isPlaying() const; - void beginFadeOut(); + virtual void playSoundEffect(uint8 track); + + virtual void beginFadeOut(); private: void internalLoadFile(Common::String file); @@ -92,9 +93,6 @@ private: Common::String _soundFileLoaded; - uint8 _sfxPriority; - uint8 _sfxFourthByteOfSong; - int _numSoundTriggers; const int *_soundTriggers; diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp index efa844968d..968488eef3 100644 --- a/engines/kyra/sound_lol.cpp +++ b/engines/kyra/sound_lol.cpp @@ -98,12 +98,12 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) { _speechList = newSpeechList; _activeVoiceFileTotalTime = 0; - for (SpeechList::iterator i = _speechList.begin(); i != _speechList.end(); ++i) { + for (SpeechList::iterator i = _speechList.begin(); i != _speechList.end();) { // Just in case any file loading failed: Remove the bad streams here. if (!*i) i = _speechList.erase(i); else - _activeVoiceFileTotalTime += (*i)->getLength().msecs(); + _activeVoiceFileTotalTime += (*i++)->getLength().msecs(); } _sound->playVoiceStream(*_speechList.begin(), &_speechHandle); |