diff options
Diffstat (limited to 'engines')
46 files changed, 1379 insertions, 1202 deletions
diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp index d5c7df0e55..2d22630381 100644 --- a/engines/lastexpress/debug.cpp +++ b/engines/lastexpress/debug.cpp @@ -44,6 +44,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -793,7 +795,7 @@ bool Debugger::cmdFight(int argc, const char **argv) { restoreArchive(); // Stop audio and restore scene - getSound()->stopAllSound(); + getSoundQueue()->stopAllSound(); clearBg(GraphicsManager::kBackgroundAll); @@ -925,7 +927,7 @@ bool Debugger::cmdBeetle(int argc, const char **argv) { restoreArchive(); // Stop audio and restore scene - getSound()->stopAllSound(); + getSoundQueue()->stopAllSound(); clearBg(GraphicsManager::kBackgroundAll); diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp index 112edec9af..6fcadcfa54 100644 --- a/engines/lastexpress/entities/abbot.cpp +++ b/engines/lastexpress/entities/abbot.cpp @@ -34,6 +34,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -1409,7 +1411,7 @@ IMPLEMENT_FUNCTION(43, Abbot, function43) setup_playSound("Abb4002"); break; } else { - if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSound()->isBuffered(kEntityBoutarel) || !params->param4) + if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSoundQueue()->isBuffered(kEntityBoutarel) || !params->param4) params->param4 = (uint)getState()->time + 450; if (params->param4 < getState()->time) { @@ -1754,7 +1756,7 @@ IMPLEMENT_FUNCTION(49, Abbot, pickBomb) break; case kActionKnock: - if (!getSound()->isBuffered("LIB012", true)) + if (!getSoundQueue()->isBuffered("LIB012", true)) getSound()->playSound(kEntityPlayer, "LIB012"); break; diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp index d794cc8520..2eb3a9ec85 100644 --- a/engines/lastexpress/entities/anna.cpp +++ b/engines/lastexpress/entities/anna.cpp @@ -34,6 +34,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -312,7 +314,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12) params->param4 = 0; params->param5 = 0; } else { - getSound()->removeFromQueue(kEntityAnna); + getSoundQueue()->removeFromQueue(kEntityAnna); getObjects()->update(kObjectCompartmentF, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal); getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorNormal, kCursorNormal); @@ -323,7 +325,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12) break; case kActionOpenDoor: - getSound()->removeFromQueue(kEntityAnna); + getSoundQueue()->removeFromQueue(kEntityAnna); setCallback(3); setup_playSound("LIB013"); break; @@ -339,8 +341,8 @@ IMPLEMENT_FUNCTION(12, Anna, function12) getEntities()->drawSequenceLeft(kEntityAnna, "418C"); - if (getSound()->isBuffered(kEntityAnna)) - getSound()->processEntry(kEntityAnna); + if (getSoundQueue()->isBuffered(kEntityAnna)) + getSoundQueue()->processEntry(kEntityAnna); getSound()->playSound(kEntityAnna, "ANN2135A"); break; @@ -379,7 +381,7 @@ IMPLEMENT_FUNCTION(12, Anna, function12) break; case 3: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { setCallback(4); setup_playSound("MAX1120"); break; @@ -503,7 +505,7 @@ IMPLEMENT_FUNCTION_IS(15, Anna, function15, TimeValue) break; case 1: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { setCallback(2); setup_playSound("MAX1120"); break; @@ -1456,7 +1458,7 @@ label_callback_1: case 2: case 3: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { setCallback(4); setup_playSound("MAX1120"); break; @@ -1521,8 +1523,8 @@ IMPLEMENT_FUNCTION(35, Anna, function35) case kActionKnock: case kActionOpenDoor: - if (getSound()->isBuffered(kEntityAnna)) - getSound()->processEntry(kEntityAnna); + if (getSoundQueue()->isBuffered(kEntityAnna)) + getSoundQueue()->processEntry(kEntityAnna); if (savepoint.action == kActionKnock) getSound()->playSound(kEntityPlayer, "LIB012"); @@ -1564,8 +1566,8 @@ IMPLEMENT_FUNCTION(35, Anna, function35) break; case kAction226031488: - if (getSound()->isBuffered(kEntityAnna)) - getSound()->processEntry(kEntityAnna); + if (getSoundQueue()->isBuffered(kEntityAnna)) + getSoundQueue()->processEntry(kEntityAnna); getSavePoints()->push(kEntityAnna, kEntityMax, kAction71277948); break; @@ -1844,7 +1846,7 @@ IMPLEMENT_FUNCTION(41, Anna, function41) case 1: case 2: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { setCallback(3); setup_playSound("MAX1120"); break; @@ -2090,7 +2092,7 @@ IMPLEMENT_FUNCTION(48, Anna, function48) break; if (params->param3 != kTimeInvalid && getState()->time > kTime1969200) { - UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSound()->isBuffered(kEntityBoutarel)), params->param3, 150) + UPDATE_PARAM_PROC_TIME(kTime1983600, (!getEntities()->isInRestaurant(kEntityPlayer) || getSoundQueue()->isBuffered(kEntityBoutarel)), params->param3, 150) setCallback(3); setup_playSound("Aug3007A"); break; @@ -2481,7 +2483,7 @@ IMPLEMENT_FUNCTION(53, Anna, function53) break; case 1: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { setCallback(2); setup_playSound("MAX1120"); break; @@ -2620,7 +2622,7 @@ IMPLEMENT_FUNCTION(54, Anna, function54) break; case 1: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { setCallback(2); setup_playSound("MAX1120"); break; @@ -2789,7 +2791,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57) break; case 4: - if (getSound()->isBuffered(kEntityAugust)) { + if (getSoundQueue()->isBuffered(kEntityAugust)) { setCallback(4); setup_updateFromTime(75); } else { @@ -2817,7 +2819,7 @@ IMPLEMENT_FUNCTION(57, Anna, function57) case kAction123712592: getEntities()->drawSequenceLeft(kEntityAnna, "628Af"); - if (getSound()->isBuffered(kEntityAugust)) { + if (getSoundQueue()->isBuffered(kEntityAugust)) { setCallback(4); setup_updateFromTime(75); } else { @@ -3158,8 +3160,8 @@ IMPLEMENT_FUNCTION(63, Anna, function63) // Anna will get killed... case kAction272177921: - if (getSound()->isBuffered("MUS012")) - getSound()->processEntry("MUS012"); + if (getSoundQueue()->isBuffered("MUS012")) + getSoundQueue()->processEntry("MUS012"); setCallback(1); setup_savegame(kSavegameTypeEvent, kEventAnnaKilled); @@ -3935,8 +3937,8 @@ IMPLEMENT_FUNCTION(80, Anna, function80) break; case 1: - if (getSound()->isBuffered(kEntityAnna)) - getSound()->processEntry(kEntityAnna); + if (getSoundQueue()->isBuffered(kEntityAnna)) + getSoundQueue()->processEntry(kEntityAnna); getAction()->playAnimation(kEventKronosBringFirebird); getScenes()->loadSceneFromItem(kItemFirebird); @@ -3951,8 +3953,8 @@ IMPLEMENT_FUNCTION(80, Anna, function80) case 3: getProgress().isEggOpen = true; - if (getSound()->isBuffered(kEntityAnna)) - getSound()->processEntry(kEntityAnna); + if (getSoundQueue()->isBuffered(kEntityAnna)) + getSoundQueue()->processEntry(kEntityAnna); getAction()->playAnimation(kEventKronosOpenFirebird); getScenes()->loadSceneFromPosition(kCarRestaurant, 3); diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp index fbd50d64fb..44dd3eb579 100644 --- a/engines/lastexpress/entities/august.cpp +++ b/engines/lastexpress/entities/august.cpp @@ -36,6 +36,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -1427,7 +1429,7 @@ IMPLEMENT_FUNCTION(29, August, function29) if (getState()->time < kTime1134000) { if (!getEntities()->isInRestaurant(kEntityPlayer) - || getSound()->isBuffered("MRB1076") || getSound()->isBuffered("MRB1078") || getSound()->isBuffered("MRB1078A")) + || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A")) params->param3 = (uint)getState()->time + 225; if (params->param3 > getState()->time) @@ -1762,7 +1764,7 @@ IMPLEMENT_FUNCTION(34, August, function34) break; case kActionNone: - if (!getSound()->isBuffered(kEntityAugust) && getProgress().field_18 != 4) + if (!getSoundQueue()->isBuffered(kEntityAugust) && getProgress().field_18 != 4) getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring break; @@ -2183,7 +2185,7 @@ IMPLEMENT_FUNCTION_III(42, August, function42, CarIndex, EntityPosition, bool) break; case kActionExcuseMe: - if (!getSound()->isBuffered(kEntityAugust)) + if (!getSoundQueue()->isBuffered(kEntityAugust)) getSound()->excuseMe(kEntityAugust); break; @@ -3343,7 +3345,7 @@ IMPLEMENT_FUNCTION(65, August, function65) getObjects()->update(kObjectCompartment3, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand); - if (!getSound()->isBuffered(kEntityAugust)) + if (!getSoundQueue()->isBuffered(kEntityAugust)) getSound()->playSound(kEntityAugust, "AUG1057"); // August snoring break; } @@ -3504,9 +3506,9 @@ IMPLEMENT_FUNCTION(69, August, unhookCars) break; case kActionDefault: - getSound()->processEntries(); - if (getSound()->isBuffered("ARRIVE")) - getSound()->removeFromQueue("ARRIVE"); + getSoundQueue()->processEntries(); + if (getSoundQueue()->isBuffered("ARRIVE")) + getSoundQueue()->removeFromQueue("ARRIVE"); setCallback(1); setup_savegame(kSavegameTypeEvent, kEventAugustUnhookCarsBetrayal); @@ -3516,7 +3518,7 @@ IMPLEMENT_FUNCTION(69, August, unhookCars) if (getCallback() == 1) { getAction()->playAnimation(getProgress().field_C ? kEventAugustUnhookCarsBetrayal : kEventAugustUnhookCars); getEntities()->clearSequences(kEntityAugust); - getSound()->resetState(); + getSoundQueue()->resetState(); getSound()->playSound(kEntityPlayer, "MUS050"); getScenes()->loadSceneFromPosition(kCarRestaurant, 85, 1); getSavePoints()->pushAll(kEntityAugust, kActionProceedChapter5); diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp index db7761784f..cf5d286d64 100644 --- a/engines/lastexpress/entities/boutarel.cpp +++ b/engines/lastexpress/entities/boutarel.cpp @@ -32,6 +32,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -941,7 +943,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29) if (getEntities()->isInRestaurant(kEntityAnna) && getEntities()->isInRestaurant(kEntityAugust) - && !getSound()->isBuffered(kEntityBoutarel) + && !getSoundQueue()->isBuffered(kEntityBoutarel) && params->param3 != kTimeInvalid) { if (getState()->time <= kTime1998000) diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp index d4425ada43..53d89e9699 100644 --- a/engines/lastexpress/entities/chapters.cpp +++ b/engines/lastexpress/entities/chapters.cpp @@ -65,6 +65,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -164,16 +166,16 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End) break; case kActionKnock: - if (!getSound()->isBuffered("LIB012", true)) + if (!getSoundQueue()->isBuffered("LIB012", true)) getSound()->playSound(kEntityPlayer, "LIB012"); break; case kActionOpenDoor: if (params->param1) { getEntities()->clearSequences(kEntityChapters); - getSound()->processEntry(kEntityChapters); + getSoundQueue()->processEntry(kEntityChapters); getSound()->playSound(kEntityPlayer, "LIB014"); - getSound()->resetState(); + getSoundQueue()->resetState(); ENTITY_PARAM(0, 4) = 7; @@ -194,7 +196,7 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End) getSound()->playSound(kEntityPlayer, "LIB014"); getSound()->playSound(kEntityPlayer, "LIB015", kFlagDefault, 15); - if (!getSound()->isBuffered(kEntityChapters)) + if (!getSoundQueue()->isBuffered(kEntityChapters)) getSound()->playSound(kEntityChapters, "MUS009", kFlagDefault); getScenes()->loadSceneFromPosition(kCarLocomotive, 38); @@ -241,42 +243,42 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End) RESET_ENTITY_STATE(kEntityHadija, Alouan, setup_function12); if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; } - getSound()->processEntries(); + getSoundQueue()->processEntries(); - if (getSound()->isBuffered("CON1505")) - getSound()->processEntry("CON1505"); + if (getSoundQueue()->isBuffered("CON1505")) + getSoundQueue()->processEntry("CON1505"); - if (getSound()->isBuffered("AUG1057")) - getSound()->processEntry("AUG1057"); + if (getSoundQueue()->isBuffered("AUG1057")) + getSoundQueue()->processEntry("AUG1057"); - if (getSound()->isBuffered("ZFX1005")) - getSound()->processEntry("ZFX1005"); + if (getSoundQueue()->isBuffered("ZFX1005")) + getSoundQueue()->processEntry("ZFX1005"); - if (getSound()->isBuffered("ZFX1006")) - getSound()->processEntry("ZFX1006"); + if (getSoundQueue()->isBuffered("ZFX1006")) + getSoundQueue()->processEntry("ZFX1006"); - if (getSound()->isBuffered("ZFX1007")) - getSound()->processEntry("ZFX1007"); + if (getSoundQueue()->isBuffered("ZFX1007")) + getSoundQueue()->processEntry("ZFX1007"); - if (getSound()->isBuffered("ZFX1007A")) - getSound()->processEntry("ZFX1007A"); + if (getSoundQueue()->isBuffered("ZFX1007A")) + getSoundQueue()->processEntry("ZFX1007A"); - if (getSound()->isBuffered("ZFX1007B")) - getSound()->processEntry("ZFX1007B"); + if (getSoundQueue()->isBuffered("ZFX1007B")) + getSoundQueue()->processEntry("ZFX1007B"); getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault); getInventory()->unselectItem(); // FIXME add event pump ? - while (getSound()->isBuffered("MUS008")) - getSound()->updateQueue(); + while (getSoundQueue()->isBuffered("MUS008")) + getSoundQueue()->updateQueue(); getProgress().field_84 = true; @@ -301,7 +303,7 @@ IMPLEMENT_FUNCTION(6, Chapters, chapter1End) if (params->param2 >= 3) { - if (!getSound()->isBuffered("LIB031", true)) + if (!getSoundQueue()->isBuffered("LIB031", true)) getSound()->playSound(kEntityPlayer, "LIB031"); if (params->param2 == 3) { @@ -319,7 +321,7 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init) return; getProgress().chapter = kChapter1; - getSound()->resetState(); + getSoundQueue()->resetState(); getState()->time = kTimeChapter1; getState()->timeDelta = 0; @@ -385,7 +387,7 @@ IMPLEMENT_FUNCTION_END ////////////////////////////////////////////////////////////////////////// #define PLAY_STEAM() { \ - getSound()->resetState(); \ + getSoundQueue()->resetState(); \ getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4)); \ ENTITY_PARAM(0, 2) = 0; \ } @@ -563,7 +565,7 @@ label_chapter1_next: } if (ENTITY_PARAM(0, 3)) { - getSound()->resetState(); + getSoundQueue()->resetState(); ENTITY_PARAM(0, 3) = 0; if (params->param4) { @@ -694,7 +696,7 @@ IMPLEMENT_FUNCTION(9, Chapters, chapter1Next) if (savepoint.action == kActionDefault) { // Reset sound cache if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; } @@ -702,8 +704,8 @@ IMPLEMENT_FUNCTION(9, Chapters, chapter1Next) getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault); getInventory()->unselectItem(); - while (getSound()->isBuffered("MUS008")) - getSound()->updateQueue(); + while (getSoundQueue()->isBuffered("MUS008")) + getSoundQueue()->updateQueue(); setup_chapter2(); } @@ -790,7 +792,7 @@ IMPLEMENT_FUNCTION(11, Chapters, chapter2Init) // Reset sound cache if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; } @@ -874,7 +876,7 @@ IMPLEMENT_FUNCTION(14, Chapters, chapter3Init) getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue); if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; } @@ -987,7 +989,7 @@ label_callback_8: } } - getSound()->resetState(); + getSoundQueue()->resetState(); getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4)); ENTITY_PARAM(0, 2) = 0; @@ -998,7 +1000,7 @@ label_callback_8: } if (ENTITY_PARAM(0, 3)) { - getSound()->resetState(); + getSoundQueue()->resetState(); ENTITY_PARAM(0, 3) = 0; } break; @@ -1150,8 +1152,8 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init) if (savepoint.action != kActionDefault) return; - getSound()->processEntries(); - getSound()->resetState(); + getSoundQueue()->processEntries(); + getSoundQueue()->resetState(); getProgress().isTrainRunning = true; @@ -1177,7 +1179,7 @@ IMPLEMENT_FUNCTION(18, Chapters, chapter4Init) getObjects()->update(kObject107, kEntityPlayer, kObjectLocation3, kCursorKeepValue, kCursorKeepValue); if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; } @@ -1319,7 +1321,7 @@ label_callback_4: } if (ENTITY_PARAM(0, 3)) { - getSound()->resetState(); + getSoundQueue()->resetState(); ENTITY_PARAM(0, 3) = 0; } else if (!params->param2 && !params->param3) { getSound()->playSound(kEntityChapters, "ZFX1001"); @@ -1356,17 +1358,17 @@ label_callback_4: goto label_callback_4; case 5: - if (getSound()->isBuffered(kEntityChapters)) - getSound()->removeFromQueue(kEntityChapters); + if (getSoundQueue()->isBuffered(kEntityChapters)) + getSoundQueue()->removeFromQueue(kEntityChapters); getAction()->playAnimation(kEventTrainExplosionBridge); getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneNone, true); break; case 6: - getSound()->processEntries(); + getSoundQueue()->processEntries(); getAction()->playAnimation(kEventTylerCastleDream); - getSound()->resetState(); + getSoundQueue()->resetState(); getProgress().field_18 = 1; @@ -1465,7 +1467,7 @@ label_callback_4: params->param1 = 1; if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; @@ -1474,8 +1476,8 @@ label_callback_4: getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault); getInventory()->unselectItem(); - while (getSound()->isBuffered("MUS008")) - getSound()->updateQueue(); + while (getSoundQueue()->isBuffered("MUS008")) + getSoundQueue()->updateQueue(); if (getInventory()->hasItem(kItemBomb)) { RESET_ENTITY_STATE(kEntityAlexei, Alexei, setup_function47); @@ -1522,8 +1524,8 @@ label_callback_4: case kAction191001984: getState()->time = kTime2520000; - if (getSound()->isBuffered(kEntityChapters)) - getSound()->removeFromQueue(kEntityChapters); + if (getSoundQueue()->isBuffered(kEntityChapters)) + getSoundQueue()->removeFromQueue(kEntityChapters); getEntities()->clearSequences(kEntityChapters); getInventory()->removeItem(kItemTelegram); @@ -1535,8 +1537,8 @@ label_callback_4: break; case kAction201959744: - if (getSound()->isBuffered(kEntityChapters)) - getSound()->removeFromQueue(kEntityChapters); + if (getSoundQueue()->isBuffered(kEntityChapters)) + getSoundQueue()->removeFromQueue(kEntityChapters); getSound()->playSound(kEntityTrain, "ZFX4001", kFlagDefault); @@ -1644,7 +1646,7 @@ IMPLEMENT_FUNCTION(21, Chapters, chapter5Init) getObjects()->updateLocation2(kObjectRestaurantCar, kObjectLocation2); if (ENTITY_PARAM(0, 2) || ENTITY_PARAM(0, 3)) { - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); ENTITY_PARAM(0, 2) = 0; ENTITY_PARAM(0, 3) = 0; } @@ -1675,7 +1677,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler) if (!getProgress().isNightTime) { getSound()->playSound(kEntityChapters, "ARRIVE", kFlag8); - getSound()->processEntries(); + getSoundQueue()->processEntries(); } } @@ -1684,7 +1686,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler) if (!getEvent(kEventLocomotiveMilosDay) && !getEvent(kEventLocomotiveMilosNight)) { getSound()->playSound(kEntityChapters, "ARRIVE", kFlag8); - getSound()->processEntries(); + getSoundQueue()->processEntries(); } } break; @@ -1713,8 +1715,8 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler) getProgress().isNightTime = true; getState()->time = kTime2916000; - if (getSound()->isBuffered(kEntityChapters)) - getSound()->removeFromQueue(kEntityChapters); + if (getSoundQueue()->isBuffered(kEntityChapters)) + getSoundQueue()->removeFromQueue(kEntityChapters); break; } IMPLEMENT_FUNCTION_END @@ -1730,7 +1732,7 @@ void Chapters::enterExitStation(const SavePoint &savepoint, bool isEnteringStati return; } - getSound()->removeFromQueue(kEntityChapters); + getSoundQueue()->removeFromQueue(kEntityChapters); if (!ENTITY_PARAM(0, 2)) { if (ENTITY_PARAM(0, 3)) @@ -1798,7 +1800,7 @@ void Chapters::enterExitHelper(bool isEnteringStation) { EXPOSE_PARAMS(EntityData::EntityParametersSIIS); getSound()->playSound(kEntityChapters, isEnteringStation ? "ARRIVE" : "DEPART", kFlag8); - getSound()->processEntries(); + getSoundQueue()->processEntries(); getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand); getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, isEnteringStation ? kCursorNormal : kCursorHand); diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp index 336f911800..cd8fbfd8ff 100644 --- a/engines/lastexpress/entities/cooks.cpp +++ b/engines/lastexpress/entities/cooks.cpp @@ -29,6 +29,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -101,7 +103,7 @@ IMPLEMENT_FUNCTION(3, Cooks, function3) if (getEntities()->isPlayerPosition(kCarRestaurant, 46)) { getEntities()->drawSequenceLeft(kEntityCooks, "308D"); - if (!getSound()->isBuffered(kEntityCooks)) { + if (!getSoundQueue()->isBuffered(kEntityCooks)) { if (params->param1) { if (!getEntities()->hasValidFrame(kEntityCooks)) { getSound()->playSound(kEntityCooks, "LIB015"); @@ -187,7 +189,7 @@ IMPLEMENT_FUNCTION(4, Cooks, function4) if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) { getEntities()->drawSequenceLeft(kEntityCooks, "308D"); - if (!getSound()->isBuffered(kEntityCooks)) { + if (!getSoundQueue()->isBuffered(kEntityCooks)) { if (params->param1) { if (!getEntities()->hasValidFrame(kEntityCooks)) { getSound()->playSound(kEntityCooks, "LIB015"); diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp index 0733a4c984..fea08f4611 100644 --- a/engines/lastexpress/entities/coudert.cpp +++ b/engines/lastexpress/entities/coudert.cpp @@ -32,6 +32,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -314,7 +316,7 @@ IMPLEMENT_FUNCTION_II(9, Coudert, updateEntity, CarIndex, EntityPosition) case kActionExcuseMeCath: if (getData()->clothes == kClothes1) getSound()->playSound(kEntityPlayer, "ZFX1003", getSound()->getSoundFlag(kEntityCoudert)); - else if (!getSound()->isBuffered(kEntityCoudert)) + else if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityPlayer, "JAC1112", getSound()->getSoundFlag(kEntityCoudert)); break; @@ -409,7 +411,7 @@ IMPLEMENT_FUNCTION_I(12, Coudert, excuseMe, EntityIndex) if (savepoint.action != kActionDefault) return; - if (getSound()->isBuffered(kEntityCoudert)) { + if (getSoundQueue()->isBuffered(kEntityCoudert)) { CALLBACK_ACTION(); return; } @@ -823,7 +825,7 @@ IMPLEMENT_FUNCTION(18, Coudert, function18) getScenes()->loadSceneFromItemPosition(kItem5); if (getEntities()->isPlayerPosition(kCarRedSleeping, 68)) { - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, "JAC1111"); getScenes()->loadSceneFromPosition(kCarRedSleeping, 25); @@ -1642,7 +1644,7 @@ IMPLEMENT_FUNCTION_I(31, Coudert, function31, uint32) break; case 1: - if (getSound()->isBuffered(kEntityCoudert)) { + if (getSoundQueue()->isBuffered(kEntityCoudert)) { getEntities()->drawSequenceLeft(kEntityCoudert, "627K"); } else { setCallback(2); @@ -1929,7 +1931,7 @@ IMPLEMENT_FUNCTION_I(35, Coudert, function35, bool) break; case 1: - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, "Ann3124"); if (params->param1) @@ -2008,8 +2010,8 @@ IMPLEMENT_FUNCTION(37, Coudert, function37) break; case kActionDefault: - if (getSound()->isBuffered(kEntityCoudert)) - getSound()->processEntry(kEntityCoudert); + if (getSoundQueue()->isBuffered(kEntityCoudert)) + getSoundQueue()->processEntry(kEntityCoudert); if (ENTITY_PARAM(0, 7)) { getData()->entityPosition = kPosition_8200; @@ -2268,7 +2270,7 @@ label_callback_8: } label_callback_9: - if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityCoudert)) + if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, rnd(2) ? "JAC1065" : "JAC1065A"); if (getState()->time > kTime1107000 && !ENTITY_PARAM(0, 1) && !getEvent(kEventVassiliSeizure)) { @@ -3019,7 +3021,7 @@ IMPLEMENT_FUNCTION(46, Coudert, function46) // Fallback to next case case 7: - if (getSound()->isBuffered(kEntityCoudert)) { + if (getSoundQueue()->isBuffered(kEntityCoudert)) { setCallback(7); setup_updateFromTime(75); } else { @@ -3088,7 +3090,7 @@ IMPLEMENT_FUNCTION_I(47, Coudert, function47, bool) // Fallback to next case case 4: - if (getSound()->isBuffered(kEntityCoudert)) { + if (getSoundQueue()->isBuffered(kEntityCoudert)) { setCallback(4); setup_updateFromTime(225); } else { diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp index 86b6820499..6bbe740730 100644 --- a/engines/lastexpress/entities/francois.cpp +++ b/engines/lastexpress/entities/francois.cpp @@ -30,6 +30,8 @@ #include "lastexpress/game/savepoint.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -275,7 +277,7 @@ IMPLEMENT_FUNCTION_I(11, Francois, function11, TimeValue) break; case kActionNone: - if (!getSound()->isBuffered(kEntityFrancois)) { + if (!getSoundQueue()->isBuffered(kEntityFrancois)) { UPDATE_PARAM_PROC(CURRENT_PARAM(1, 1), getState()->timeTicks, params->param6) switch (rnd(7)) { @@ -370,8 +372,8 @@ label_callback: getData()->field_4A3 = 30; getData()->inventoryItem = kItemNone; - if (getSound()->isBuffered(kEntityFrancois)) - getSound()->processEntry(kEntityFrancois); + if (getSoundQueue()->isBuffered(kEntityFrancois)) + getSoundQueue()->processEntry(kEntityFrancois); setCallback(4); setup_updateEntity(kCarRedSleeping, kPosition_5790); @@ -381,8 +383,8 @@ label_callback: case kAction1: getData()->inventoryItem = kItemNone; - if (getSound()->isBuffered(kEntityFrancois)) - getSound()->processEntry(kEntityFrancois); + if (getSoundQueue()->isBuffered(kEntityFrancois)) + getSoundQueue()->processEntry(kEntityFrancois); setCallback(6); setup_savegame(kSavegameTypeEvent, kEventFrancoisWhistle); diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp index db71981b60..6c73784b21 100644 --- a/engines/lastexpress/entities/kahina.cpp +++ b/engines/lastexpress/entities/kahina.cpp @@ -32,6 +32,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -607,8 +609,8 @@ label_callback_3: break; if (getEvent(kEventKahinaAskSpeakFirebird)) { - if (getSound()->isBuffered(kEntityKahina)) - getSound()->processEntry(kEntityKahina); + if (getSoundQueue()->isBuffered(kEntityKahina)) + getSoundQueue()->processEntry(kEntityKahina); if (savepoint.action == kActionKnock) getSound()->playSound(kEntityPlayer, "LIB012"); @@ -1163,8 +1165,8 @@ IMPLEMENT_FUNCTION(24, Kahina, function24) case 1: if (ENTITY_PARAM(0, 2)) { getEntities()->clearSequences(kEntityKahina); - if (getSound()->isBuffered(kEntityKahina)) - getSound()->processEntry(kEntityKahina); + if (getSoundQueue()->isBuffered(kEntityKahina)) + getSoundQueue()->processEntry(kEntityKahina); getProgress().field_44 = 0; @@ -1198,8 +1200,8 @@ IMPLEMENT_FUNCTION(24, Kahina, function24) case kAction137503360: getEntities()->clearSequences(kEntityKahina); - if (getSound()->isBuffered(kEntityKahina)) - getSound()->processEntry(kEntityKahina); + if (getSoundQueue()->isBuffered(kEntityKahina)) + getSoundQueue()->processEntry(kEntityKahina); getProgress().field_44 = 0; diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp index 5afc52fe3d..06ebd54694 100644 --- a/engines/lastexpress/entities/kronos.cpp +++ b/engines/lastexpress/entities/kronos.cpp @@ -39,6 +39,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -216,7 +218,7 @@ IMPLEMENT_FUNCTION(11, Kronos, function11) case kActionDefault: getData()->entityPosition = kPosition_7000; - if (!getSound()->isBuffered(kEntityKronos)) + if (!getSoundQueue()->isBuffered(kEntityKronos)) getSound()->playSound(kEntityKronos, "KRO1001"); break; } @@ -457,7 +459,7 @@ IMPLEMENT_FUNCTION(19, Kronos, function19) case 2: getAction()->playAnimation(kEventConcertStart); - getSound()->setupEntry(kSoundType7, kEntityKronos); + getSoundQueue()->setupEntry(kSoundType7, kEntityKronos); getScenes()->loadSceneFromPosition(kCarKronos, 83); RESET_ENTITY_STATE(kEntityRebecca, Rebecca, setup_function39); @@ -480,7 +482,7 @@ IMPLEMENT_FUNCTION(20, Kronos, function20) break; case kActionNone: - params->param5 = getSound()->getEntryTime(kEntityKronos)* 2; + params->param5 = getSoundQueue()->getEntryTime(kEntityKronos)* 2; if (params->param6 < ARRAYSIZE(concertData) && params->param5 > concertData[params->param6].time) { @@ -560,8 +562,8 @@ IMPLEMENT_FUNCTION(20, Kronos, function20) case 3: getAction()->playAnimation(kEventCathFallingAsleep); - while (getSound()->isBuffered("1919.LNK")) - getSound()->updateQueue(); + while (getSoundQueue()->isBuffered("1919.LNK")) + getSoundQueue()->updateQueue(); getAction()->playAnimation(kEventCathWakingUp); getScenes()->processScene(); @@ -746,7 +748,7 @@ IMPLEMENT_FUNCTION(22, Kronos, function22) case kActionKnock: case kActionOpenDoor: - if (!getSound()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true)) + if (!getSoundQueue()->isBuffered(savepoint.action == kActionKnock ? "LIB012" : "LIB013", true)) getSound()->playSound(kEntityPlayer, savepoint.action == kActionKnock ? "LIB012" : "LIB013"); if (getEvent(kEventConcertLeaveWithBriefcase)) diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp index f9ae741d0e..cb782854af 100644 --- a/engines/lastexpress/entities/mahmud.cpp +++ b/engines/lastexpress/entities/mahmud.cpp @@ -34,6 +34,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -157,7 +159,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool) case kActionEndSound: case kActionDrawScene: - if (!getSound()->isBuffered(kEntityMahmud)) { + if (!getSoundQueue()->isBuffered(kEntityMahmud)) { EntityPosition position = getEntityData(kEntityPlayer)->entityPosition; if (position < kPosition_1500 || position >= kPosition_5790 || (position > kPosition_4455 && params->param5 != 5)) { getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand); @@ -173,12 +175,12 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool) case kActionKnock: case kActionOpenDoor: - if (!getSound()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true)) + if (!getSoundQueue()->isBuffered((savepoint.action == kActionKnock) ? "LIB012" : "LIB013", true)) getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock) ? "LIB012" : "LIB013"); params->param5 = savepoint.param.intValue; - if (!getSound()->isBuffered(kEntityMahmud)) { + if (!getSoundQueue()->isBuffered(kEntityMahmud)) { params->param3++; switch(params->param3) { @@ -282,7 +284,7 @@ IMPLEMENT_FUNCTION(11, Mahmud, function11) case kActionOpenDoor: { getSound()->playSound(kEntityPlayer, (savepoint.action == kActionKnock ? "LIB012" : "LIB013")); - if (!getSound()->isBuffered(kEntityMahmud)) { + if (!getSoundQueue()->isBuffered(kEntityMahmud)) { params->param1++; getSound()->playSound(kEntityMahmud, (params->param1 == 1 ? "MAH1170E" : (params->param1 == 2 ? "MAH1173B" : "MAH1174"))); @@ -396,8 +398,8 @@ IMPLEMENT_FUNCTION(11, Mahmud, function11) break; case kAction123852928: - if (getSound()->isBuffered(kEntityMahmud)) - getSound()->processEntry(kEntityMahmud); + if (getSoundQueue()->isBuffered(kEntityMahmud)) + getSoundQueue()->processEntry(kEntityMahmud); getObjects()->update(kObjectCompartment5, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand); getObjects()->update(kObjectCompartment6, kEntityTrain, kObjectLocation3, kCursorHandKnock, kCursorHand); @@ -560,7 +562,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler) TIME_CHECK_CALLBACK(kTime1098000, params->param6, 1, setup_function13); - if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) { + if (!getSoundQueue()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) { params->param7 = 1; setCallback(2); @@ -636,7 +638,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler) params->param4 = 0; params->param5 = 0; - if (!getSound()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) { + if (!getSoundQueue()->isBuffered("HAR1104") && getState()->time > kTime1167300 && !params->param7) { params->param7 = 1; setCallback(2); setup_function12(); diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp index 12123ed04a..924f8f77aa 100644 --- a/engines/lastexpress/entities/max.cpp +++ b/engines/lastexpress/entities/max.cpp @@ -31,6 +31,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -91,7 +93,7 @@ IMPLEMENT_FUNCTION(6, Max, chapter12_handler) case kActionNone: UPDATE_PARAM(params->param2, getState()->time, params->param1); - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max1122"); params->param1 = 255 * (4 * rnd(20) + 40); @@ -108,7 +110,7 @@ IMPLEMENT_FUNCTION(6, Max, chapter12_handler) break; case kAction158007856: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { getSound()->playSound(kEntityMax, "Max1122"); params->param1 = 255 * (4 * rnd(20) + 40); } @@ -125,7 +127,7 @@ IMPLEMENT_FUNCTION(7, Max, function7) case kActionNone: UPDATE_PARAM(params->param2, getState()->time, params->param1) - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max1122"); params->param1 = 255 * (4 * rnd(20) + 40); @@ -137,8 +139,8 @@ IMPLEMENT_FUNCTION(7, Max, function7) getObjects()->update(kObjectCompartmentF, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal); getObjects()->update(kObject53, kEntityMax, kObjectLocation1, kCursorNormal, kCursorNormal); - if (getSound()->isBuffered(kEntityMax)) - getSound()->processEntry(kEntityMax); + if (getSoundQueue()->isBuffered(kEntityMax)) + getSoundQueue()->processEntry(kEntityMax); setCallback((savepoint.action == kActionKnock) ? 1 : 2); setup_playSound((savepoint.action == kActionKnock) ? "LIB012" : "LIB013"); @@ -156,7 +158,7 @@ IMPLEMENT_FUNCTION(7, Max, function7) break; case kActionDrawScene: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { if (getEntities()->isPlayerPosition(kCarRedSleeping, 56) || getEntities()->isPlayerPosition(kCarRedSleeping, 78)) getSound()->playSound(kEntityMax, "Max1120"); } @@ -197,7 +199,7 @@ IMPLEMENT_FUNCTION(7, Max, function7) break; case kAction158007856: - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { getSound()->playSound(kEntityMax, "Max1122"); params->param1 = 255 * (4 * rnd(20) + 40); } @@ -214,7 +216,7 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler) case kActionNone: UPDATE_PARAM(params->param3, getState()->time, params->param2); - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max3101"); params->param2 = 255 * (4 * rnd(20) + 40); @@ -228,8 +230,8 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler) break; } - if (getSound()->isBuffered(kEntityMax)) - getSound()->processEntry(kEntityMax); + if (getSoundQueue()->isBuffered(kEntityMax)) + getSoundQueue()->processEntry(kEntityMax); getAction()->playAnimation(kEventCathMaxLickHand); getScenes()->processScene(); @@ -247,7 +249,7 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler) getData()->location = kLocationInsideCompartment; getData()->car = kCarBaggage; - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max3101"); break; @@ -255,8 +257,8 @@ IMPLEMENT_FUNCTION(8, Max, chapter4Handler) if (getCallback() != 1) break; - if (getSound()->isBuffered(kEntityMax)) - getSound()->processEntry(kEntityMax); + if (getSoundQueue()->isBuffered(kEntityMax)) + getSoundQueue()->processEntry(kEntityMax); getSound()->playSound(kEntityPlayer, "LIB026"); getAction()->playAnimation(kEventCathMaxFree); @@ -392,7 +394,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler) UPDATE_PARAM(params->param3, getState()->time, params->param1); - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max1122"); params->param1 = 255 * (4 * rnd(20) + 40); @@ -424,7 +426,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler) if (params->param2) break; - if (!getSound()->isBuffered(kEntityMax)) { + if (!getSoundQueue()->isBuffered(kEntityMax)) { getSound()->playSound(kEntityMax, "Max1122"); params->param1 = 255 * (4 * rnd(20) + 40); } @@ -464,7 +466,7 @@ IMPLEMENT_FUNCTION(14, Max, freeFromCage) getData()->location = kLocationInsideCompartment; getData()->car = kCarBaggage; - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max1122"); break; @@ -476,17 +478,17 @@ IMPLEMENT_FUNCTION(14, Max, freeFromCage) break; case 1: - if (getSound()->isBuffered(kEntityMax)) - getSound()->removeFromQueue(kEntityMax); + if (getSoundQueue()->isBuffered(kEntityMax)) + getSoundQueue()->removeFromQueue(kEntityMax); getAction()->playAnimation(kEventCathMaxCage); - getSound()->setupEntry(kSoundType7, kEntityMax); + getSoundQueue()->setupEntry(kSoundType7, kEntityMax); getScenes()->processScene(); break; case 2: - if (getSound()->isBuffered(kEntityMax)) - getSound()->processEntry(kEntityMax); + if (getSoundQueue()->isBuffered(kEntityMax)) + getSoundQueue()->processEntry(kEntityMax); getSound()->playSound(kEntityPlayer, "LIB026"); getAction()->playAnimation(kEventCathMaxFree); @@ -523,7 +525,7 @@ IMPLEMENT_FUNCTION(15, Max, function15) getData()->location = kLocationOutsideCompartment; getData()->car = kCarRedSleeping; - if (!getSound()->isBuffered(kEntityMax)) + if (!getSoundQueue()->isBuffered(kEntityMax)) getSound()->playSound(kEntityMax, "Max3010"); setCallback(1); diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp index b99e344b20..464cc343bb 100644 --- a/engines/lastexpress/entities/mertens.cpp +++ b/engines/lastexpress/entities/mertens.cpp @@ -32,6 +32,8 @@ #include "lastexpress/game/state.h" #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -503,7 +505,7 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex) if (savepoint.action == kActionDefault) return; - if (getSound()->isBuffered(kEntityMertens)) { + if (getSoundQueue()->isBuffered(kEntityMertens)) { CALLBACK_ACTION(); return; } @@ -589,7 +591,7 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool) if (params->param2) params->param3 = 1; - if (!getSound()->isBuffered(kEntityMertens)) { + if (!getSoundQueue()->isBuffered(kEntityMertens)) { } @@ -1188,7 +1190,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22) break; case 5: - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playSound(kEntityMertens, "MAH1170I"); setCallback(6); @@ -1198,7 +1200,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22) case 6: getData()->location = kLocationInsideCompartment; getEntities()->clearSequences(kEntityMertens); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playSound(kEntityMertens, "MAH1172", kFlagInvalid, 225); setCallback(7); @@ -2300,7 +2302,7 @@ IMPLEMENT_FUNCTION_I(31, Mertens, function31, MertensActionType) break; case 1: - if (getSound()->isBuffered(kEntityMertens)) { + if (getSoundQueue()->isBuffered(kEntityMertens)) { getEntities()->drawSequenceLeft(kEntityMertens, "601J"); } else { setCallback(2); @@ -3017,7 +3019,7 @@ IMPLEMENT_FUNCTION(42, Mertens, function42) if (getState()->time <= kTime1188000) { if ((!getEntities()->isPlayerInCar(kCarGreenSleeping) && !getEntities()->isPlayerInCar(kCarRedSleeping)) - || getSound()->isBuffered("REB1205") + || getSoundQueue()->isBuffered("REB1205") || !getEntities()->isInsideCompartment(kEntityMmeBoutarel, kCarRedSleeping, kPosition_5790) || !params->param4) { params->param4 = (uint)getState()->time; @@ -3138,7 +3140,7 @@ label_callback_18: } label_callback_19: - if (ENTITY_PARAM(0, 1) && !getSound()->isBuffered(kEntityMertens)) { + if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityMertens)) { if (getProgress().field_18 != 4) getSound()->playSound(kEntityMertens, "CON1505"); } diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp index 68030b3be3..1526c281b2 100644 --- a/engines/lastexpress/entities/milos.cpp +++ b/engines/lastexpress/entities/milos.cpp @@ -36,6 +36,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -1577,8 +1579,8 @@ IMPLEMENT_FUNCTION(29, Milos, chapter4Handler) break; case kAction221683008: - if (getSound()->isBuffered(kEntityMilos)) - getSound()->processEntry(kEntityMilos); + if (getSoundQueue()->isBuffered(kEntityMilos)) + getSoundQueue()->processEntry(kEntityMilos); params->param1 = 1; getSavePoints()->push(kEntityMilos, kEntityCoudert, kAction123199584); @@ -1720,15 +1722,15 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler) break; case 2: - if (getSound()->isBuffered("MUS050")) - getSound()->processEntry("MUS050"); + if (getSoundQueue()->isBuffered("MUS050")) + getSoundQueue()->processEntry("MUS050"); - if (getSound()->isBuffered("ARRIVE")) - getSound()->removeFromQueue("ARRIVE"); + if (getSoundQueue()->isBuffered("ARRIVE")) + getSoundQueue()->removeFromQueue("ARRIVE"); - getSound()->processEntries(); + getSoundQueue()->processEntries(); getAction()->playAnimation(isNight() ? kEventLocomotiveMilosNight : kEventLocomotiveMilosDay); - getSound()->setupEntry(kSoundType7, kEntityMilos); + getSoundQueue()->setupEntry(kSoundType7, kEntityMilos); getScenes()->loadSceneFromPosition(kCarCoalTender, 1); break; @@ -1740,7 +1742,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler) case 4: getAction()->playAnimation(kEventLocomotiveRestartTrain); getAction()->playAnimation(kEventLocomotiveOldBridge); - getSound()->resetState(); + getSoundQueue()->resetState(); getState()->time = kTime2983500; setCallback(5); @@ -1783,7 +1785,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler) setup_savegame(kSavegameTypeEvent, kEventLocomotiveAnnaStopsTrain); } - getSound()->processEntry(kEntityMilos); + getSoundQueue()->processEntry(kEntityMilos); if (getState()->time < kTimeTrainStopped2) getState()->time = kTimeTrainStopped2; diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp index 78f2d2fb4b..1d4c52ca09 100644 --- a/engines/lastexpress/entities/mmeboutarel.cpp +++ b/engines/lastexpress/entities/mmeboutarel.cpp @@ -31,6 +31,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -399,7 +401,7 @@ IMPLEMENT_FUNCTION(13, MmeBoutarel, function13) break; case kActionNone: - if (!getSound()->isBuffered(kEntityMmeBoutarel) && params->param6 != kTimeInvalid) { + if (!getSoundQueue()->isBuffered(kEntityMmeBoutarel) && params->param6 != kTimeInvalid) { UPDATE_PARAM_PROC_TIME(params->param1, !getEntities()->isDistanceBetweenEntities(kEntityMmeBoutarel, kEntityPlayer, 2000), params->param6, 0) getObjects()->update(kObjectCompartmentD, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal); getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorNormal); @@ -883,8 +885,8 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler) if (getState()->time <= kTime2038500) { if (!getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param1 - || getSound()->isBuffered("FRA2012") - || getSound()->isBuffered("FRA2010") + || getSoundQueue()->isBuffered("FRA2012") + || getSoundQueue()->isBuffered("FRA2010") ||!params->param2) params->param2 = (uint)getState()->time; diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp index d4a7359511..8bbcf64e84 100644 --- a/engines/lastexpress/entities/pascale.cpp +++ b/engines/lastexpress/entities/pascale.cpp @@ -30,6 +30,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -201,7 +203,7 @@ IMPLEMENT_FUNCTION(10, Pascale, welcomeCath) break; case kActionNone: - if (params->param1 && !getSound()->isBuffered(kEntityPascale)) + if (params->param1 && !getSoundQueue()->isBuffered(kEntityPascale)) getEntities()->updatePositionExit(kEntityPascale, kCarRestaurant, 64); break; @@ -462,10 +464,10 @@ IMPLEMENT_FUNCTION(16, Pascale, serveTatianaVassili) getEntities()->drawSequenceLeft(kEntityPascale, "014B"); getEntities()->updatePositionEnter(kEntityPascale, kCarRestaurant, 67); - if (getSound()->isBuffered("TAT1069A")) - getSound()->processEntry("TAT1069A"); - else if (getSound()->isBuffered("TAT1069B")) - getSound()->processEntry("TAT1069B"); + if (getSoundQueue()->isBuffered("TAT1069A")) + getSoundQueue()->processEntry("TAT1069A"); + else if (getSoundQueue()->isBuffered("TAT1069B")) + getSoundQueue()->processEntry("TAT1069B"); setCallback(2); setup_playSound("TAT1066"); @@ -1213,7 +1215,7 @@ label_callback1: break; case kAction169750080: - if (getSound()->isBuffered(kEntityPascale)) { + if (getSoundQueue()->isBuffered(kEntityPascale)) { params->param4 = 1; } else { setCallback(7); diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp index 68a37b368d..6d1c5244f2 100644 --- a/engines/lastexpress/entities/rebecca.cpp +++ b/engines/lastexpress/entities/rebecca.cpp @@ -30,6 +30,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -511,7 +513,7 @@ IMPLEMENT_FUNCTION_I(20, Rebecca, function20, TimeValue) if (getProgress().chapter == kChapter1 && !ENTITY_PARAM(0, 3)) { if (params->param7 != kTimeInvalid && getState()->time > kTime1174500) { if (getState()->time <= kTime1183500) { - if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSound()->isBuffered("CON1210") || !params->param7) + if (!getEntities()->isDistanceBetweenEntities(kEntityRebecca, kEntityPlayer, 2000) || getSoundQueue()->isBuffered("CON1210") || !params->param7) params->param7 = (uint)(getState()->time); if (params->param7 >= getState()->time) diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp index bbaff5f1d9..6dcab7121e 100644 --- a/engines/lastexpress/entities/salko.cpp +++ b/engines/lastexpress/entities/salko.cpp @@ -33,6 +33,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -596,8 +598,8 @@ IMPLEMENT_FUNCTION(24, Salko, chapter5Handler) break; case 1: - if (getSound()->isBuffered("MUS050")) - getSound()->processEntry("MUS050"); + if (getSoundQueue()->isBuffered("MUS050")) + getSoundQueue()->processEntry("MUS050"); getAction()->playAnimation(kEventCathSalkoTrainTopFight); diff --git a/engines/lastexpress/entities/tables.cpp b/engines/lastexpress/entities/tables.cpp index da053c5871..702b636c31 100644 --- a/engines/lastexpress/entities/tables.cpp +++ b/engines/lastexpress/entities/tables.cpp @@ -29,6 +29,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -88,8 +90,8 @@ IMPLEMENT_FUNCTION_END ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION(5, Tables, chapter5) if (savepoint.action == kActionDefault) { - if (_id == kEntityTables2 && getSound()->isBuffered(kEntityTables2)) - getSound()->processEntry(kEntityTables2); + if (_id == kEntityTables2 && getSoundQueue()->isBuffered(kEntityTables2)) + getSoundQueue()->processEntry(kEntityTables2); setup_draw(); } @@ -113,21 +115,21 @@ IMPLEMENT_FUNCTION(6, Tables, draw) case kChapter1: if (getState()->time > kTime1165500 && !params->param1) { params->param1 = 1; - getSound()->processEntry(kEntityTables2); + getSoundQueue()->processEntry(kEntityTables2); } break; case kChapter3: if (getState()->time > kTime2052000 && !params->param2) { params->param2 = 1; - getSound()->processEntry(kEntityTables2); + getSoundQueue()->processEntry(kEntityTables2); } break; case kChapter4: if (getState()->time > kTime2488500 && !params->param3) { params->param3 = 1; - getSound()->processEntry(kEntityTables2); + getSoundQueue()->processEntry(kEntityTables2); } break; diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp index db5c413dc9..2f60b448ba 100644 --- a/engines/lastexpress/entities/tatiana.cpp +++ b/engines/lastexpress/entities/tatiana.cpp @@ -35,6 +35,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -420,7 +422,7 @@ IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler) break; case kActionNone: - if (getSound()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSound()->isBuffered("TAT1066")) + if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSoundQueue()->isBuffered("TAT1066")) goto label_tatiana_chapter1_2; UPDATE_PARAM_PROC(params->param5, getState()->timeTicks, 450) @@ -568,7 +570,7 @@ IMPLEMENT_FUNCTION(21, Tatiana, function21) // Fallback to next case case 3: - if (getSound()->isBuffered(kEntityTatiana)) { + if (getSoundQueue()->isBuffered(kEntityTatiana)) { setCallback(3); setup_updateFromTime(75); } else { @@ -1858,7 +1860,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, function46) parameters->param3 = 1; if (parameters->param2) { - getSound()->removeFromQueue(kEntityTatiana); + getSoundQueue()->removeFromQueue(kEntityTatiana); getSavePoints()->call(kEntityTatiana, kEntityTatiana, kActionEndSound); } } else { @@ -1947,7 +1949,7 @@ IMPLEMENT_FUNCTION(48, Tatiana, function48) params->param1 = 0; } - if (!params->param1 || getSound()->isBuffered(kEntityTatiana)) + if (!params->param1 || getSoundQueue()->isBuffered(kEntityTatiana)) goto label_end; UPDATE_PARAM_GOTO(params->param2, getState()->timeTicks, 5 * (3 * rnd(5) + 30), label_end); @@ -2086,7 +2088,7 @@ IMPLEMENT_FUNCTION(50, Tatiana, function50) break; case kActionKnock: - if (!getSound()->isBuffered("LIB012", true)) + if (!getSoundQueue()->isBuffered("LIB012", true)) getSound()->playSound(kEntityPlayer, "LIB012"); break; @@ -2107,14 +2109,14 @@ IMPLEMENT_FUNCTION(50, Tatiana, function50) getObjects()->update(kObject48, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand); getObjects()->update(kObjectCompartmentA, kEntityTatiana, kObjectLocationNone, kCursorHandKnock, kCursorHand); - if (!getSound()->isBuffered(kEntityTatiana)) + if (!getSoundQueue()->isBuffered(kEntityTatiana)) getSound()->playSound(kEntityTatiana, "Tat4166"); break; case kActionCallback: if (getCallback() == 1) { - if (getSound()->isBuffered("MUS013")) - getSound()->processEntry("MUS013"); + if (getSoundQueue()->isBuffered("MUS013")) + getSoundQueue()->processEntry("MUS013"); getAction()->playAnimation(kEventVassiliDeadAlexei); getSavePoints()->push(kEntityTatiana, kEntityAbbot, kAction104060776); @@ -2223,11 +2225,11 @@ IMPLEMENT_FUNCTION(54, Tatiana, function54) case kActionCallback: if (getCallback() == 1) { - if (getSound()->isBuffered("MUS050")) - getSound()->processEntry("MUS050"); + if (getSoundQueue()->isBuffered("MUS050")) + getSoundQueue()->processEntry("MUS050"); - if (getSound()->isBuffered(kEntityTatiana)) - getSound()->processEntry(kEntityTatiana); + if (getSoundQueue()->isBuffered(kEntityTatiana)) + getSoundQueue()->processEntry(kEntityTatiana); getAction()->playAnimation(isNight() ? kEventTatianaVassiliTalkNight : kEventTatianaVassiliTalk); getScenes()->processScene(); diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp index 1a5c6f4f64..74eed63bbf 100644 --- a/engines/lastexpress/entities/train.cpp +++ b/engines/lastexpress/entities/train.cpp @@ -32,6 +32,8 @@ #include "lastexpress/game/state.h" #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -300,13 +302,13 @@ label_process: } // Update object - if (ENTITY_PARAM(0, 8) && !getSound()->isBuffered(kEntityTables5)) { + if (ENTITY_PARAM(0, 8) && !getSoundQueue()->isBuffered(kEntityTables5)) { getObjects()->update((ObjectIndex)ENTITY_PARAM(0, 8), getObjects()->get((ObjectIndex)ENTITY_PARAM(0, 8)).entity, kObjectLocation3, kCursorHandKnock, kCursorHand); ENTITY_PARAM(0, 8) = 0; } // Play clock sound - if (params->param6 && !getSound()->isBuffered("ZFX1001", true)) + if (params->param6 && !getSoundQueue()->isBuffered("ZFX1001", true)) getSound()->playSound(kEntityPlayer, "ZFX1001"); break; @@ -339,12 +341,12 @@ label_process: // Play clock sound if (getEntities()->isPlayerPosition(kCarRestaurant, 81)) { params->param6 = 1; - if (!getSound()->isBuffered("ZFX1001")) + if (!getSoundQueue()->isBuffered("ZFX1001")) getSound()->playSound(kEntityPlayer, "ZFX1001"); } else { params->param6 = 0; - if (getSound()->isBuffered("ZFX1001", true)) - getSound()->removeFromQueue("ZFX1001"); + if (getSoundQueue()->isBuffered("ZFX1001", true)) + getSoundQueue()->removeFromQueue("ZFX1001"); } // Draw moving background behind windows @@ -562,8 +564,8 @@ void Train::resetParam8() { && !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param2) && !getEntities()->isInsideCompartment(kEntityPlayer, (CarIndex)params1->param1, (EntityPosition)params1->param3)) { - if (getSound()->isBuffered((const char *)¶ms1->seq)) - getSound()->processEntry((const char *)¶ms1->seq); + if (getSoundQueue()->isBuffered((const char *)¶ms1->seq)) + getSoundQueue()->processEntry((const char *)¶ms1->seq); params->param8 = 0; } diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp index a1daf3e524..a7fbc7cf32 100644 --- a/engines/lastexpress/entities/vassili.cpp +++ b/engines/lastexpress/entities/vassili.cpp @@ -35,6 +35,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -295,7 +297,7 @@ IMPLEMENT_FUNCTION(9, Vassili, function9) || getEntities()->isPlayerPosition(kCarRedSleeping, 41)) { if (savepoint.action == kActionDrawScene) - getSound()->processEntry(kEntityVassili); + getSoundQueue()->processEntry(kEntityVassili); setup_seizure(); } else { diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp index c0a00b8c05..c18137c835 100644 --- a/engines/lastexpress/entities/verges.cpp +++ b/engines/lastexpress/entities/verges.cpp @@ -32,6 +32,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -139,7 +141,7 @@ IMPLEMENT_FUNCTION_END ////////////////////////////////////////////////////////////////////////// IMPLEMENT_FUNCTION_II(8, Verges, updateEntity, CarIndex, EntityPosition) if (savepoint.action == kActionExcuseMeCath) { - if (!getSound()->isBuffered(kEntityVerges)) + if (!getSoundQueue()->isBuffered(kEntityVerges)) getSound()->playSound(kEntityPlayer, "TRA1113", getSound()->getSoundFlag(kEntityVerges)); return; @@ -187,7 +189,7 @@ switch (savepoint.action) { break; case 2: - if (!getSound()->isBuffered(kEntityVerges)) + if (!getSoundQueue()->isBuffered(kEntityVerges)) getSound()->playSound(kEntityVerges, (char *)¶ms->seq1); getEntities()->drawSequenceRight(kEntityVerges, "813DS"); @@ -232,7 +234,7 @@ IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition) case kActionNone: if (!params->param7) { - if (!getSound()->isBuffered(kEntityVerges)) { + if (!getSoundQueue()->isBuffered(kEntityVerges)) { getSound()->playSound(kEntityVerges, (char *)¶ms->seq); params->param7 = 1; } @@ -258,7 +260,7 @@ IMPLEMENT_FUNCTION_IIS(10, Verges, function10, CarIndex, EntityPosition) break; case kActionDefault: - if (!getSound()->isBuffered(kEntityVerges)) { + if (!getSoundQueue()->isBuffered(kEntityVerges)) { getSound()->playSound(kEntityVerges, (char *)¶ms->seq); params->param7 = 1; } @@ -704,7 +706,7 @@ IMPLEMENT_FUNCTION(24, Verges, policeGettingOffTrain) case kActionCallback: if (getCallback() == 1) { - getSound()->processEntry(kEntityVerges); + getSoundQueue()->processEntry(kEntityVerges); getAction()->playAnimation(kEventGendarmesArrestation); getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverPolice1, true); } @@ -1314,7 +1316,7 @@ IMPLEMENT_FUNCTION(32, Verges, function32) break; case 2: - if (!getSound()->isBuffered(kEntityVerges)) + if (!getSoundQueue()->isBuffered(kEntityVerges)) getSound()->playSound(kEntityVerges, "TRA3004"); getEntities()->drawSequenceRight(kEntityVerges, "813DS"); @@ -1752,16 +1754,16 @@ IMPLEMENT_FUNCTION(40, Verges, chapter5Handler) break; case kActionNone: - if (getEntities()->isInSalon(kEntityPlayer) && !getSound()->isBuffered(kEntityVerges)) + if (getEntities()->isInSalon(kEntityPlayer) && !getSoundQueue()->isBuffered(kEntityVerges)) getSound()->playSound(kEntityVerges, "WAT5000"); break; case kActionOpenDoor: - if (getSound()->isBuffered(kEntityVerges)) - getSound()->processEntry(kEntityVerges); + if (getSoundQueue()->isBuffered(kEntityVerges)) + getSoundQueue()->processEntry(kEntityVerges); - if (getSound()->isBuffered("MUS050")) - getSound()->processEntry("MUS050"); + if (getSoundQueue()->isBuffered("MUS050")) + getSoundQueue()->processEntry("MUS050"); getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward); @@ -1811,7 +1813,7 @@ IMPLEMENT_FUNCTION(41, Verges, function41) // Fallback to next case case 2: - if (getSound()->isBuffered(kEntityVerges)) { + if (getSoundQueue()->isBuffered(kEntityVerges)) { setCallback(2); setup_updateFromTime(225); } else { diff --git a/engines/lastexpress/fight/fight.cpp b/engines/lastexpress/fight/fight.cpp index 685b3b09d1..38a93cfd94 100644 --- a/engines/lastexpress/fight/fight.cpp +++ b/engines/lastexpress/fight/fight.cpp @@ -37,6 +37,8 @@ #include "lastexpress/game/scenes.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -86,7 +88,7 @@ void Fight::eventMouse(const Common::Event &ev) { // Handle right button click if (ev.type == Common::EVENT_RBUTTONUP) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); setStopped(); getGlobalTimer() ? _state = 0 : ++_state; @@ -133,15 +135,15 @@ void Fight::eventMouse(const Common::Event &ev) { // Stop fight if clicked if (ev.type == Common::EVENT_LBUTTONUP) { _handleTimer = false; - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); bailout(kFightEndExit); } // Reset timer on right click if (ev.type == Common::EVENT_RBUTTONUP) { if (getGlobalTimer()) { - if (getSound()->isBuffered("TIMER")) - getSound()->removeFromQueue("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); setGlobalTimer(900); } @@ -277,7 +279,7 @@ Fight::FightEndType Fight::setup(FightType type) { if (_engine->handleEvents()) continue; - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); } // Cleanup after fight is over diff --git a/engines/lastexpress/fight/fighter_anna.cpp b/engines/lastexpress/fight/fighter_anna.cpp index 3c0132eef6..feb35515a0 100644 --- a/engines/lastexpress/fight/fighter_anna.cpp +++ b/engines/lastexpress/fight/fighter_anna.cpp @@ -26,6 +26,8 @@ #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -107,7 +109,7 @@ void FighterPlayerAnna::handleAction(FightAction action) { } if (_field_34 > 4) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); _fight->bailout(Fight::kFightEndWin); } } @@ -175,7 +177,7 @@ void FighterOpponentAnna::update() { _opponent->handleAction((FightAction)_sequenceIndex); if (_opponent->getCountdown() <= 0) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); handleAction(kFightActionLost); } } diff --git a/engines/lastexpress/fight/fighter_ivo.cpp b/engines/lastexpress/fight/fighter_ivo.cpp index 60d6c1a874..9988fca790 100644 --- a/engines/lastexpress/fight/fighter_ivo.cpp +++ b/engines/lastexpress/fight/fighter_ivo.cpp @@ -26,6 +26,8 @@ #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -110,7 +112,7 @@ void FighterPlayerIvo::update() { if (_opponent->getCountdown() <= 0) { setSequenceAndDraw(9, kFightSequenceType1); _opponent->setSequenceAndDraw(8, kFightSequenceType1); - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); handleAction(kFightActionWin); return; @@ -227,7 +229,7 @@ void FighterOpponentIvo::update() { if (_opponent->getCountdown() <= 0) { setSequenceAndDraw(7, kFightSequenceType1); _opponent->setSequenceAndDraw(8, kFightSequenceType1); - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); _opponent->handleAction(kFightActionWin); diff --git a/engines/lastexpress/fight/fighter_milos.cpp b/engines/lastexpress/fight/fighter_milos.cpp index 972c44882b..82c965caf3 100644 --- a/engines/lastexpress/fight/fighter_milos.cpp +++ b/engines/lastexpress/fight/fighter_milos.cpp @@ -27,6 +27,8 @@ #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -107,7 +109,7 @@ void FighterPlayerMilos::update() { setSequenceAndDraw(5, kFightSequenceType1); _opponent->setSequenceAndDraw(6, kFightSequenceType1); - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); getSound()->playSound(kEntityTrain, "MUS029", kFlagDefault); handleAction(kFightActionWin); @@ -210,7 +212,7 @@ void FighterOpponentMilos::update() { _opponent->handleAction((FightAction)_sequenceIndex); if (_opponent->getCountdown() <= 0) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); handleAction(kFightActionLost); } } diff --git a/engines/lastexpress/fight/fighter_salko.cpp b/engines/lastexpress/fight/fighter_salko.cpp index 6f71a6dda8..166f7c3899 100644 --- a/engines/lastexpress/fight/fighter_salko.cpp +++ b/engines/lastexpress/fight/fighter_salko.cpp @@ -27,6 +27,8 @@ #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -95,7 +97,7 @@ void FighterPlayerSalko::update() { if (_frame && checkFrame(2)) { if (_opponent->getCountdown() <= 0) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); _fight->bailout(Fight::kFightEndWin); return; @@ -184,7 +186,7 @@ void FighterOpponentSalko::update() { if (_frame && checkFrame(2)) { if (_opponent->getCountdown() <= 0) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); _fight->bailout(Fight::kFightEndLost); // Stop processing diff --git a/engines/lastexpress/fight/fighter_vesna.cpp b/engines/lastexpress/fight/fighter_vesna.cpp index c92d041c7e..075f158bda 100644 --- a/engines/lastexpress/fight/fighter_vesna.cpp +++ b/engines/lastexpress/fight/fighter_vesna.cpp @@ -27,6 +27,8 @@ #include "lastexpress/game/sound.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -103,7 +105,7 @@ void FighterPlayerVesna::update() { _opponent->handleAction(kFightAction3); if (_opponent->getCountdown() <= 0) { - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); _fight->bailout(Fight::kFightEndWin); return; } @@ -251,7 +253,7 @@ void FighterOpponentVesna::update() { _opponent->update(); Fighter::update(); - getSound()->removeFromQueue(kEntityTables0); + getSoundQueue()->removeFromQueue(kEntityTables0); // Stop processing return; diff --git a/engines/lastexpress/game/action.cpp b/engines/lastexpress/game/action.cpp index 54bb8759ee..f195825d6e 100644 --- a/engines/lastexpress/game/action.cpp +++ b/engines/lastexpress/game/action.cpp @@ -42,6 +42,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" #include "lastexpress/resource.h" @@ -453,7 +455,7 @@ IMPLEMENT_ACTION(savePoint) IMPLEMENT_ACTION(playSound) // Check that the file is not already buffered - if (hotspot.param2 || !getSound()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true)) + if (hotspot.param2 || !getSoundQueue()->isBuffered(Common::String::format("LIB%03d", hotspot.param1), true)) getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2); return kSceneInvalid; @@ -465,7 +467,7 @@ IMPLEMENT_ACTION(playMusic) // Check that the file is not already buffered Common::String filename = Common::String::format("MUS%03d", hotspot.param1); - if (!getSound()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5)) + if (!getSoundQueue()->isBuffered(filename) && (hotspot.param1 != 50 || getProgress().chapter == kChapter5)) getSound()->playSound(kEntityPlayer, filename, kFlagDefault, hotspot.param2); return kSceneInvalid; @@ -481,7 +483,7 @@ IMPLEMENT_ACTION(knock) if (getObjects()->get(object).entity) { getSavePoints()->push(kEntityPlayer, getObjects()->get(object).entity, kActionKnock, object); } else { - if (!getSound()->isBuffered("LIB012", true)) + if (!getSoundQueue()->isBuffered("LIB012", true)) getSound()->playSoundEvent(kEntityPlayer, 12); } @@ -516,7 +518,7 @@ IMPLEMENT_ACTION(compartment) && (compartment != kObjectCompartment1 || !getInventory()->hasItem(kItemKey) || (getInventory()->getSelectedItem() != kItemFirebird && getInventory()->getSelectedItem() != kItemBriefcase)))) { - if (!getSound()->isBuffered("LIB13")) + if (!getSoundQueue()->isBuffered("LIB13")) getSound()->playSoundEvent(kEntityPlayer, 13); // Stop processing further @@ -621,7 +623,7 @@ IMPLEMENT_ACTION(updateObjetLocation2) getObjects()->updateLocation2(object, location); - if (object != kObject112 || getSound()->isBuffered("LIB096")) { + if (object != kObject112 || getSoundQueue()->isBuffered("LIB096")) { if (object == 1) getSound()->playSoundEvent(kEntityPlayer, 73); } else { @@ -805,7 +807,7 @@ IMPLEMENT_ACTION(enterCompartment) getSound()->playSoundEvent(kEntityPlayer, 14); getSound()->playSoundEvent(kEntityPlayer, 15, 22); - if (getProgress().field_78 && !getSound()->isBuffered("MUS003")) { + if (getProgress().field_78 && !getSoundQueue()->isBuffered("MUS003")) { getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault); getProgress().field_78 = 0; } @@ -1083,7 +1085,7 @@ IMPLEMENT_ACTION(25) break; case 2: - if (!getSound()->isBuffered("MUS021")) + if (!getSoundQueue()->isBuffered("MUS021")) getSound()->playSound(kEntityPlayer, "MUS021", kFlagDefault); break; @@ -1134,7 +1136,7 @@ IMPLEMENT_ACTION(26) ////////////////////////////////////////////////////////////////////////// // Action 27 IMPLEMENT_ACTION(27) - if (!getSound()->isBuffered("LIB031", true)) + if (!getSoundQueue()->isBuffered("LIB031", true)) getSound()->playSoundEvent(kEntityPlayer, 31); switch (getEntityData(kEntityPlayer)->car) { @@ -1182,7 +1184,7 @@ IMPLEMENT_ACTION(29) getSound()->playSoundEvent(kEntityPlayer, hotspot.param1, hotspot.param2); Common::String filename = Common::String::format("MUS%03d", hotspot.param3); - if (!getSound()->isBuffered(filename)) + if (!getSoundQueue()->isBuffered(filename)) getSound()->playSound(kEntityPlayer, filename, kFlagDefault); return kSceneInvalid; @@ -1354,7 +1356,7 @@ IMPLEMENT_ACTION(dialog) // Action 38 IMPLEMENT_ACTION(eggBox) getSound()->playSoundEvent(kEntityPlayer, 43); - if (getProgress().field_7C && !getSound()->isBuffered("MUS003")) { + if (getProgress().field_7C && !getSoundQueue()->isBuffered("MUS003")) { getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault); getProgress().field_7C = 0; } @@ -1366,7 +1368,7 @@ IMPLEMENT_ACTION(eggBox) // Action 39 IMPLEMENT_ACTION(39) getSound()->playSoundEvent(kEntityPlayer, 24); - if (getProgress().field_80 && !getSound()->isBuffered("MUS003")) { + if (getProgress().field_80 && !getSoundQueue()->isBuffered("MUS003")) { getSound()->playSound(kEntityPlayer, "MUS003", kFlagDefault); getProgress().field_80 = 0; } @@ -1408,7 +1410,7 @@ IMPLEMENT_ACTION(playMusicChapter) if (id) { Common::String filename = Common::String::format("MUS%03d", id); - if (!getSound()->isBuffered(filename)) + if (!getSoundQueue()->isBuffered(filename)) getSound()->playSound(kEntityPlayer, filename, kFlagDefault); } @@ -1440,7 +1442,7 @@ IMPLEMENT_ACTION(playMusicChapterSetupTrain) Common::String filename = Common::String::format("MUS%03d", hotspot.param1); - if (!getSound()->isBuffered(filename) && hotspot.param3 & id) { + if (!getSoundQueue()->isBuffered(filename) && hotspot.param3 & id) { getSound()->playSound(kEntityPlayer, filename, kFlagDefault); getSavePoints()->call(kEntityPlayer, kEntityTrain, kAction203863200, filename.c_str()); @@ -1612,7 +1614,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playWarningCompartment(kEntityMertens, object); getSavePoints()->push(kEntityPlayer, kEntityMertens, kAction305159806); @@ -1628,7 +1630,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1640,7 +1642,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityMertens)) + if (!getSoundQueue()->isBuffered(kEntityMertens)) getSound()->playSound(kEntityMertens, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1667,7 +1669,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playWarningCompartment(kEntityCoudert, object); getSavePoints()->push(kEntityPlayer, kEntityCoudert, kAction305159806); @@ -1684,7 +1686,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1699,7 +1701,7 @@ bool Action::handleOtherCompartment(ObjectIndex object, bool doPlaySound, bool d if (doPlaySound) playCompartmentSoundEvents(object); - if (!getSound()->isBuffered(kEntityCoudert)) + if (!getSoundQueue()->isBuffered(kEntityCoudert)) getSound()->playSound(kEntityCoudert, (rnd(2)) ? "JAC1000" : "JAC1000A"); if (doLoadScene) @@ -1930,8 +1932,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const { if (!getFlags()->mouseRightClick) { if (getGlobalTimer()) { - if (getSound()->isBuffered("TIMER")) { - getSound()->processEntry("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) { + getSoundQueue()->processEntry("TIMER"); setGlobalTimer(105); } } @@ -1948,8 +1950,8 @@ void Action::playAnimation(EventIndex index, bool debugMode) const { if (animation.load(getArchive(Common::String(_animationList[index].filename) + ".nis") , processSound ? Animation::kFlagDefault : Animation::kFlagProcess)) animation.play(); - if (getSound()->isBuffered("TIMER")) - getSound()->removeFromQueue("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); } // Show cursor diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp index 0fa3af36b7..8dd2c26c19 100644 --- a/engines/lastexpress/game/entities.cpp +++ b/engines/lastexpress/game/entities.cpp @@ -71,6 +71,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -299,7 +301,7 @@ void Entities::setupChapter(ChapterIndex chapter) { memset(&_compartments1, 0, sizeof(_compartments1)); memset(&_positions, 0, sizeof(_positions)); - getSound()->resetQueue(kSoundType13); + getSoundQueue()->resetQueue(kSoundType13); } // we skip the header when doing entity setup @@ -369,8 +371,8 @@ void Entities::resetState(EntityIndex entityIndex) { getData(entityIndex)->currentCall = 0; getData(entityIndex)->inventoryItem = kItemNone; - if (getSound()->isBuffered(entityIndex)) - getSound()->removeFromQueue(entityIndex); + if (getSoundQueue()->isBuffered(entityIndex)) + getSoundQueue()->removeFromQueue(entityIndex); clearSequences(entityIndex); diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp index 4d75fcaca5..c3a10225e9 100644 --- a/engines/lastexpress/game/inventory.cpp +++ b/engines/lastexpress/game/inventory.cpp @@ -33,6 +33,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -162,8 +164,8 @@ void Inventory::handleMouseEvent(const Common::Event &ev) { } else if (ev.type == Common::EVENT_RBUTTONDOWN) { if (getGlobalTimer()) { - if (getSound()->isBuffered("TIMER")) - getSound()->removeFromQueue("TIMER"); + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); setGlobalTimer(900); } @@ -630,7 +632,7 @@ void Inventory::drawBlinkingEgg() { // if (getGlobalTimer() + ticks >= 90) // getSound()->playSoundWithSubtitles("TIMER.SND", 50331664, kEntityPlayer); - // if (getSound()->isBuffered("TIMER")) + // if (getSoundQueue()->isBuffered("TIMER")) // setGlobalTimer(0); //} diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp index c1237eefe9..cdde2a0e0a 100644 --- a/engines/lastexpress/game/logic.cpp +++ b/engines/lastexpress/game/logic.cpp @@ -47,6 +47,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -152,7 +154,7 @@ void Logic::eventMouse(const Common::Event &ev) { _engine->getCursor()->setStyle(getInventory()->get(kItemWhistle)->cursor); // Check if clicked - if (ev.type == Common::EVENT_LBUTTONUP && !getSound()->isBuffered("LIB045")) { + if (ev.type == Common::EVENT_LBUTTONUP && !getSoundQueue()->isBuffered("LIB045")) { getSound()->playSoundEvent(kEntityPlayer, 45); @@ -424,7 +426,7 @@ void Logic::resetState() { */ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, bool showScene) const { - getSound()->processEntries(); + getSoundQueue()->processEntries(); getEntities()->reset(); getFlags()->isGameRunning = false; getSavePoints()->reset(); @@ -432,16 +434,16 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo if (showScene) { - getSound()->processEntry(kSoundType11); + getSoundQueue()->processEntry(kSoundType11); if (sceneIndex && !getFlags()->mouseRightClick) { getScenes()->loadScene(sceneIndex); - while (getSound()->isBuffered(kEntityTables4)) { + while (getSoundQueue()->isBuffered(kEntityTables4)) { if (getFlags()->mouseRightClick) break; - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); } } } @@ -451,7 +453,7 @@ void Logic::gameOver(SavegameType type, uint32 value, SceneIndex sceneIndex, boo } void Logic::switchChapter() const { - getSound()->clearStatus(); + getSoundQueue()->clearStatus(); switch(getState()->progress.chapter) { default: @@ -491,7 +493,7 @@ void Logic::switchChapter() const { } void Logic::playFinalSequence() const { - getSound()->processEntries(); + getSoundQueue()->processEntries(); _action->playAnimation(kEventFinalSequence); showCredits(); diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp index 594cd1276b..8dfc214913 100644 --- a/engines/lastexpress/game/savegame.cpp +++ b/engines/lastexpress/game/savegame.cpp @@ -30,6 +30,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/debug.h" #include "lastexpress/lastexpress.h" #include "lastexpress/helpers.h" @@ -125,7 +127,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) { while (_savegame->pos() < _savegame->size() && !_savegame->eos() && !_savegame->err()) { // Update sound queue while we go through the savegame - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); SavegameEntryHeader *entry = new SavegameEntryHeader(); entry->saveLoadWithSerializer(ser); @@ -217,7 +219,7 @@ void SaveLoad::loadGame(GameId id) { _gameTicksLastSavegame = getState()->timeTicks; if (header.keepIndex) { - getSound()->clearQueue(); + getSoundQueue()->clearQueue(); readEntry(&type, &entity, &val, false); } @@ -377,7 +379,7 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) { WRITE_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32); WRITE_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128); WRITE_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40); - WRITE_ENTRY("sound", getSound()->saveLoadWithSerializer(ser), 3 * 4 + getSound()->count() * 64); + WRITE_ENTRY("sound", getSoundQueue()->saveLoadWithSerializer(ser), 3 * 4 + getSoundQueue()->count() * 64); WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 128 * 16 + 4 + getSavePoints()->count() * 16); header.offset = (uint32)_savegame->pos() - (originalPosition + 32); @@ -452,7 +454,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b LOAD_ENTRY("inventory", getInventory()->saveLoadWithSerializer(ser), 7 * 32); LOAD_ENTRY("objects", getObjects()->saveLoadWithSerializer(ser), 5 * 128); LOAD_ENTRY("entities", getEntities()->saveLoadWithSerializer(ser), 1262 * 40); - LOAD_ENTRY_ONLY("sound", getSound()->saveLoadWithSerializer(ser)); + LOAD_ENTRY_ONLY("sound", getSoundQueue()->saveLoadWithSerializer(ser)); LOAD_ENTRY_ONLY("savepoints", getSavePoints()->saveLoadWithSerializer(ser)); // Update chapter diff --git a/engines/lastexpress/game/scenes.cpp b/engines/lastexpress/game/scenes.cpp index b346c9daf8..408f48044c 100644 --- a/engines/lastexpress/game/scenes.cpp +++ b/engines/lastexpress/game/scenes.cpp @@ -34,6 +34,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -1057,9 +1059,9 @@ void SceneManager::preProcessScene(SceneIndex *index) { // Sound processing Scene *newScene = getScenes()->get(*index); - if (getSound()->isBuffered(kEntityTables4)) { + if (getSoundQueue()->isBuffered(kEntityTables4)) { if (newScene->type != Scene::kTypeReadText || newScene->param1) - getSound()->processEntry(kEntityTables4); + getSoundQueue()->processEntry(kEntityTables4); } // Cleanup beetle sequences @@ -1089,8 +1091,8 @@ void SceneManager::postProcessScene() { if (getFlags()->mouseRightClick) break; - getSound()->updateQueue(); - getSound()->updateSubtitles(); + getSoundQueue()->updateQueue(); + getSoundQueue()->updateSubtitles(); } } @@ -1157,7 +1159,7 @@ void SceneManager::postProcessScene() { if (getState()->time >= kTimeCityGalanta || getProgress().field_18 == 4) break; - getSound()->processEntry(kSoundType7); + getSoundQueue()->processEntry(kSoundType7); getSound()->playSound(kEntityTrain, "LIB050", kFlagDefault); switch (getProgress().chapter) { diff --git a/engines/lastexpress/game/sound.cpp b/engines/lastexpress/game/sound.cpp index 3fb3f8894d..bc4f71e18d 100644 --- a/engines/lastexpress/game/sound.cpp +++ b/engines/lastexpress/game/sound.cpp @@ -31,6 +31,7 @@ #include "lastexpress/game/state.h" #include "lastexpress/sound/entry.h" +#include "lastexpress/sound/queue.h" #include "lastexpress/helpers.h" #include "lastexpress/graphics.h" @@ -39,9 +40,6 @@ namespace LastExpress { -#define SOUNDCACHE_ENTRY_SIZE 92160 -#define SOUNDCACHE_MAX_SIZE 6 - // Letters & messages static const char *const messages[24] = { "", @@ -115,349 +113,32 @@ static const SoundFlag soundFlags[32] = { kFlag3, kFlag3, kFlag3, kFlag3, kFlag3 }; -SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine), _state(0), _currentType(kSoundType16), _flag(0) { +SoundManager::SoundManager(LastExpressEngine *engine) : _engine(engine) { + _loopingSoundDuration = 0; + + _queue = new SoundQueue(engine); + + memset(&_lastWarning, 0, sizeof(_lastWarning)); + // Initialize unknown data _data0 = 0; _data1 = 0; _data2 = 0; - - memset(&_buffer, 0, sizeof(_buffer)); - memset(&_lastWarning, 0, sizeof(_lastWarning)); - - // Sound cache - _soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE); - - _subtitlesFlag = 0; - _currentSubtitle = NULL; - - _loopingSoundDuration = 0; } SoundManager::~SoundManager() { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - SAFE_DELETE(*i); - _soundList.clear(); - - // Entries in the cache are just pointers to sound list entries - _soundCache.clear(); - - for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) - SAFE_DELETE(*i); - _subtitles.clear(); - - _currentSubtitle = NULL; - - free(_soundCacheData); + SAFE_DELETE(_queue); // Zero passed pointers _engine = NULL; } ////////////////////////////////////////////////////////////////////////// -// Timer -////////////////////////////////////////////////////////////////////////// -void SoundManager::handleTimer() { - Common::StackLock locker(_mutex); - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - SoundEntry *entry = (*i); - if (entry->_stream == NULL) { - SAFE_DELETE(*i); - i = _soundList.reverse_erase(i); - continue; - } else if (!entry->_soundStream) { - entry->_soundStream = new StreamedSound(); - - // TODO: stream any sound in the queue after filtering - entry->_soundStream->load(entry->_stream); - } - } -} - -////////////////////////////////////////////////////////////////////////// -// Sound queue management -////////////////////////////////////////////////////////////////////////// -void SoundManager::updateQueue() { - // TODO add mutex lock! - warning("Sound::updateQueue: not implemented!"); -} - -void SoundManager::resetQueue(SoundType type1, SoundType type2) { - if (!type2) - type2 = type1; - - Common::StackLock locker(_mutex); - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->getType() != type1 && (*i)->getType() != type2) - (*i)->reset(); - } -} - -void SoundManager::removeFromQueue(EntityIndex entity) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(entity); - if (entry) - entry->reset(); -} - -void SoundManager::removeFromQueue(Common::String filename) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(filename); - if (entry) - entry->reset(); -} - -void SoundManager::clearQueue() { - _flag |= 4; - - // FIXME: Wait a while for a flag to be set - //for (int i = 0; i < 3000000; i++) - // if (_flag & 8) - // break; - - _flag |= 8; - - Common::StackLock locker(_mutex); - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - SoundEntry *entry = (*i); - - // Delete entry - entry->close(); - SAFE_DELETE(entry); - - i = _soundList.reverse_erase(i); - } - - updateSubtitles(); -} - -bool SoundManager::isBuffered(EntityIndex entity) { - Common::StackLock locker(_mutex); - - return (getEntry(entity) != NULL); -} - -bool SoundManager::isBuffered(Common::String filename, bool testForEntity) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(filename); - - if (testForEntity) - return entry != NULL && entry->getEntity() != kEntityPlayer; - - return (entry != NULL); -} - -////////////////////////////////////////////////////////////////////////// -// Entry -////////////////////////////////////////////////////////////////////////// -bool SoundManager::setupCache(SoundEntry *entry) { - if (entry->_soundData) - return true; - - if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) { - - SoundEntry *cacheEntry = NULL; - uint32 size = 1000; - - for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) { - if (!((*i)->_status.status & kSoundStatus_180)) { - uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1); - - if (newSize < size) { - cacheEntry = (*i); - size = newSize; - } - } - } - - if (entry->_priority <= size) - return false; - - if (!cacheEntry) - error("[SoundManager::setupCache] Cannot find a valid entry"); - - cacheEntry->setInCache(); - - // TODO: Wait until the cache entry is ready to be removed - while (!(cacheEntry->_status.status1 & 1)) - ; - - if (cacheEntry->_soundData) - removeFromCache(cacheEntry); - - _soundCache.push_back(entry); - entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1); - } else { - _soundCache.push_back(entry); - entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1); - } - - return true; -} - -void SoundManager::removeFromCache(SoundEntry *entry) { - for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) { - if ((*i) == entry) { - // Remove sound buffer - entry->_soundData = NULL; - - // Remove entry from sound cache - i = _soundCache.reverse_erase(i); - } - } -} - -void SoundManager::clearStatus() { - Common::StackLock locker(_mutex); - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->_status.status |= kSoundStatusClear3; -} - -void SoundManager::processEntry(EntityIndex entity) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(entity); - if (entry) { - entry->update(0); - entry->setEntity(kEntityPlayer); - } -} - -void SoundManager::processEntry(SoundType type) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(type); - if (entry) - entry->update(0); -} - -void SoundManager::setupEntry(SoundType type, EntityIndex index) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(type); - if (entry) - entry->setEntity(index); -} - -void SoundManager::processEntry(Common::String filename) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(filename); - if (entry) { - entry->update(0); - entry->setEntity(kEntityPlayer); - } -} - -void SoundManager::processEntries() { - _state = 0; - - processEntry(kSoundType1); - processEntry(kSoundType2); -} - -uint32 SoundManager::getEntryTime(EntityIndex index) { - Common::StackLock locker(_mutex); - - SoundEntry *entry = getEntry(index); - if (entry) - return entry->_time; - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -// Misc -////////////////////////////////////////////////////////////////////////// - -void SoundManager::unknownFunction4() { - // TODO: Add mutex ? - warning("Sound::unknownFunction4: not implemented!"); -} - -////////////////////////////////////////////////////////////////////////// -// Entry search -////////////////////////////////////////////////////////////////////////// -SoundEntry *SoundManager::getEntry(EntityIndex index) { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->getEntity() == index) - return *i; - } - - return NULL; -} - -SoundEntry *SoundManager::getEntry(Common::String name) { - if (!name.contains('.')) - name += ".SND"; - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->_name2 == name) - return *i; - } - - return NULL; -} - -SoundEntry *SoundManager::getEntry(SoundType type) { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { - if ((*i)->getType() == type) - return *i; - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -// Savegame -////////////////////////////////////////////////////////////////////////// -void SoundManager::saveLoadWithSerializer(Common::Serializer &s) { - Common::StackLock locker(_mutex); - - s.syncAsUint32LE(_state); - s.syncAsUint32LE(_currentType); - - // Compute the number of entries to save - uint32 numEntries = count(); - s.syncAsUint32LE(numEntries); - - // Save or load each entry data - if (s.isSaving()) { - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->saveLoadWithSerializer(s); - } else { - warning("Sound::saveLoadWithSerializer: loading not implemented"); - s.skip(numEntries * 64); - } -} - - -// FIXME: We probably need another mutex here to protect during the whole savegame process -// as we could have removed an entry between the time we check the count and the time we -// save the entries -uint32 SoundManager::count() { - Common::StackLock locker(_mutex); - - uint32 numEntries = 0; - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - if ((*i)->_name2.matchString("NISSND?")) - ++numEntries; - - return numEntries; -} - -////////////////////////////////////////////////////////////////////////// -// Game-related functions +// Sound-related functions ////////////////////////////////////////////////////////////////////////// void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) { - if (isBuffered(entity) && entity) - removeFromQueue(entity); + if (_queue->isBuffered(entity) && entity) + _queue->removeFromQueue(entity); SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000); @@ -473,8 +154,6 @@ void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundF bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4) { SoundEntry *entry = new SoundEntry(_engine); - Common::StackLock locker(_mutex); - entry->open(filename, flag, 30); entry->_entity = entity; @@ -623,13 +302,13 @@ void SoundManager::playSteam(CityIndex index) { if (index >= ARRAYSIZE(cities)) error("SoundManager::playSteam: invalid city index (was %d, max %d)", index, ARRAYSIZE(cities)); - _state |= kSoundState2; + _queue->resetState(kSoundState2); - if (!getEntry(kSoundType1)) + if (!_queue->getEntry(kSoundType1)) playSoundWithSubtitles("STEAM.SND", kFlagSteam, kEntitySteam); // Get the new sound entry and show subtitles - SoundEntry *entry = getEntry(kSoundType1); + SoundEntry *entry = _queue->getEntry(kSoundType1); if (entry) entry->showSubtitle(cities[index]); } @@ -679,8 +358,8 @@ void SoundManager::playFightSound(byte action, byte a4) { } void SoundManager::playDialog(EntityIndex entity, EntityIndex entityDialog, SoundFlag flag, byte a4) { - if (isBuffered(getDialogName(entityDialog))) - removeFromQueue(getDialogName(entityDialog)); + if (_queue->isBuffered(getDialogName(entityDialog))) + _queue->removeFromQueue(getDialogName(entityDialog)); playSound(entity, getDialogName(entityDialog), flag, a4); } @@ -993,7 +672,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const { // Letters & Messages ////////////////////////////////////////////////////////////////////////// void SoundManager::readText(int id){ - if (!isBuffered(kEntityTables4)) + if (!_queue->isBuffered(kEntityTables4)) return; if (id < 0 || (id > 8 && id < 50) || id > 64) @@ -1004,8 +683,8 @@ void SoundManager::readText(int id){ // Check if file is in cache for id [1;8] if (id <= 8) - if (isBuffered(text)) - removeFromQueue(text); + if (_queue->isBuffered(text)) + _queue->removeFromQueue(text); playSound(kEntityTables4, text, kFlagDefault); } @@ -1193,7 +872,7 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar } void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag flag) { - if (isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain) + if (_queue->isBuffered(entity) && entity != kEntityPlayer && entity != kEntityChapters && entity != kEntityTrain) return; if (entity2 == kEntityFrancois || entity2 == kEntityMax) @@ -1598,72 +1277,17 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const { } ////////////////////////////////////////////////////////////////////////// -// Subtitles -////////////////////////////////////////////////////////////////////////// -void SoundManager::updateSubtitles() { - Common::StackLock locker(_mutex); - - uint32 index = 0; - SubtitleEntry *subtitle = NULL; - - for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { - uint32 current_index = 0; - SoundEntry *soundEntry = (*i)->getSoundEntry(); - SoundStatus status = (SoundStatus)soundEntry->_status.status; - - if (!(status & kSoundStatus_40) - || status & kSoundStatus_180 - || soundEntry->_time == 0 - || (status & kSoundStatusClear1) < 6 - || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) { - current_index = 0; - } else { - current_index = soundEntry->_priority + (status & kSoundStatusClear1); - - if (_currentSubtitle == (*i)) - current_index += 4; - } - - if (index < current_index) { - index = current_index; - subtitle = (*i); - } - } - - if (_currentSubtitle == subtitle) { - if (subtitle) - subtitle->setupAndDraw(); - - return; - } - - if (_subtitlesFlag & 1) - subtitle->drawOnScreen(); - - if (subtitle) { - subtitle->loadData(); - subtitle->setupAndDraw(); - } -} - -////////////////////////////////////////////////////////////////////////// // Misc ////////////////////////////////////////////////////////////////////////// void SoundManager::playLoopingSound(int param) { - Common::List<SoundEntry *>::iterator snd; - char tmp[80]; + SoundEntry *entry = _queue->getEntry(kSoundType1); - for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) { - if ((*snd)->getType() == kSoundType1) - break; - } - - byte numLoops[8]; static const EntityPosition positions[8] = { kPosition_8200, kPosition_7500, kPosition_6470, kPosition_5790, kPosition_4840, kPosition_4070, kPosition_3050, kPosition_2740 }; + byte numLoops[8]; numLoops[1] = 4; numLoops[2] = 2; numLoops[3] = 2; @@ -1671,13 +1295,14 @@ void SoundManager::playLoopingSound(int param) { numLoops[5] = 2; numLoops[6] = 2; + char tmp[80]; tmp[0] = 0; int partNumber = 1; int fnameLen = 6; - if (_state & 1 && param >= 0x45 && param <= 0x46) { - if (_state & 2) { + if (_queue->getSoundState() & 1 && param >= 0x45 && param <= 0x46) { + if (_queue->getSoundState() & 2) { strcpy(tmp, "STEAM.SND"); _loopingSoundDuration = 32767; @@ -1727,390 +1352,28 @@ void SoundManager::playLoopingSound(int param) { } } - if (partNumber != 99) { + if (partNumber != 99) sprintf(tmp, "LOOP%d%c.SND", partNumber, _engine->getRandom().getRandomNumber(numLoops[partNumber] - 1) + 'A'); - } } if (getFlags()->flag_3) fnameLen = 5; - if (!*snd || scumm_strnicmp((*snd)->_name2.c_str(), tmp, fnameLen)) { + if (!entry || scumm_strnicmp(entry->_name2.c_str(), tmp, fnameLen)) { _loopingSoundDuration = _engine->getRandom().getRandomNumber(319) + 260; if (partNumber != 99) { playSoundWithSubtitles(tmp, kFlagLoopedSound, kEntitySteam); - if (*snd) - (*snd)->update(0); + if (entry) + entry->update(0); - for (snd = _soundList.begin(); snd != _soundList.end(); ++snd) { - if ((*snd)->getType() == kSoundType1) { - (*snd)->update(7); - break; - } - } + SoundEntry *entry1 = _queue->getEntry(kSoundType1); + if (entry1) + entry1->update(7); } } } } -void SoundManager::stopAllSound() { - Common::StackLock locker(_mutex); - - for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) - (*i)->_soundStream->stop(); -} - -////////////////////////////////////////////////////////////////////////// -// Sound filter -////////////////////////////////////////////////////////////////////////// - -static const int filterData[1424] = { - 0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256, - 384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0, - 192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640, - 64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128, - 320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576, - 704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192, - 192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448, - 576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832, - 320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320, - 320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704, - 832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448, - 448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448, - 640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960, - 1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576, - 576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576, - 576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832, - 960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088, - 1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704, - 704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768, - 768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960, - 1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280, - 1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896, - 896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896, - 896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152, - 1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408, - 1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, - 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088, - 1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088, - 1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152, - 1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152, - 1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408, - 1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536, - 1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728, - 1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856, - 1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344, - 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408, - 1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408, - 1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472, - 1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664, - 1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856, - 1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984, - 2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, - 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664, - 1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664, - 1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728, - 1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728, - 1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984, - 2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112, - 2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304, - 2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432, - 1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920, - 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984, - 1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984, - 1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048, - 2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240, - 2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432, - 2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560, - 2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, - 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240, - 2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240, - 2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304, - 2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304, - 2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560, - 2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688, - 2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880, - 3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008, - 2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496, - 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560, - 2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560, - 2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624, - 2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816, - 2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008, - 3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136, - 3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, - 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816, - 2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816, - 2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880, - 2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880, - 3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136, - 3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264, - 3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456, - 3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584, - 3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072, - 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136, - 3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136, - 3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200, - 3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392, - 3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584, - 3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712, - 3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, - 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392, - 3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392, - 3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456, - 3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456, - 3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712, - 3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840, - 3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032, - 4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160, - 3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648, - 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712, - 3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712, - 3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776, - 3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968, - 4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160, - 4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288, - 4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, - 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968, - 3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968, - 3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032, - 4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032, - 4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288, - 4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416, - 4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608, - 4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736, - 4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224, - 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288, - 4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288, - 4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352, - 4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544, - 4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736, - 4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864, - 4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, - 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544, - 4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544, - 4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608, - 4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608, - 4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864, - 4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992, - 5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184, - 5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312, - 4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800, - 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864, - 4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864, - 4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928, - 5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120, - 5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312, - 5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440, - 5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, - 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120, - 5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120, - 5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184, - 5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184, - 5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440, - 5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568, - 5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, - 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632, - 5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376, - 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440, - 5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440, - 5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, - 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632, - 5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, - 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632, - 5632 -}; - -static const int filterData2[1424] = { - 0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11, - -13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, - -11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5, - -7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18, - -1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12, - 15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4, - 7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19, - -22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14, - -17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5, - -8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26, - 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10, - 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27, - -31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16, - -21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2, - -7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25, - 31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3, - 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34, - -40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17, - -24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50, - 58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21, - 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55, - -63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32, - -41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5, - -15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50, - 61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6, - 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56, - -68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20, - -34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82, - 97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8, - 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74, - -90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9, - -27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70, - 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130, - -150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55, - -77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133, - 157, 181, -12, -36, -60, -84, -109, -133, -157, -181, - 13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93, - -120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191, - 221, -14, -44, -73, -103, -132, -162, -191, -221, 16, - 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113, - -146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232, - 268, -17, -53, -89, -125, -160, -196, -232, -268, 19, - 58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137, - -176, -215, -255, -294, 21, 64, 108, 151, 194, 237, - 281, 324, -21, -64, -108, -151, -194, -237, -281, -324, - 23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118, - -166, -213, -261, -308, -356, 26, 78, 130, 182, 235, - 287, 339, 391, -26, -78, -130, -182, -235, -287, -339, - -391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86, - -143, -201, -258, -316, -373, -431, 31, 94, 158, 221, - 284, 347, 411, 474, -31, -94, -158, -221, -284, -347, - -411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34, - -104, -174, -244, -313, -383, -453, -523, 38, 115, 191, - 268, 345, 422, 498, 575, -38, -115, -191, -268, -345, - -422, -498, -575, 42, 126, 210, 294, 379, 463, 547, - 631, -42, -126, -210, -294, -379, -463, -547, -631, - 46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231, - -324, -417, -510, -602, -695, 51, 153, 255, 357, 459, - 561, 663, 765, -51, -153, -255, -357, -459, -561, -663, - -765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168, - -280, -392, -505, -617, -729, -841, 61, 185, 308, 432, - 555, 679, 802, 926, -61, -185, -308, -432, -555, -679, - -802, -926, 68, 204, 340, 476, 612, 748, 884, 1020, - -68, -204, -340, -476, -612, -748, -884, -1020, 74, - 224, 373, 523, 672, 822, 971, 1121, -74, -224, -373, - -523, -672, -822, -971, -1121, 82, 246, 411, 575, 740, - 904, 1069, 1233, -82, -246, -411, -575, -740, -904, - -1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357, - -90, -271, -452, -633, -814, -995, -1176, -1357, 99, - 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497, - -696, -895, -1094, -1293, -1492, 109, 328, 547, 766, - 985, 1204, 1423, 1642, -109, -328, -547, -766, -985, - -1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324, - 1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564, - -1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132, - -397, -662, -927, -1192, -1457, -1722, -1987, 145, 437, - 728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728, - -1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121, - 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442, - -1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940, - 2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292, - -2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910, - -194, -582, -970, -1358, -1746, -2134, -2522, -2910, - 213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213, - -640, -1066, -1493, -1920, -2347, -2773, -3200, 234, - 704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704, - -1173, -1643, -2112, -2582, -3051, -3521, 258, 774, - 1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291, - -1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988, - 2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556, - -3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436, - 4060, 4685, -312, -937, -1561, -2186, -2811, -3436, - -4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467, - 5154, -343, -1030, -1718, -2405, -3092, -3779, -4467, - -5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, - -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, - 415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415, - -1247, -2079, -2911, -3742, -4574, -5406, -6238, 457, - 1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372, - -2287, -3202, -4117, -5032, -5947, -6862, 503, 1509, - 2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516, - -3522, -4529, -5535, -6542, -7548, 553, 1660, 2767, - 3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874, - -4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479, - 6697, 7915, 9133, -608, -1826, -3044, -4262, -5479, - -6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367, - 8706, 10046, -669, -2009, -3348, -4688, -6027, -7367, - -8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577, - 11051, -736, -2210, -3683, -5157, -6630, -8104, -9577, - -11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, - -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, - 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891, - -2674, -4457, -6240, -8023, -9806, -11589, -13372, 980, - 2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941, - -4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236, - 5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236, - -5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559, - 5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559, - -5933, -8306, -10679, -13052, -15426, -17799, 1305, - 3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305, - -3915, -6526, -9136, -11747, -14357, -16968, -19578, - 1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538, - -1435, -4307, -7179, -10051, -12922, -15794, -18666, - -21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531, - 23690, -1579, -4738, -7896, -11055, -14214, -17373, - -20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111, - 22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111, - -22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022, - 24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022, - -24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124, - 27329, 31533, -2102, -6306, -10511, -14715, -18920, - -23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812, - 25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812, - -25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893, - 27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893, - -27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183, - 30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183, - -30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700, - 32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700, - -32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471, - 32767, 32767, 32767, -3385, -10157, -16928, -23700, - -30471, -32767, -32767, -32767, 3724, 11172, 18621, - 26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621, - -26069, -32767, -32767, -32767, -32767, 4095, 12287, - 20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287, - -20479, -28671, -32767, -32767, -32767, -32767 -}; - -static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 }; -static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 }; - -static void soundFilter(byte *data, int16 *buffer, int p1, int p2); - -void SoundManager::applyFilter(SoundEntry *entry, int16 *buffer) { - if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) { - entry->_status.status |= 0x20000000; - } else { - int variant = entry->_status.status & 0x1f; - - soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]); - } -} - - -static void soundFilter(byte *data, int16 *buffer, int p1, int p2) { - int data1, data2, data1p, data2p; - byte idx; - - data2 = data[0]; - data1 = data[1] << 6; - - data += 2; - - for (int count = 0; count < 735; count++) { - idx = data[count] >> 4; - data1p = filterData[idx + data1]; - data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767); - - buffer[2 * count] = (p2 * data2p) >> p1; - - idx = data[count] & 0xF; - - data1 = filterData[idx + data1p]; - data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767); - buffer[2 * count + 1] = (p2 * data2) >> p1; - } -} - - } // End of namespace LastExpress diff --git a/engines/lastexpress/game/sound.h b/engines/lastexpress/game/sound.h index 414fb0d028..797e52646e 100644 --- a/engines/lastexpress/game/sound.h +++ b/engines/lastexpress/game/sound.h @@ -25,55 +25,18 @@ #include "lastexpress/shared.h" -#include "lastexpress/helpers.h" - -#include "common/list.h" -#include "common/mutex.h" -#include "common/system.h" -#include "common/serializer.h" +#include "common/str.h" namespace LastExpress { class LastExpressEngine; -class SubtitleManager; -class SoundEntry; -class SubtitleEntry; +class SoundQueue; -class SoundManager : Common::Serializable { +class SoundManager { public: SoundManager(LastExpressEngine *engine); ~SoundManager(); - // Timer - void handleTimer(); - - // State - void resetState() { _state |= kSoundType1; } - - // Sound queue - void updateQueue(); - void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone); - void clearQueue(); - - // Subtitles - void updateSubtitles(); - - // Entry - bool isBuffered(Common::String filename, bool testForEntity = false); - bool isBuffered(EntityIndex entity); - void setupEntry(SoundType type, EntityIndex index); - void processEntry(EntityIndex entity); - void processEntry(SoundType type); - void processEntry(Common::String filename); - void processEntries(); - void removeFromQueue(Common::String filename); - void removeFromQueue(EntityIndex entity); - uint32 getEntryTime(EntityIndex index); - - // Misc - void unknownFunction4(); - void clearStatus(); - // Sound playing void playSound(EntityIndex entity, Common::String filename, SoundFlag flag = kFlagInvalid, byte a4 = 0); bool playSoundWithSubtitles(Common::String filename, SoundFlag flag, EntityIndex entity, byte a4 = 0); @@ -83,7 +46,6 @@ public: void playFightSound(byte action, byte a4); void playLocomotiveSound(); void playWarningCompartment(EntityIndex entity, ObjectIndex compartment); - void playLoopingSound(int param); // Dialog & Letters @@ -97,64 +59,16 @@ public: const char *wrongDoorCath() const; const char *justAMinuteCath() const; - // FLags + // Flags SoundFlag getSoundFlag(EntityIndex index) const; - // Debug - void stopAllSound(); - - // Serializable - void saveLoadWithSerializer(Common::Serializer &ser); - uint32 count(); - // Accessors - uint32 getFlag() { return _flag; } - int getSubtitleFlag() { return _subtitlesFlag; } - void setSubtitleFlag(int flag) { _subtitlesFlag = flag; } - SoundType getCurrentType() { return _currentType; } - void setCurrentType(SoundType type) { _currentType = type; } + SoundQueue *getQueue() { return _queue; } uint32 getData2() { return _data2; } - // Subtitles - void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); } - void removeSubtitle(SubtitleEntry *entry) { _subtitles.remove(entry); } - void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; } - SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; } - - // Queue - bool setupCache(SoundEntry *entry); - void addToQueue(SoundEntry *entry) { _soundList.push_back(entry); } - - SoundEntry *getEntry(SoundType type); - private: - typedef int32 *SoundBuffer; - - enum SoundState { - kSoundState0 = 0, - kSoundState1 = 1, - kSoundState2 = 2 - }; - - // Engine LastExpressEngine *_engine; - - // State flag - int _state; - SoundType _currentType; - - Common::Mutex _mutex; - - // Unknown data - uint32 _data0; - uint32 _data1; - uint32 _data2; - - // TODO: this seems to be a synchronization flag for the sound timer - uint32 _flag; - - // Filters - int32 _buffer[2940]; ///< Static sound buffer + SoundQueue *_queue; // Compartment warnings by Mertens or Coudert uint32 _lastWarning[12]; @@ -162,23 +76,10 @@ private: // Looping sound int _loopingSoundDuration; - // Sound entries - Common::List<SoundEntry *> _soundList; ///< List of all sound entries - Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer - void *_soundCacheData; - - SoundEntry *getEntry(EntityIndex index); - SoundEntry *getEntry(Common::String name); - - void removeFromCache(SoundEntry *entry); - - // Subtitles - int _subtitlesFlag; - Common::List<SubtitleEntry *> _subtitles; - SubtitleEntry *_currentSubtitle; - - // Sound filter - void applyFilter(SoundEntry *entry, int16 *buffer); + // Unknown data + uint32 _data0; + uint32 _data1; + uint32 _data2; }; } // End of namespace LastExpress diff --git a/engines/lastexpress/helpers.h b/engines/lastexpress/helpers.h index 594c8b0400..7f3f1e246c 100644 --- a/engines/lastexpress/helpers.h +++ b/engines/lastexpress/helpers.h @@ -63,6 +63,7 @@ // Sound #define getSound() _engine->getSoundManager() +#define getSoundQueue() _engine->getSoundManager()->getQueue() // Others #define getEntityData(entity) getEntities()->getData(entity) diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp index 73893c9982..2829f60740 100644 --- a/engines/lastexpress/lastexpress.cpp +++ b/engines/lastexpress/lastexpress.cpp @@ -32,6 +32,8 @@ #include "lastexpress/menu/menu.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/resource.h" @@ -151,8 +153,8 @@ Common::Error LastExpressEngine::run() { _menu->show(false, kSavegameTypeIndex, 0); while (!shouldQuit()) { - _soundMan->updateQueue(); - _soundMan->updateSubtitles(); + _soundMan->getQueue()->updateQueue(); + _soundMan->getQueue()->updateSubtitles(); if (handleEvents()) continue; @@ -280,7 +282,7 @@ void LastExpressEngine::soundTimer(void *refCon) { void LastExpressEngine::handleSoundTimer() { if (_frameCounter & 1) if (_soundMan) - _soundMan->handleTimer(); + _soundMan->getQueue()->handleTimer(); _frameCounter++; } diff --git a/engines/lastexpress/menu/menu.cpp b/engines/lastexpress/menu/menu.cpp index 74a2c77a01..288e53fc11 100644 --- a/engines/lastexpress/menu/menu.cpp +++ b/engines/lastexpress/menu/menu.cpp @@ -41,6 +41,8 @@ #include "lastexpress/menu/clock.h" #include "lastexpress/menu/trainline.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -336,7 +338,7 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) { if (getFlags()->mouseRightClick) break; - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); } } } @@ -348,10 +350,10 @@ void Menu::show(bool doSavegame, SavegameType type, uint32 value) { init(doSavegame, type, value); // Setup sound - getSound()->unknownFunction4(); - getSound()->resetQueue(kSoundType11, kSoundType13); - if (getSound()->isBuffered("TIMER")) - getSound()->removeFromQueue("TIMER"); + getSoundQueue()->resetQueue(); + getSoundQueue()->resetQueue(kSoundType11, kSoundType13); + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); // Init flags & misc _isShowingCredits = false; @@ -411,13 +413,13 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) { if (clicked) { showFrame(kOverlayButtons, kButtonQuitPushed, true); - getSound()->clearStatus(); - getSound()->updateQueue(); + getSoundQueue()->clearStatus(); + getSoundQueue()->updateQueue(); getSound()->playSound(kEntityPlayer, "LIB046"); // FIXME uncomment when sound queue is properly implemented - /*while (getSound()->isBuffered("LIB046")) - getSound()->updateQueue();*/ + /*while (getSoundQueue()->isBuffered("LIB046")) + getSoundQueue()->updateQueue();*/ getFlags()->shouldRedraw = false; @@ -484,7 +486,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) { setLogicEventHandlers(); if (_index) { - getSound()->processEntry(kSoundType11); + getSoundQueue()->processEntry(kSoundType11); } else { if (!getFlags()->mouseRightClick) { getScenes()->loadScene((SceneIndex)(5 * _gameId + 3)); @@ -496,7 +498,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) { getScenes()->loadScene((SceneIndex)(5 * _gameId + 5)); if (!getFlags()->mouseRightClick) { - getSound()->processEntry(kSoundType11); + getSoundQueue()->processEntry(kSoundType11); // Show intro Animation animation; @@ -512,7 +514,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) { if (!getEvent(kEventIntro)) { getEvent(kEventIntro) = 1; - getSound()->processEntry(kSoundType11); + getSoundQueue()->processEntry(kSoundType11); } } @@ -707,7 +709,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) { while (nextFrameCount > getFrameCount()) { _engine->pollEvents(); - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); } } else { showFrame(kOverlayButtons, kButtonVolumeDown, true); @@ -742,7 +744,7 @@ bool Menu::handleEvent(StartMenuAction action, Common::EventType type) { while (nextFrameCount > getFrameCount()) { _engine->pollEvents(); - getSound()->updateQueue(); + getSoundQueue()->updateQueue(); } } else { showFrame(kOverlayButtons, kButtonVolumeUp, true); @@ -1117,8 +1119,8 @@ void Menu::updateTime(uint32 time) { _currentTime = time; if (_time != time) { - if (getSound()->isBuffered(kEntityChapters)) - getSound()->removeFromQueue(kEntityChapters); + if (getSoundQueue()->isBuffered(kEntityChapters)) + getSoundQueue()->removeFromQueue(kEntityChapters); getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", kFlagMenuClock, kEntityChapters); adjustIndex(_currentTime, _time, false); @@ -1249,8 +1251,8 @@ void Menu::adjustTime() { _time = _currentTime; } - if (_currentTime == _time && getSound()->isBuffered(kEntityChapters)) - getSound()->removeFromQueue(kEntityChapters); + if (_currentTime == _time && getSoundQueue()->isBuffered(kEntityChapters)) + getSoundQueue()->removeFromQueue(kEntityChapters); _clock->draw(_time); _trainLine->draw(_time); diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk index eff68efb73..355ecba33b 100644 --- a/engines/lastexpress/module.mk +++ b/engines/lastexpress/module.mk @@ -67,6 +67,7 @@ MODULE_OBJS := \ menu/menu.o \ menu/trainline.o \ sound/entry.o \ + sound/queue.o \ debug.o \ detection.o \ graphics.o \ diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h index d1730eefce..69816a3d6c 100644 --- a/engines/lastexpress/shared.h +++ b/engines/lastexpress/shared.h @@ -83,6 +83,12 @@ enum SoundFlag { kFlagType9 = 0x7000000 }; +enum SoundState { + kSoundState0 = 0, + kSoundState1 = 1, + kSoundState2 = 2 +}; + ////////////////////////////////////////////////////////////////////////// // Time values ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp index 304d524f45..817416110e 100644 --- a/engines/lastexpress/sound/entry.cpp +++ b/engines/lastexpress/sound/entry.cpp @@ -27,6 +27,8 @@ #include "lastexpress/game/sound.h" #include "lastexpress/game/state.h" +#include "lastexpress/sound/queue.h" + #include "lastexpress/graphics.h" #include "lastexpress/helpers.h" #include "lastexpress/lastexpress.h" @@ -70,6 +72,7 @@ SoundEntry::~SoundEntry() { delete _soundStream; + // Zero passed pointers _engine = NULL; } @@ -79,10 +82,10 @@ void SoundEntry::open(Common::String name, SoundFlag flag, int priority) { setStatus(flag); // Add entry to sound list - getSound()->addToQueue(this); + getSoundQueue()->addToQueue(this); // Add entry to cache and load sound data - getSound()->setupCache(this); + getSoundQueue()->setupCache(this); loadSoundData(name); } @@ -90,7 +93,7 @@ void SoundEntry::close() { _status.status |= kSoundStatusRemoved; // Loop until ready - while (!(_status.status1 & 4) && !(getSound()->getFlag() & 8) && (getSound()->getFlag() & 1)) + while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1)) ; // empty loop body // The original game remove the entry from the cache here, @@ -115,16 +118,16 @@ void SoundEntry::setType(SoundFlag flag) { switch (flag & kFlagType9) { default: case kFlagNone: - _type = getSound()->getCurrentType(); - getSound()->setCurrentType((SoundType)(_type + 1)); + _type = getSoundQueue()->getCurrentType(); + getSoundQueue()->setCurrentType((SoundType)(_type + 1)); break; case kFlagType1_2: { - SoundEntry *previous2 = getSound()->getEntry(kSoundType2); + SoundEntry *previous2 = getSoundQueue()->getEntry(kSoundType2); if (previous2) previous2->update(0); - SoundEntry *previous = getSound()->getEntry(kSoundType1); + SoundEntry *previous = getSoundQueue()->getEntry(kSoundType1); if (previous) { previous->setType(kSoundType2); previous->update(0); @@ -135,7 +138,7 @@ void SoundEntry::setType(SoundFlag flag) { break; case kFlagType3: { - SoundEntry *previous = getSound()->getEntry(kSoundType3); + SoundEntry *previous = getSoundQueue()->getEntry(kSoundType3); if (previous) { previous->setType(kSoundType4); previous->update(0); @@ -146,7 +149,7 @@ void SoundEntry::setType(SoundFlag flag) { break; case kFlagType7: { - SoundEntry *previous = getSound()->getEntry(kSoundType7); + SoundEntry *previous = getSoundQueue()->getEntry(kSoundType7); if (previous) previous->setType(kSoundType8); @@ -155,7 +158,7 @@ void SoundEntry::setType(SoundFlag flag) { break; case kFlagType9: { - SoundEntry *previous = getSound()->getEntry(kSoundType9); + SoundEntry *previous = getSoundQueue()->getEntry(kSoundType9); if (previous) previous->setType(kSoundType10); @@ -164,7 +167,7 @@ void SoundEntry::setType(SoundFlag flag) { break; case kFlagType11: { - SoundEntry *previous = getSound()->getEntry(kSoundType11); + SoundEntry *previous = getSoundQueue()->getEntry(kSoundType11); if (previous) previous->setType(kSoundType14); @@ -173,7 +176,7 @@ void SoundEntry::setType(SoundFlag flag) { break; case kFlagType13: { - SoundEntry *previous = getSound()->getEntry(kSoundType13); + SoundEntry *previous = getSoundQueue()->getEntry(kSoundType13); if (previous) previous->setType(kSoundType14); @@ -221,7 +224,7 @@ void SoundEntry::update(uint val) { _status.status |= kSoundStatus_100000; if (val) { - if (getSound()->getFlag() & 32) { + if (getSoundQueue()->getFlag() & 32) { _field_40 = val; value2 = val * 2 + 1; } @@ -235,7 +238,7 @@ void SoundEntry::update(uint val) { } void SoundEntry::updateState() { - if (getSound()->getFlag() & 32) { + if (getSoundQueue()->getFlag() & 32) { if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) { uint32 newStatus = _status.status & kSoundStatusClear1; @@ -318,7 +321,7 @@ SubtitleEntry::~SubtitleEntry() { void SubtitleEntry::load(Common::String filename, SoundEntry *soundEntry) { // Add ourselves to the list of active subtitles - getSound()->addSubtitle(this); + getSoundQueue()->addSubtitle(this); // Set sound entry and filename _filename = filename + ".SBE"; @@ -326,7 +329,7 @@ void SubtitleEntry::load(Common::String filename, SoundEntry *soundEntry) { // Load subtitle data if (_engine->getResourceManager()->hasFile(filename)) { - if (getSound()->getSubtitleFlag() & 2) + if (getSoundQueue()->getSubtitleFlag() & 2) return; loadData(); @@ -339,8 +342,8 @@ void SubtitleEntry::loadData() { _data = new SubtitleManager(_engine->getFont()); _data->load(getArchive(_filename)); - getSound()->setSubtitleFlag(getSound()->getSubtitleFlag() | 2); - getSound()->setCurrentSubtitle(this); + getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() | 2); + getSoundQueue()->setCurrentSubtitle(this); } void SubtitleEntry::setupAndDraw() { @@ -354,32 +357,32 @@ void SubtitleEntry::setupAndDraw() { } else { _data->setTime((uint16)_sound->_time); - if (getSound()->getSubtitleFlag() & 1) + if (getSoundQueue()->getSubtitleFlag() & 1) drawOnScreen(); } - getSound()->setCurrentSubtitle(this); + getSoundQueue()->setCurrentSubtitle(this); } void SubtitleEntry::draw() { // Remove ourselves from the queue - getSound()->removeSubtitle(this); + getSoundQueue()->removeSubtitle(this); - if (this == getSound()->getCurrentSubtitle()) { + if (this == getSoundQueue()->getCurrentSubtitle()) { drawOnScreen(); - getSound()->setCurrentSubtitle(NULL); - getSound()->setSubtitleFlag(0); + getSoundQueue()->setCurrentSubtitle(NULL); + getSoundQueue()->setSubtitleFlag(0); } } void SubtitleEntry::drawOnScreen() { - getSound()->setSubtitleFlag(getSound()->getSubtitleFlag() & -1); + getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() & -1); if (_data == NULL) return; - if (getSound()->getSubtitleFlag() & 1) + if (getSoundQueue()->getSubtitleFlag() & 1) _engine->getGraphicsManager()->draw(_data, GraphicsManager::kBackgroundOverlay); } diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp new file mode 100644 index 0000000000..9126f5709d --- /dev/null +++ b/engines/lastexpress/sound/queue.cpp @@ -0,0 +1,795 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "lastexpress/sound/queue.h" + +#include "lastexpress/game/logic.h" +#include "lastexpress/game/state.h" + +#include "lastexpress/sound/entry.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" + +namespace LastExpress { + +#define SOUNDCACHE_ENTRY_SIZE 92160 +#define SOUNDCACHE_MAX_SIZE 6 + +SoundQueue::SoundQueue(LastExpressEngine *engine) : _engine(engine) { + _state = 0; + _currentType = kSoundType16; + _flag = 0; + + // Cache and filter buffers + memset(&_buffer, 0, sizeof(_buffer)); + _soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE); + + _subtitlesFlag = 0; + _currentSubtitle = NULL; +} + +SoundQueue::~SoundQueue() { + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + SAFE_DELETE(*i); + _soundList.clear(); + + // Entries in the cache are just pointers to sound list entries + _soundCache.clear(); + + for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) + SAFE_DELETE(*i); + _subtitles.clear(); + + _currentSubtitle = NULL; + + free(_soundCacheData); + + // Zero passed pointers + _engine = NULL; +} + +////////////////////////////////////////////////////////////////////////// +// Timer +////////////////////////////////////////////////////////////////////////// +void SoundQueue::handleTimer() { + Common::StackLock locker(_mutex); + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + SoundEntry *entry = (*i); + if (entry->_stream == NULL) { + SAFE_DELETE(*i); + i = _soundList.reverse_erase(i); + continue; + } else if (!entry->_soundStream) { + entry->_soundStream = new StreamedSound(); + + // TODO: stream any sound in the queue after filtering + entry->_soundStream->load(entry->_stream); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// Sound queue management +////////////////////////////////////////////////////////////////////////// +void SoundQueue::addToQueue(SoundEntry *entry) { + _soundList.push_back(entry); +} + +void SoundQueue::removeFromQueue(EntityIndex entity) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(entity); + if (entry) + entry->reset(); +} + +void SoundQueue::removeFromQueue(Common::String filename) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(filename); + if (entry) + entry->reset(); +} + +void SoundQueue::updateQueue() { + Common::StackLock locker(_mutex); + + warning("Sound::updateQueue: not implemented!"); +} + +void SoundQueue::resetQueue() { + Common::StackLock locker(_mutex); + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + if ((*i)->getType() == kSoundType1) { + (*i)->reset(); + break; + } + } + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + if ((*i)->getType() == kSoundType2) { + (*i)->reset(); + break; + } + } +} + +void SoundQueue::resetQueue(SoundType type1, SoundType type2) { + if (!type2) + type2 = type1; + + Common::StackLock locker(_mutex); + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + if ((*i)->getType() != type1 && (*i)->getType() != type2) + (*i)->reset(); + } +} + +void SoundQueue::clearQueue() { + _flag |= 4; + + // FIXME: Wait a while for a flag to be set + //for (int i = 0; i < 3000000; i++) + // if (_flag & 8) + // break; + + _flag |= 8; + + Common::StackLock locker(_mutex); + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + SoundEntry *entry = (*i); + + // Delete entry + entry->close(); + SAFE_DELETE(entry); + + i = _soundList.reverse_erase(i); + } + + updateSubtitles(); +} + +////////////////////////////////////////////////////////////////////////// +// State +////////////////////////////////////////////////////////////////////////// +void SoundQueue::clearStatus() { + Common::StackLock locker(_mutex); + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + (*i)->_status.status |= kSoundStatusClear3; +} + +////////////////////////////////////////////////////////////////////////// +// Entry management +////////////////////////////////////////////////////////////////////////// +void SoundQueue::setupEntry(SoundType type, EntityIndex index) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(type); + if (entry) + entry->setEntity(index); +} + +void SoundQueue::processEntry(EntityIndex entity) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(entity); + if (entry) { + entry->update(0); + entry->setEntity(kEntityPlayer); + } +} + +void SoundQueue::processEntry(SoundType type) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(type); + if (entry) + entry->update(0); +} + +void SoundQueue::processEntry(Common::String filename) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(filename); + if (entry) { + entry->update(0); + entry->setEntity(kEntityPlayer); + } +} + +void SoundQueue::processEntries() { + _state = 0; + + processEntry(kSoundType1); + processEntry(kSoundType2); +} + +SoundEntry *SoundQueue::getEntry(EntityIndex index) { + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + if ((*i)->getEntity() == index) + return *i; + } + + return NULL; +} + +SoundEntry *SoundQueue::getEntry(Common::String name) { + if (!name.contains('.')) + name += ".SND"; + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + if ((*i)->_name2 == name) + return *i; + } + + return NULL; +} + +SoundEntry *SoundQueue::getEntry(SoundType type) { + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) { + if ((*i)->getType() == type) + return *i; + } + + return NULL; +} + +uint32 SoundQueue::getEntryTime(EntityIndex index) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(index); + if (entry) + return entry->_time; + + return 0; +} + +bool SoundQueue::isBuffered(EntityIndex entity) { + Common::StackLock locker(_mutex); + + return (getEntry(entity) != NULL); +} + +bool SoundQueue::isBuffered(Common::String filename, bool testForEntity) { + Common::StackLock locker(_mutex); + + SoundEntry *entry = getEntry(filename); + + if (testForEntity) + return entry != NULL && entry->getEntity() != kEntityPlayer; + + return (entry != NULL); +} + +////////////////////////////////////////////////////////////////////////// +// Subtitles +////////////////////////////////////////////////////////////////////////// +void SoundQueue::updateSubtitles() { + Common::StackLock locker(_mutex); + + uint32 index = 0; + SubtitleEntry *subtitle = NULL; + + for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + uint32 current_index = 0; + SoundEntry *soundEntry = (*i)->getSoundEntry(); + SoundStatus status = (SoundStatus)soundEntry->_status.status; + + if (!(status & kSoundStatus_40) + || status & kSoundStatus_180 + || soundEntry->_time == 0 + || (status & kSoundStatusClear1) < 6 + || ((getFlags()->nis & 0x8000) && soundEntry->_priority < 90)) { + current_index = 0; + } else { + current_index = soundEntry->_priority + (status & kSoundStatusClear1); + + if (_currentSubtitle == (*i)) + current_index += 4; + } + + if (index < current_index) { + index = current_index; + subtitle = (*i); + } + } + + if (_currentSubtitle == subtitle) { + if (subtitle) + subtitle->setupAndDraw(); + + return; + } + + if (_subtitlesFlag & 1) + subtitle->drawOnScreen(); + + if (subtitle) { + subtitle->loadData(); + subtitle->setupAndDraw(); + } +} + +////////////////////////////////////////////////////////////////////////// +// Cache +////////////////////////////////////////////////////////////////////////// +bool SoundQueue::setupCache(SoundEntry *entry) { + if (entry->_soundData) + return true; + + if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) { + + SoundEntry *cacheEntry = NULL; + uint32 size = 1000; + + for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) { + if (!((*i)->_status.status & kSoundStatus_180)) { + uint32 newSize = (*i)->_priority + ((*i)->_status.status & kSoundStatusClear1); + + if (newSize < size) { + cacheEntry = (*i); + size = newSize; + } + } + } + + if (entry->_priority <= size) + return false; + + if (!cacheEntry) + error("[SoundManager::setupCache] Cannot find a valid entry"); + + cacheEntry->setInCache(); + + // TODO: Wait until the cache entry is ready to be removed + while (!(cacheEntry->_status.status1 & 1)) + ; + + if (cacheEntry->_soundData) + removeFromCache(cacheEntry); + + _soundCache.push_back(entry); + entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1); + } else { + _soundCache.push_back(entry); + entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1); + } + + return true; +} + +void SoundQueue::removeFromCache(SoundEntry *entry) { + for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) { + if ((*i) == entry) { + // Remove sound buffer + entry->_soundData = NULL; + + // Remove entry from sound cache + i = _soundCache.reverse_erase(i); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// Savegame +////////////////////////////////////////////////////////////////////////// +void SoundQueue::saveLoadWithSerializer(Common::Serializer &s) { + Common::StackLock locker(_mutex); + + s.syncAsUint32LE(_state); + s.syncAsUint32LE(_currentType); + + // Compute the number of entries to save + uint32 numEntries = count(); + s.syncAsUint32LE(numEntries); + + // Save or load each entry data + if (s.isSaving()) { + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + (*i)->saveLoadWithSerializer(s); + } else { + warning("Sound::saveLoadWithSerializer: loading not implemented"); + s.skip(numEntries * 64); + } +} + + +// FIXME: We probably need another mutex here to protect during the whole savegame process +// as we could have removed an entry between the time we check the count and the time we +// save the entries +uint32 SoundQueue::count() { + Common::StackLock locker(_mutex); + + uint32 numEntries = 0; + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + if ((*i)->_name2.matchString("NISSND?")) + ++numEntries; + + return numEntries; +} + +////////////////////////////////////////////////////////////////////////// +// Sound filters +////////////////////////////////////////////////////////////////////////// +static const int filterData[1424] = { + 0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256, + 384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0, + 192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640, + 64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128, + 320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576, + 704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192, + 192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448, + 576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832, + 320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320, + 320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704, + 832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448, + 448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448, + 640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960, + 1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576, + 576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576, + 576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832, + 960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088, + 1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704, + 704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768, + 768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960, + 1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280, + 1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896, + 896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896, + 896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152, + 1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408, + 1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, + 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088, + 1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088, + 1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152, + 1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152, + 1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408, + 1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536, + 1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728, + 1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856, + 1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344, + 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408, + 1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408, + 1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472, + 1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664, + 1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856, + 1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984, + 2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, + 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664, + 1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664, + 1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728, + 1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728, + 1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984, + 2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112, + 2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304, + 2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432, + 1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920, + 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984, + 1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984, + 1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048, + 2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240, + 2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432, + 2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560, + 2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, + 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240, + 2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240, + 2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304, + 2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304, + 2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560, + 2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688, + 2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880, + 3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008, + 2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496, + 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560, + 2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560, + 2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624, + 2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816, + 2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008, + 3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136, + 3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, + 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816, + 2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816, + 2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880, + 2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880, + 3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136, + 3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264, + 3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456, + 3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584, + 3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072, + 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136, + 3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136, + 3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200, + 3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392, + 3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584, + 3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712, + 3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, + 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392, + 3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392, + 3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456, + 3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456, + 3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712, + 3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840, + 3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032, + 4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160, + 3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648, + 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712, + 3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712, + 3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776, + 3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968, + 4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160, + 4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288, + 4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, + 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968, + 3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968, + 3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032, + 4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032, + 4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288, + 4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416, + 4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608, + 4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736, + 4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224, + 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288, + 4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288, + 4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352, + 4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544, + 4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736, + 4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864, + 4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, + 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544, + 4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544, + 4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608, + 4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608, + 4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864, + 4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992, + 5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184, + 5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312, + 4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800, + 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864, + 4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864, + 4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928, + 5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120, + 5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312, + 5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440, + 5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, + 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120, + 5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120, + 5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184, + 5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184, + 5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440, + 5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568, + 5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, + 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632, + 5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376, + 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440, + 5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440, + 5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, + 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632, + 5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, + 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632, + 5632 +}; + +static const int filterData2[1424] = { + 0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11, + -13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, + -11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5, + -7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18, + -1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12, + 15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4, + 7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19, + -22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14, + -17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5, + -8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26, + 30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10, + 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27, + -31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16, + -21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2, + -7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25, + 31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3, + 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34, + -40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17, + -24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50, + 58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21, + 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55, + -63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32, + -41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5, + -15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50, + 61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6, + 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56, + -68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20, + -34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82, + 97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8, + 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74, + -90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9, + -27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70, + 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130, + -150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55, + -77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133, + 157, 181, -12, -36, -60, -84, -109, -133, -157, -181, + 13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93, + -120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191, + 221, -14, -44, -73, -103, -132, -162, -191, -221, 16, + 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113, + -146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232, + 268, -17, -53, -89, -125, -160, -196, -232, -268, 19, + 58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137, + -176, -215, -255, -294, 21, 64, 108, 151, 194, 237, + 281, 324, -21, -64, -108, -151, -194, -237, -281, -324, + 23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118, + -166, -213, -261, -308, -356, 26, 78, 130, 182, 235, + 287, 339, 391, -26, -78, -130, -182, -235, -287, -339, + -391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86, + -143, -201, -258, -316, -373, -431, 31, 94, 158, 221, + 284, 347, 411, 474, -31, -94, -158, -221, -284, -347, + -411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34, + -104, -174, -244, -313, -383, -453, -523, 38, 115, 191, + 268, 345, 422, 498, 575, -38, -115, -191, -268, -345, + -422, -498, -575, 42, 126, 210, 294, 379, 463, 547, + 631, -42, -126, -210, -294, -379, -463, -547, -631, + 46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231, + -324, -417, -510, -602, -695, 51, 153, 255, 357, 459, + 561, 663, 765, -51, -153, -255, -357, -459, -561, -663, + -765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168, + -280, -392, -505, -617, -729, -841, 61, 185, 308, 432, + 555, 679, 802, 926, -61, -185, -308, -432, -555, -679, + -802, -926, 68, 204, 340, 476, 612, 748, 884, 1020, + -68, -204, -340, -476, -612, -748, -884, -1020, 74, + 224, 373, 523, 672, 822, 971, 1121, -74, -224, -373, + -523, -672, -822, -971, -1121, 82, 246, 411, 575, 740, + 904, 1069, 1233, -82, -246, -411, -575, -740, -904, + -1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357, + -90, -271, -452, -633, -814, -995, -1176, -1357, 99, + 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497, + -696, -895, -1094, -1293, -1492, 109, 328, 547, 766, + 985, 1204, 1423, 1642, -109, -328, -547, -766, -985, + -1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324, + 1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564, + -1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132, + -397, -662, -927, -1192, -1457, -1722, -1987, 145, 437, + 728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728, + -1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121, + 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442, + -1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940, + 2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292, + -2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910, + -194, -582, -970, -1358, -1746, -2134, -2522, -2910, + 213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213, + -640, -1066, -1493, -1920, -2347, -2773, -3200, 234, + 704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704, + -1173, -1643, -2112, -2582, -3051, -3521, 258, 774, + 1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291, + -1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988, + 2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556, + -3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436, + 4060, 4685, -312, -937, -1561, -2186, -2811, -3436, + -4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467, + 5154, -343, -1030, -1718, -2405, -3092, -3779, -4467, + -5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670, + -378, -1134, -1890, -2646, -3402, -4158, -4914, -5670, + 415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415, + -1247, -2079, -2911, -3742, -4574, -5406, -6238, 457, + 1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372, + -2287, -3202, -4117, -5032, -5947, -6862, 503, 1509, + 2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516, + -3522, -4529, -5535, -6542, -7548, 553, 1660, 2767, + 3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874, + -4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479, + 6697, 7915, 9133, -608, -1826, -3044, -4262, -5479, + -6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367, + 8706, 10046, -669, -2009, -3348, -4688, -6027, -7367, + -8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577, + 11051, -736, -2210, -3683, -5157, -6630, -8104, -9577, + -11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157, + -810, -2431, -4052, -5673, -7294, -8915, -10536, -12157, + 891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891, + -2674, -4457, -6240, -8023, -9806, -11589, -13372, 980, + 2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941, + -4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236, + 5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236, + -5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559, + 5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559, + -5933, -8306, -10679, -13052, -15426, -17799, 1305, + 3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305, + -3915, -6526, -9136, -11747, -14357, -16968, -19578, + 1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538, + -1435, -4307, -7179, -10051, -12922, -15794, -18666, + -21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531, + 23690, -1579, -4738, -7896, -11055, -14214, -17373, + -20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111, + 22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111, + -22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022, + 24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022, + -24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124, + 27329, 31533, -2102, -6306, -10511, -14715, -18920, + -23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812, + 25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812, + -25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893, + 27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893, + -27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183, + 30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183, + -30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700, + 32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700, + -32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471, + 32767, 32767, 32767, -3385, -10157, -16928, -23700, + -30471, -32767, -32767, -32767, 3724, 11172, 18621, + 26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621, + -26069, -32767, -32767, -32767, -32767, 4095, 12287, + 20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287, + -20479, -28671, -32767, -32767, -32767, -32767 +}; + +static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 }; +static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 }; + +static void soundFilter(byte *data, int16 *buffer, int p1, int p2); + +void SoundQueue::applyFilter(SoundEntry *entry, int16 *buffer) { + if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) { + entry->_status.status |= 0x20000000; + } else { + int variant = entry->_status.status & 0x1f; + + soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]); + } +} + + +static void soundFilter(byte *data, int16 *buffer, int p1, int p2) { + int data1, data2, data1p, data2p; + byte idx; + + data2 = data[0]; + data1 = data[1] << 6; + + data += 2; + + for (int count = 0; count < 735; count++) { + idx = data[count] >> 4; + data1p = filterData[idx + data1]; + data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767); + + buffer[2 * count] = (p2 * data2p) >> p1; + + idx = data[count] & 0xF; + + data1 = filterData[idx + data1p]; + data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767); + buffer[2 * count + 1] = (p2 * data2) >> p1; + } +} + +////////////////////////////////////////////////////////////////////////// +// Debug +////////////////////////////////////////////////////////////////////////// +void SoundQueue::stopAllSound() { + Common::StackLock locker(_mutex); + + for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) + (*i)->_soundStream->stop(); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/sound/queue.h b/engines/lastexpress/sound/queue.h new file mode 100644 index 0000000000..3748a266e0 --- /dev/null +++ b/engines/lastexpress/sound/queue.h @@ -0,0 +1,131 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef LASTEXPRESS_SOUND_QUEUE_H +#define LASTEXPRESS_SOUND_QUEUE_H + +#include "lastexpress/shared.h" + +#include "common/array.h" +#include "common/mutex.h" +#include "common/serializer.h" + +namespace LastExpress { + +class LastExpressEngine; +class SoundEntry; +class SubtitleEntry; + +class SoundQueue : Common::Serializable { +public: + SoundQueue(LastExpressEngine *engine); + ~SoundQueue(); + + // Timer + void handleTimer(); + + // Queue + void addToQueue(SoundEntry *entry); + void removeFromQueue(Common::String filename); + void removeFromQueue(EntityIndex entity); + void updateQueue(); + void resetQueue(); + void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone); + void clearQueue(); + + // State + void clearStatus(); + int getSoundState() { return _state; } + void resetState() { resetState(kSoundState1); } + void resetState(SoundState state) { _state |= state; } + + // Entries + void setupEntry(SoundType type, EntityIndex index); + void processEntry(EntityIndex entity); + void processEntry(SoundType type); + void processEntry(Common::String filename); + void processEntries(); + SoundEntry *getEntry(SoundType type); + SoundEntry *getEntry(EntityIndex index); + SoundEntry *getEntry(Common::String name); + uint32 getEntryTime(EntityIndex index); + bool isBuffered(Common::String filename, bool testForEntity = false); + bool isBuffered(EntityIndex entity); + + // Subtitles + void updateSubtitles(); + void addSubtitle(SubtitleEntry *entry) { _subtitles.push_back(entry); } + void removeSubtitle(SubtitleEntry *entry) { _subtitles.remove(entry); } + void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; } + SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; } + + // Cache + bool setupCache(SoundEntry *entry); + + // Serializable + void saveLoadWithSerializer(Common::Serializer &ser); + uint32 count(); + + // Accessors + uint32 getFlag() { return _flag; } + int getSubtitleFlag() { return _subtitlesFlag; } + void setSubtitleFlag(int flag) { _subtitlesFlag = flag; } + SoundType getCurrentType() { return _currentType; } + void setCurrentType(SoundType type) { _currentType = type; } + +protected: + // Debug + void stopAllSound(); + +private: + LastExpressEngine *_engine; + + Common::Mutex _mutex; + + // State & shared data + int _state; + SoundType _currentType; + // TODO: this seems to be a synchronization flag for the sound timer + uint32 _flag; + + // Entries + Common::List<SoundEntry *> _soundList; ///< List of all sound entries + Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer + void *_soundCacheData; + + // Subtitles + int _subtitlesFlag; + Common::List<SubtitleEntry *> _subtitles; + SubtitleEntry *_currentSubtitle; + + // Filters + int32 _buffer[2940]; ///< Static sound buffer + + void removeFromCache(SoundEntry *entry); + void applyFilter(SoundEntry *entry, int16 *buffer); + + friend class Debugger; +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_SOUND_QUEUE_H |