From 4719fd99007df8b4e20b93484a2229e32aed6261 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 20 May 2012 09:22:14 +1000 Subject: COMMON: Fix comparison operation on coroutine wait methods --- common/coroutines.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/coroutines.cpp b/common/coroutines.cpp index d511ab4b35..4a45f2ec23 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -386,7 +386,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio *expired = true; // Outer loop for doing checks until expiry - while (g_system->getMillis() < _ctx->endTime) { + while (g_system->getMillis() <= _ctx->endTime) { // Check to see if a process or event with the given Id exists _ctx->pProcess = getProcess(pid); _ctx->pEvent = !_ctx->pProcess ? getEvent(pid) : NULL; @@ -456,7 +456,7 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 * *expired = true; // Outer loop for doing checks until expiry - while (g_system->getMillis() < _ctx->endTime) { + while (g_system->getMillis() <= _ctx->endTime) { _ctx->signalled = bWaitAll; for (_ctx->i = 0; _ctx->i < nCount; ++_ctx->i) { -- cgit v1.2.3 From 839527a9553e94234a1eb802648a4ed64e926a5c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 25 May 2012 23:13:55 +1000 Subject: COMMON: Fix method error messages --- common/coroutines.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/coroutines.cpp b/common/coroutines.cpp index 4a45f2ec23..aff13a5494 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -433,7 +433,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, uint32 duration, bool *expired) { if (!pCurrent) - error("Called CoroutineScheduler::waitForMultipleEvents from the main process"); + error("Called CoroutineScheduler::waitForMultipleObjects from the main process"); CORO_BEGIN_CONTEXT; uint32 endTime; @@ -505,7 +505,7 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 * */ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) { if (!pCurrent) - error("Called CoroutineScheduler::waitForSingleObject from the main process"); + error("Called CoroutineScheduler::sleep from the main process"); CORO_BEGIN_CONTEXT; uint32 endTime; -- cgit v1.2.3 From a2b51174aad31f66280da91e9c7ec25babd045e6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 25 May 2012 23:36:18 +1000 Subject: COMMON: Cleaned up coroutine comments --- common/coroutines.cpp | 58 +++++++++++++++++++++++++++++++-------------------- common/coroutines.h | 4 +++- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/common/coroutines.cpp b/common/coroutines.cpp index aff13a5494..b1b08c6bae 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -37,11 +37,15 @@ DECLARE_SINGLETON(CoroutineScheduler); #ifdef COROUTINE_DEBUG namespace { +/** Count of active coroutines */ static int s_coroCount = 0; typedef Common::HashMap CoroHashMap; static CoroHashMap *s_coroFuncs = 0; +/** + * Change the current coroutine status + */ static void changeCoroStats(const char *func, int change) { if (!s_coroFuncs) s_coroFuncs = new CoroHashMap(); @@ -49,6 +53,9 @@ static void changeCoroStats(const char *func, int change) { (*s_coroFuncs)[func] += change; } +/** + * Display the details of active coroutines + */ static void displayCoroStats() { debug("%d active coros", s_coroCount); @@ -65,6 +72,9 @@ static void displayCoroStats() { } #endif +/** + * Creates a coroutine context + */ CoroBaseContext::CoroBaseContext(const char *func) : _line(0), _sleep(0), _subctx(0) { #ifdef COROUTINE_DEBUG @@ -74,6 +84,9 @@ CoroBaseContext::CoroBaseContext(const char *func) #endif } +/** + * Destructor for coroutine context + */ CoroBaseContext::~CoroBaseContext() { #ifdef COROUTINE_DEBUG s_coroCount--; @@ -499,7 +512,7 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 * /** * Make the active process sleep for the given duration in milliseconds - * @param duration Duration in milliseconds + * @param duration Duration in milliseconds * @remarks This duration won't be precise, since it relies on the frequency the * scheduler is called. */ @@ -530,9 +543,9 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) { * Creates a new process. * * @param pid process identifier - * @param CORO_ADDR coroutine start address - * @param pParam process specific info - * @param sizeParam size of process specific info + * @param CORO_ADDR Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info */ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam) { PROCESS *pProc; @@ -601,9 +614,9 @@ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const /** * Creates a new process with an auto-incrementing Process Id. * - * @param CORO_ADDR coroutine start address - * @param pParam process specific info - * @param sizeParam size of process specific info + * @param CORO_ADDR Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info */ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam) { PROCESS *pProc = createProcess(++pidCounter, coroAddr, pParam, sizeParam); @@ -613,9 +626,9 @@ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam, /** * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter. * - * @param CORO_ADDR coroutine start address - * @param pParam process specific info - * @param sizeParam size of process specific info + * @param CORO_ADDR Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info */ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam) { return createProcess(coroAddr, &pParam, sizeof(void *)); @@ -625,7 +638,7 @@ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam) /** * Kills the specified process. * - * @param pKillProc which process to kill + * @param pKillProc Which process to kill */ void CoroutineScheduler::killProcess(PROCESS *pKillProc) { // make sure a valid process pointer @@ -674,7 +687,7 @@ PROCESS *CoroutineScheduler::getCurrentProcess() { /** * Returns the process identifier of the specified process. * - * @param pProc which process + * @param pProc Which process */ int CoroutineScheduler::getCurrentPID() const { PROCESS *pProc = pCurrent; @@ -690,9 +703,9 @@ int CoroutineScheduler::getCurrentPID() const { * Kills any process matching the specified PID. The current * process cannot be killed. * - * @param pidKill process identifier of process to kill - * @param pidMask mask to apply to process identifiers before comparison - * @return The number of processes killed is returned. + * @param pidKill Process identifier of process to kill + * @param pidMask Mask to apply to process identifiers before comparison + * @return The number of processes killed is returned. */ int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) { int numKilled = 0; @@ -750,7 +763,7 @@ int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) { * called by killProcess() to allow the resource allocator to free * resources allocated to the dying process. * - * @param pFunc Function to be called by killProcess() + * @param pFunc Function to be called by killProcess() */ void CoroutineScheduler::setResourceCallback(VFPTRPP pFunc) { pRCfunction = pFunc; @@ -778,9 +791,9 @@ EVENT *CoroutineScheduler::getEvent(uint32 pid) { /** * Creates a new event object - * @param bManualReset Events needs to be manually reset. Otherwise, events + * @param bManualReset Events needs to be manually reset. Otherwise, events * will be automatically reset after a process waits on the event finishes - * @param bInitialState Specifies whether the event is signalled or not initially + * @param bInitialState Specifies whether the event is signalled or not initially */ uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) { EVENT *evt = new EVENT(); @@ -794,7 +807,7 @@ uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) { /** * Destroys the given event - * @param pidEvent Event PID + * @param pidEvent Event Process Id */ void CoroutineScheduler::closeEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); @@ -806,7 +819,7 @@ void CoroutineScheduler::closeEvent(uint32 pidEvent) { /** * Sets the event - * @param pidEvent Event PID + * @param pidEvent Event Process Id */ void CoroutineScheduler::setEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); @@ -816,7 +829,7 @@ void CoroutineScheduler::setEvent(uint32 pidEvent) { /** * Resets the event - * @param pidEvent Event PID + * @param pidEvent Event Process Id */ void CoroutineScheduler::resetEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); @@ -827,7 +840,7 @@ void CoroutineScheduler::resetEvent(uint32 pidEvent) { /** * Temporarily sets a given event to true, and then runs all waiting processes, allowing any * processes waiting on the event to be fired. It then immediately resets the event again. - * @param pidEvent Event PID + * @param pidEvent Event Process Id * * @remarks Should not be run inside of another process */ @@ -880,5 +893,4 @@ void CoroutineScheduler::pulseEvent(uint32 pidEvent) { evt->signalled = false; } - } // end of namespace Common diff --git a/common/coroutines.h b/common/coroutines.h index 6df843887c..06af245ba7 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -65,7 +65,8 @@ typedef CoroBaseContext *CoroContext; /** This is a special constant that can be temporarily used as a parameter to call coroutine-ised * from methods from methods that haven't yet been converted to being a coroutine, so code at least - * compiles correctly. Be aware, though, that if you use this, you will get runtime errors. + * compiles correctly. Be aware, though, that an error will occur if a coroutine that was passed + * the nullContext tries to sleep or yield control. */ extern CoroContext nullContext; @@ -283,6 +284,7 @@ public: #define CORO_INFINITE 0xffffffff #define CORO_INVALID_PID_VALUE 0 +/** Coroutine parameter for methods converted to coroutines */ typedef void (*CORO_ADDR)(CoroContext &, const void *); /** process structure */ -- cgit v1.2.3 From da3f0ba44829708c35278341395285786b095c98 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 28 May 2012 20:16:39 -0400 Subject: SCUMM: Fix error in spyfox iOS credits --- engines/scumm/he/script_v90he.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index 0beebdb7a1..9e8ac7e2f2 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -2373,8 +2373,8 @@ void ScummEngine_v90he::o90_kernelSetFunctions() { case 2001: _logicHE->dispatch(args[1], num - 2, (int32 *)&args[2]); break; - case 201102: - // Used in puttzoo iOS + case 201102: // Used in puttzoo iOS + case 20111014: // Used in spyfox iOS break; default: error("o90_kernelSetFunctions: default case %d (param count %d)", args[0], num); -- cgit v1.2.3 From e35e4a1f686a982e67247f5de0537ce44ed791cd Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Tue, 29 May 2012 10:58:06 +1000 Subject: SCUMM: Add Macintosh UK version of Freddi Fish 4. --- devtools/scumm-md5.txt | 2 +- engines/scumm/detection_tables.h | 3 ++- engines/scumm/scumm-md5.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt index 99e23f7aca..f08b7d29d2 100644 --- a/devtools/scumm-md5.txt +++ b/devtools/scumm-md5.txt @@ -540,8 +540,8 @@ freddi3 Freddi Fish 3: The Case of the Stolen Conch Shell freddi4 Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch 4f580a021eee026f3b4589e17d130d78 -1 All All - - - Kirben, sev 14d48c95b43ddeb983254cf6c43851f1 -1 nl All - - - adutchguy, daniel9 + 3b832f4a90740bf22e9b8ed42ca0128c -1 gb All HE 99 - - Reckless d74122362a77ec24525fdd50297dfd82 -1 fr Mac - - - ThierryFR - 3b832f4a90740bf22e9b8ed42ca0128c -1 gb Windows HE 99 - - Reckless 07b810e37be7489263f7bc7627d4765d -1 ru Windows unenc Unencrypted - sev a336134914eaab4892d35625aa15ad1d -1 ru Windows HE 99 - - George Kormendi b5298a5c15ffbe8b381d51ea4e26d35c -1 de All HE 99 - - Joachim Eberhard diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index f48b40dd48..34ec6b6543 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -704,7 +704,8 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "freddi4", "Freddi 4 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi4", "FreddiGS", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "freddi4", "FreddiGS", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, - { "freddi4", "FreddiHRBG", kGenHEPC, UNK_LANG, UNK, 0 }, + { "freddi4", "FreddiHRBG", kGenHEPC, Common::EN_GRB, UNK, 0 }, + { "freddi4", "FreddiHRBG", kGenHEMac, Common::EN_GRB, Common::kPlatformMacintosh, 0 }, { "freddi4", "FreddiMini", kGenHEPC, UNK_LANG, UNK, 0 }, { "freddi4", "Malice4", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, { "freddi4", "MaliceMRC", kGenHEPC, Common::FR_FRA, UNK, 0 }, diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index f719f7df19..946e954a46 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Mon May 28 18:17:29 2012 + This file was generated by the md5table tool on Tue May 29 00:49:03 2012 DO NOT EDIT MANUALLY! */ @@ -174,7 +174,7 @@ static const MD5Table md5table[] = { { "3ae7f002d9256b8bdf76aaf8a3a069f8", "freddi", "HE 100", "", 34837, Common::EN_GRB, Common::kPlatformWii }, { "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows }, { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC }, - { "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows }, + { "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformUnknown }, { "3c4c471342bd95505a42334367d8f127", "puttmoon", "HE 70", "", 12161, Common::RU_RUS, Common::kPlatformWindows }, { "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformPC }, { "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, -- cgit v1.2.3 From 5ba886ce8b3dc5b543d81e3f3a655b328749d778 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 29 May 2012 21:43:23 +1000 Subject: COMMON: Fixed CORO_ADDR parameter names in Doxygen comments --- common/coroutines.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/coroutines.cpp b/common/coroutines.cpp index b1b08c6bae..6159bdc0f3 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -542,8 +542,8 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) { /** * Creates a new process. * - * @param pid process identifier - * @param CORO_ADDR Coroutine start address + * @param pid process identifier + * @param coroAddr Coroutine start address * @param pParam Process specific info * @param sizeParam Size of process specific info */ @@ -614,7 +614,7 @@ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const /** * Creates a new process with an auto-incrementing Process Id. * - * @param CORO_ADDR Coroutine start address + * @param coroAddr Coroutine start address * @param pParam Process specific info * @param sizeParam Size of process specific info */ @@ -626,7 +626,7 @@ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam, /** * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter. * - * @param CORO_ADDR Coroutine start address + * @param coroAddr Coroutine start address * @param pParam Process specific info * @param sizeParam Size of process specific info */ -- cgit v1.2.3 From 415831987d542e249ef9032fdab49bece24934fa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 29 May 2012 21:51:10 +1000 Subject: COMMON: Copied coroutine doxygen method descriptions to the header file --- common/coroutines.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/common/coroutines.h b/common/coroutines.h index 06af245ba7..5daec4b426 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -356,7 +356,6 @@ private: PROCESS *getProcess(uint32 pid); EVENT *getEvent(uint32 pid); public: - CoroutineScheduler(); ~CoroutineScheduler(); @@ -366,31 +365,62 @@ public: void printStats(); #endif + /** Give all active processes a chance to run */ void schedule(); + + /** Reschedules all the processes to run again this tick */ void rescheduleAll(); + + /** If the specified process has already run on this tick, make it run again on the current tick. */ void reschedule(PPROCESS pReSchedProc = NULL); + + /** Moves the specified process to the end of the dispatch queue, so it can again in the current tick */ void giveWay(PPROCESS pReSchedProc = NULL); + + /** Continously makes a given process wait for another process to finish or event to signal. */ void waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired = NULL); + + /** Continously makes a given process wait for given prcesses to finished or events to be set */ void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, uint32 duration, bool *expired = NULL); - void sleep(CORO_PARAM, uint32 duration); + /** Make the active process sleep for the given duration in milliseconds */ + void sleep(CORO_PARAM, uint32 duration); + + /** Creates a new process. */ PROCESS *createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam); uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam); uint32 createProcess(CORO_ADDR coroAddr, const void *pParam); + + /** Kills the specified process. */ void killProcess(PROCESS *pKillProc); + /** Returns a pointer to the currently running process. */ PROCESS *getCurrentProcess(); + + /** Returns the process identifier of the specified process. */ int getCurrentPID() const; + + /** Kills any process matching the specified PID. The current process cannot be killed. */ int killMatchingProcess(uint32 pidKill, int pidMask = -1); + /** Set pointer to a function to be called by killProcess() */ void setResourceCallback(VFPTRPP pFunc); /* Event methods */ + /** Creates a new event (semaphore) object */ uint32 createEvent(bool bManualReset, bool bInitialState); + + /** Destroys the given event */ void closeEvent(uint32 pidEvent); + + /** Sets the event */ void setEvent(uint32 pidEvent); + + /** Resets the event */ void resetEvent(uint32 pidEvent); + + /** Temporarily sets a given event to true, allowing other waiting processes to fire */ void pulseEvent(uint32 pidEvent); }; -- cgit v1.2.3 From aa7c44a070ac6b33411749b66014f80a953b70c5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 29 May 2012 14:16:31 +0200 Subject: GOB: Hook up the PE cursors to v7 loadCursor Addy Junior / Adibou2 now shows proper cursors. Thanks to clone2727 for the constant nagging. :P --- engines/gob/draw.cpp | 14 ++++++ engines/gob/draw.h | 7 +++ engines/gob/draw_v2.cpp | 39 ++++++++++----- engines/gob/inter.h | 10 +++- engines/gob/inter_v7.cpp | 125 +++++++++++++++++++++++++++++++++++++++++------ engines/gob/surface.cpp | 12 +++++ engines/gob/surface.h | 1 + engines/gob/video.cpp | 5 +- 8 files changed, 182 insertions(+), 31 deletions(-) diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 4b659f51de..545c790fb8 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -117,6 +117,13 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _cursorAnimDelays[i] = 0; } + _cursorPalettes = 0; + _cursorKeyColors = 0; + _cursorPaletteStarts = 0; + _cursorPaletteCounts = 0; + _cursorHotspotsX = 0; + _cursorHotspotsY = 0; + _palLoadData1[0] = 0; _palLoadData1[1] = 17; _palLoadData1[2] = 34; @@ -134,6 +141,13 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { } Draw::~Draw() { + delete[] _cursorPalettes; + delete[] _cursorKeyColors; + delete[] _cursorPaletteStarts; + delete[] _cursorPaletteCounts; + delete[] _cursorHotspotsX; + delete[] _cursorHotspotsY; + for (int i = 0; i < kFontCount; i++) delete _fonts[i]; } diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 393822c33a..2d2c7fd0e7 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -145,6 +145,13 @@ public: int8 _cursorAnimHigh[40]; int8 _cursorAnimDelays[40]; + byte *_cursorPalettes; + byte *_cursorKeyColors; + uint16 *_cursorPaletteStarts; + uint16 *_cursorPaletteCounts; + int32 *_cursorHotspotsX; + int32 *_cursorHotspotsY; + int16 _palLoadData1[4]; int16 _palLoadData2[4]; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 78702f2ec9..cf82df9c71 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -83,7 +83,7 @@ void Draw_v2::blitCursor() { void Draw_v2::animateCursor(int16 cursor) { int16 cursorIndex = cursor; int16 newX = 0, newY = 0; - uint16 hotspotX = 0, hotspotY = 0; + uint16 hotspotX, hotspotY; _showCursor |= 1; @@ -133,27 +133,42 @@ void Draw_v2::animateCursor(int16 cursor) { } // '------ - newX = _vm->_global->_inter_mouseX; - newY = _vm->_global->_inter_mouseY; + hotspotX = 0; + hotspotY = 0; + if (_cursorHotspotXVar != -1) { - newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar); - newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); + hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar); + hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); } else if (_cursorHotspotX != -1) { - newX -= hotspotX = _cursorHotspotX; - newY -= hotspotY = _cursorHotspotY; + hotspotX = _cursorHotspotX; + hotspotY = _cursorHotspotY; + } else if (_cursorHotspotsX != 0) { + hotspotX = _cursorHotspotsX[_cursorIndex]; + hotspotY = _cursorHotspotsY[_cursorIndex]; } + newX = _vm->_global->_inter_mouseX - hotspotX; + newY = _vm->_global->_inter_mouseY - hotspotY; + _scummvmCursor->clear(); _scummvmCursor->blit(*_cursorSprites, cursorIndex * _cursorWidth, 0, (cursorIndex + 1) * _cursorWidth - 1, _cursorHeight - 1, 0, 0); - if ((_vm->getGameType() != kGameTypeAdibou2) && - (_vm->getGameType() != kGameTypeAdi2) && - (_vm->getGameType() != kGameTypeAdi4)) - CursorMan.replaceCursor(_scummvmCursor->getData(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat()); + uint32 keyColor = 0; + if (_cursorKeyColors) + keyColor = _cursorKeyColors[cursorIndex]; + + CursorMan.replaceCursor(_scummvmCursor->getData(), + _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat()); + + if (_cursorPalettes) { + CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3), + _cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]); + CursorMan.disableCursorPalette(false); + } else + CursorMan.disableCursorPalette(true); if (_frontSurface != _backSurface) { if (!_noInvalidated) { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index c79b6e2260..ded016543e 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -31,6 +31,10 @@ #include "gob/iniconfig.h" #include "gob/databases.h" +namespace Common { + class PEResources; +} + namespace Gob { class Cheater_Geisha; @@ -648,7 +652,7 @@ private: class Inter_v7 : public Inter_Playtoons { public: Inter_v7(GobEngine *vm); - virtual ~Inter_v7() {} + virtual ~Inter_v7(); protected: virtual void setupOpcodesDraw(); @@ -684,7 +688,11 @@ private: INIConfig _inis; Databases _databases; + Common::PEResources *_cursors; + Common::String findFile(const Common::String &mask); + + bool loadCursorFile(); }; } // End of namespace Gob diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp index 81547f7362..71e4ac07ad 100644 --- a/engines/gob/inter_v7.cpp +++ b/engines/gob/inter_v7.cpp @@ -22,8 +22,11 @@ #include "common/endian.h" #include "common/archive.h" +#include "common/winexe.h" +#include "common/winexe_pe.h" #include "graphics/cursorman.h" +#include "graphics/wincursor.h" #include "gob/gob.h" #include "gob/global.h" @@ -42,7 +45,11 @@ namespace Gob { #define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) #define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) -Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm) { +Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm), _cursors(0) { +} + +Inter_v7::~Inter_v7() { + delete _cursors; } void Inter_v7::setupOpcodesDraw() { @@ -88,25 +95,100 @@ void Inter_v7::o7_draw0x0C() { void Inter_v7::o7_loadCursor() { int16 cursorIndex = _vm->_game->_script->readValExpr(); - Common::String cursorFile = _vm->_game->_script->evalString(); + Common::String cursorName = _vm->_game->_script->evalString(); + + // Clear the cursor sprite at that index + _vm->_draw->_cursorSprites->fillRect(cursorIndex * _vm->_draw->_cursorWidth, 0, + cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, + _vm->_draw->_cursorHeight - 1, 0); + + Graphics::WinCursorGroup *cursorGroup = 0; + Graphics::Cursor *defaultCursor = 0; + + // Load the cursor file and cursor group + if (loadCursorFile()) + cursorGroup = Graphics::WinCursorGroup::createCursorGroup(*_cursors, Common::WinResourceID(cursorName)); + + // If the requested cursor does not exist, create a default one + const Graphics::Cursor *cursor = 0; + if (!cursorGroup || cursorGroup->cursors.empty() || !cursorGroup->cursors[0].cursor) { + defaultCursor = Graphics::makeDefaultWinCursor(); - warning("Addy Stub: Load cursor \"%s\" to %d", cursorFile.c_str(), cursorIndex); + cursor = defaultCursor; + } else + cursor = cursorGroup->cursors[0].cursor; - byte cursor[9]; - byte palette[6]; + // Cursor sprite dimensions mismatch, recreate the cursor sprites + if ((cursor->getWidth() > _vm->_draw->_cursorWidth ) || + (cursor->getHeight() > _vm->_draw->_cursorHeight) || + (_vm->_draw->_cursorSprites->getWidth() < ((cursorIndex + 1) * _vm->_draw->_cursorWidth)) || + !_vm->_draw->_cursorPalettes) { - cursor[0] = 0; cursor[1] = 0; cursor[2] = 0; - cursor[3] = 0; cursor[4] = 1; cursor[5] = 0; - cursor[6] = 0; cursor[7] = 0; cursor[8] = 0; + const int count = cursorIndex + 1; - palette[0] = 0; palette[1] = 0; palette[2] = 0; - palette[3] = 255; palette[4] = 255; palette[5] = 255; + _vm->_draw->freeSprite(Draw::kCursorSurface); + _vm->_draw->_cursorSprites.reset(); + _vm->_draw->_cursorSpritesBack.reset(); + _vm->_draw->_scummvmCursor.reset(); - CursorMan.pushCursorPalette(palette, 0, 2); - CursorMan.disableCursorPalette(false); - CursorMan.replaceCursor(cursor, 3, 3, 1, 1, 255); + _vm->_draw->_cursorWidth = MAX(cursor->getWidth() , _vm->_draw->_cursorWidth); + _vm->_draw->_cursorHeight = MAX(cursor->getHeight(), _vm->_draw->_cursorHeight); - CursorMan.showMouse(true); + _vm->_draw->_transparentCursor = 1; + + _vm->_draw->initSpriteSurf(Draw::kCursorSurface, _vm->_draw->_cursorWidth * count, + _vm->_draw->_cursorHeight, 2); + + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; + + _vm->_draw->_scummvmCursor = + _vm->_video->initSurfDesc(_vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); + + for (int i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + _vm->_draw->_cursorAnimLow[1] = 0; + + delete[] _vm->_draw->_cursorPalettes; + delete[] _vm->_draw->_cursorKeyColors; + delete[] _vm->_draw->_cursorPaletteStarts; + delete[] _vm->_draw->_cursorPaletteCounts; + delete[] _vm->_draw->_cursorHotspotsX; + delete[] _vm->_draw->_cursorHotspotsY; + + _vm->_draw->_cursorPalettes = new byte[256 * 3 * count]; + _vm->_draw->_cursorKeyColors = new byte[count]; + _vm->_draw->_cursorPaletteStarts = new uint16[count]; + _vm->_draw->_cursorPaletteCounts = new uint16[count]; + _vm->_draw->_cursorHotspotsX = new int32[count]; + _vm->_draw->_cursorHotspotsY = new int32[count]; + + memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3); + memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte)); + memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32)); + memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32)); + } + + Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface()); + + _vm->_draw->_cursorSprites->blit(cursorSurf, 0, 0, cursor->getWidth() - 1, cursor->getHeight() - 1, + cursorIndex * _vm->_draw->_cursorWidth, 0, 0); + + memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3); + + _vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor(); + _vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex(); + _vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount(); + _vm->_draw->_cursorHotspotsX [cursorIndex] = cursor->getHotspotX(); + _vm->_draw->_cursorHotspotsY [cursorIndex] = cursor->getHotspotY(); + + delete cursorGroup; + delete defaultCursor; } void Inter_v7::o7_displayWarning() { @@ -529,4 +611,19 @@ Common::String Inter_v7::findFile(const Common::String &mask) { return files.front()->getName(); } +bool Inter_v7::loadCursorFile() { + if (_cursors) + return true; + + _cursors = new Common::PEResources(); + + if (_cursors->loadFromEXE("cursor32.dll")) + return true; + + delete _cursors; + _cursors = 0; + + return false; +} + } // End of namespace Gob diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index e294209ed7..3af19f891d 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -280,6 +280,18 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) : _ownVidMem = false; } +Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) : + _width(width), _height(height), _bpp(bpp), _vidMem(0) { + + assert((_width > 0) && (_height > 0)); + assert((_bpp == 1) || (_bpp == 2)); + + _vidMem = new byte[_bpp * _width * _height]; + _ownVidMem = true; + + memcpy(_vidMem, vidMem, _bpp * _width * _height); +} + Surface::~Surface() { if (_ownVidMem) delete[] _vidMem; diff --git a/engines/gob/surface.h b/engines/gob/surface.h index 866e63490f..5376603801 100644 --- a/engines/gob/surface.h +++ b/engines/gob/surface.h @@ -122,6 +122,7 @@ private: class Surface { public: Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem = 0); + Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem); ~Surface(); uint16 getWidth () const; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index ee5ff4abff..c865b2b40e 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -226,10 +226,7 @@ void Video::setSize(bool defaultTo1XScaler) { void Video::retrace(bool mouse) { if (mouse) - if ((_vm->getGameType() != kGameTypeAdibou2) && - (_vm->getGameType() != kGameTypeAdi2) && - (_vm->getGameType() != kGameTypeAdi4)) - CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); + CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); if (_vm->_global->_primarySurfDesc) { int screenX = _screenDeltaX; -- cgit v1.2.3 From be25e31a0a2da25c586a16a16ba9d55053f21524 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 29 May 2012 17:12:06 +0200 Subject: GOB: Fix v7 cursors drawn by the scripts When the cursor name is "", then that cursor is drawn by the scripts instead of loaded from cursor32.dll. That cursor does not have its own palette then. Fixes the cursors in the "paint" game in Adibou2. --- engines/gob/draw.cpp | 3 ++ engines/gob/draw.h | 2 + engines/gob/draw_v2.cpp | 4 +- engines/gob/inter.h | 1 + engines/gob/inter_v7.cpp | 133 +++++++++++++++++++++++++++-------------------- 5 files changed, 84 insertions(+), 59 deletions(-) diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 545c790fb8..fe59b11f76 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -117,6 +117,8 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _cursorAnimDelays[i] = 0; } + _cursorCount = 0; + _doCursorPalettes = 0; _cursorPalettes = 0; _cursorKeyColors = 0; _cursorPaletteStarts = 0; @@ -142,6 +144,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { Draw::~Draw() { delete[] _cursorPalettes; + delete[] _doCursorPalettes; delete[] _cursorKeyColors; delete[] _cursorPaletteStarts; delete[] _cursorPaletteCounts; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 2d2c7fd0e7..24c5550ea5 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -145,6 +145,8 @@ public: int8 _cursorAnimHigh[40]; int8 _cursorAnimDelays[40]; + int32 _cursorCount; + bool *_doCursorPalettes; byte *_cursorPalettes; byte *_cursorKeyColors; uint16 *_cursorPaletteStarts; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index cf82df9c71..ab9a90de8f 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -157,13 +157,13 @@ void Draw_v2::animateCursor(int16 cursor) { _cursorHeight - 1, 0, 0); uint32 keyColor = 0; - if (_cursorKeyColors) + if (_doCursorPalettes && _cursorKeyColors && _doCursorPalettes[cursorIndex]) keyColor = _cursorKeyColors[cursorIndex]; CursorMan.replaceCursor(_scummvmCursor->getData(), _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat()); - if (_cursorPalettes) { + if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) { CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3), _cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]); CursorMan.disableCursorPalette(false); diff --git a/engines/gob/inter.h b/engines/gob/inter.h index ded016543e..1e6f74db4e 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -693,6 +693,7 @@ private: Common::String findFile(const Common::String &mask); bool loadCursorFile(); + void resizeCursors(int16 width, int16 height, int16 count, bool transparency); }; } // End of namespace Gob diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp index 71e4ac07ad..6cf69ed9df 100644 --- a/engines/gob/inter_v7.cpp +++ b/engines/gob/inter_v7.cpp @@ -93,6 +93,70 @@ void Inter_v7::o7_draw0x0C() { WRITE_VAR(17, 0); } +void Inter_v7::resizeCursors(int16 width, int16 height, int16 count, bool transparency) { + if (width <= 0) + width = _vm->_draw->_cursorWidth; + if (height <= 0) + height = _vm->_draw->_cursorHeight; + + width = MAX(width , _vm->_draw->_cursorWidth); + height = MAX(height, _vm->_draw->_cursorHeight); + + _vm->_draw->_transparentCursor = transparency; + + // Cursors sprite already big enough + if ((_vm->_draw->_cursorWidth >= width) && (_vm->_draw->_cursorHeight >= height) && + (_vm->_draw->_cursorCount >= count)) + return; + + _vm->_draw->_cursorCount = count; + _vm->_draw->_cursorWidth = width; + _vm->_draw->_cursorHeight = height; + + _vm->_draw->freeSprite(Draw::kCursorSurface); + _vm->_draw->_cursorSprites.reset(); + _vm->_draw->_cursorSpritesBack.reset(); + _vm->_draw->_scummvmCursor.reset(); + + _vm->_draw->initSpriteSurf(Draw::kCursorSurface, width * count, height, 2); + + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; + + _vm->_draw->_scummvmCursor = _vm->_video->initSurfDesc(width, height, SCUMMVM_CURSOR); + + for (int i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + _vm->_draw->_cursorAnimLow[1] = 0; + + delete[] _vm->_draw->_doCursorPalettes; + delete[] _vm->_draw->_cursorPalettes; + delete[] _vm->_draw->_cursorKeyColors; + delete[] _vm->_draw->_cursorPaletteStarts; + delete[] _vm->_draw->_cursorPaletteCounts; + delete[] _vm->_draw->_cursorHotspotsX; + delete[] _vm->_draw->_cursorHotspotsY; + + _vm->_draw->_cursorPalettes = new byte[256 * 3 * count]; + _vm->_draw->_doCursorPalettes = new bool[count]; + _vm->_draw->_cursorKeyColors = new byte[count]; + _vm->_draw->_cursorPaletteStarts = new uint16[count]; + _vm->_draw->_cursorPaletteCounts = new uint16[count]; + _vm->_draw->_cursorHotspotsX = new int32[count]; + _vm->_draw->_cursorHotspotsY = new int32[count]; + + memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3); + memset(_vm->_draw->_doCursorPalettes , 0, count * sizeof(bool)); + memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte)); + memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32)); + memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32)); +} + void Inter_v7::o7_loadCursor() { int16 cursorIndex = _vm->_game->_script->readValExpr(); Common::String cursorName = _vm->_game->_script->evalString(); @@ -102,6 +166,14 @@ void Inter_v7::o7_loadCursor() { cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, _vm->_draw->_cursorHeight - 1, 0); + // If the cursor name is empty, that cursor will be drawn by the scripts + if (cursorName.empty()) { + // Make sure the cursors sprite is big enough and set to non-extern palette + resizeCursors(-1, -1, cursorIndex + 1, true); + _vm->_draw->_doCursorPalettes[cursorIndex] = false; + return; + } + Graphics::WinCursorGroup *cursorGroup = 0; Graphics::Cursor *defaultCursor = 0; @@ -118,69 +190,16 @@ void Inter_v7::o7_loadCursor() { } else cursor = cursorGroup->cursors[0].cursor; - // Cursor sprite dimensions mismatch, recreate the cursor sprites - if ((cursor->getWidth() > _vm->_draw->_cursorWidth ) || - (cursor->getHeight() > _vm->_draw->_cursorHeight) || - (_vm->_draw->_cursorSprites->getWidth() < ((cursorIndex + 1) * _vm->_draw->_cursorWidth)) || - !_vm->_draw->_cursorPalettes) { - - const int count = cursorIndex + 1; - - _vm->_draw->freeSprite(Draw::kCursorSurface); - _vm->_draw->_cursorSprites.reset(); - _vm->_draw->_cursorSpritesBack.reset(); - _vm->_draw->_scummvmCursor.reset(); - - _vm->_draw->_cursorWidth = MAX(cursor->getWidth() , _vm->_draw->_cursorWidth); - _vm->_draw->_cursorHeight = MAX(cursor->getHeight(), _vm->_draw->_cursorHeight); - - _vm->_draw->_transparentCursor = 1; - - _vm->_draw->initSpriteSurf(Draw::kCursorSurface, _vm->_draw->_cursorWidth * count, - _vm->_draw->_cursorHeight, 2); - - _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; - _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; - - _vm->_draw->_scummvmCursor = - _vm->_video->initSurfDesc(_vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); - - for (int i = 0; i < 40; i++) { - _vm->_draw->_cursorAnimLow[i] = -1; - _vm->_draw->_cursorAnimDelays[i] = 0; - _vm->_draw->_cursorAnimHigh[i] = 0; - } - _vm->_draw->_cursorAnimLow[1] = 0; - - delete[] _vm->_draw->_cursorPalettes; - delete[] _vm->_draw->_cursorKeyColors; - delete[] _vm->_draw->_cursorPaletteStarts; - delete[] _vm->_draw->_cursorPaletteCounts; - delete[] _vm->_draw->_cursorHotspotsX; - delete[] _vm->_draw->_cursorHotspotsY; - - _vm->_draw->_cursorPalettes = new byte[256 * 3 * count]; - _vm->_draw->_cursorKeyColors = new byte[count]; - _vm->_draw->_cursorPaletteStarts = new uint16[count]; - _vm->_draw->_cursorPaletteCounts = new uint16[count]; - _vm->_draw->_cursorHotspotsX = new int32[count]; - _vm->_draw->_cursorHotspotsY = new int32[count]; - - memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3); - memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte)); - memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16)); - memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16)); - memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32)); - memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32)); - } + // Make sure the cursors sprite it big enough + resizeCursors(cursor->getWidth(), cursor->getHeight(), cursorIndex + 1, true); Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface()); - _vm->_draw->_cursorSprites->blit(cursorSurf, 0, 0, cursor->getWidth() - 1, cursor->getHeight() - 1, - cursorIndex * _vm->_draw->_cursorWidth, 0, 0); + _vm->_draw->_cursorSprites->blit(cursorSurf, cursorIndex * _vm->_draw->_cursorWidth, 0); memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3); + _vm->_draw->_doCursorPalettes [cursorIndex] = true; _vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor(); _vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex(); _vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount(); -- cgit v1.2.3 From 96ae10c7491aed3258912ef91c8787b7975376ad Mon Sep 17 00:00:00 2001 From: D G Turner Date: Wed, 30 May 2012 03:53:52 +0100 Subject: DREAMWEB: Removal of dead code and cleanup in sound code. The removed blocks in the playChannel functions referencing index are non-functional leftovers from more complex logic in the original code structure, and thus can be safely removed. --- engines/dreamweb/sound.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp index b3d5db9e0d..fcbcb9d0a0 100644 --- a/engines/dreamweb/sound.cpp +++ b/engines/dreamweb/sound.cpp @@ -40,7 +40,6 @@ bool DreamWebEngine::loadSpeech(byte type1, int idx1, byte type2, int idx2) { return result; } - void DreamWebEngine::volumeAdjust() { if (_volumeDirection == 0) return; @@ -57,9 +56,6 @@ void DreamWebEngine::volumeAdjust() { void DreamWebEngine::playChannel0(uint8 index, uint8 repeat) { debug(1, "playChannel0(index:%d, repeat:%d)", index, repeat); _channel0Playing = index; - if (index >= 12) - index -= 12; - _channel0Repeat = repeat; } @@ -68,14 +64,12 @@ void DreamWebEngine::playChannel1(uint8 index) { return; _channel1Playing = index; - if (index >= 12) - index -= 12; } void DreamWebEngine::cancelCh0() { debug(1, "cancelCh0()"); - _channel0Repeat = 0; _channel0Playing = 255; + _channel0Repeat = 0; stopSound(0); } @@ -104,11 +98,6 @@ void DreamWebEngine::loadRoomsSample() { loadSounds(1, sampleSuffix.c_str()); } -} // End of namespace DreamWeb - - -namespace DreamWeb { - void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) { debug(1, "playSound(%u, %u, %u)", channel, id, loops); -- cgit v1.2.3 From ae31469a9aa7163c4ed42414fbb2c6c95e2d7e8a Mon Sep 17 00:00:00 2001 From: D G Turner Date: Wed, 30 May 2012 04:23:34 +0100 Subject: DREAMWEB: Replaced vsync() function with waitForVSync(). As a call to waitForVSync() was the only contents of vsync(), there should be no functional change. --- engines/dreamweb/dreamweb.h | 1 - engines/dreamweb/keypad.cpp | 12 ++++++------ engines/dreamweb/monitor.cpp | 6 +++--- engines/dreamweb/newplace.cpp | 2 +- engines/dreamweb/object.cpp | 2 +- engines/dreamweb/print.cpp | 16 ++++++++-------- engines/dreamweb/saveload.cpp | 8 ++++---- engines/dreamweb/stubs.cpp | 22 +++++++++++----------- engines/dreamweb/talk.cpp | 4 ++-- engines/dreamweb/titles.cpp | 18 +++++++++--------- engines/dreamweb/vgafades.cpp | 2 +- engines/dreamweb/vgagrafx.cpp | 4 ---- 12 files changed, 46 insertions(+), 51 deletions(-) diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h index 6744b53ebc..468a1f58a8 100644 --- a/engines/dreamweb/dreamweb.h +++ b/engines/dreamweb/dreamweb.h @@ -1135,7 +1135,6 @@ public: void frameOutBh(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y); void frameOutFx(uint8 *dst, const uint8 *src, uint16 pitch, uint16 width, uint16 height, uint16 x, uint16 y); void doShake(); - void vSync(); void setMode(); void showPCX(const Common::String &suffix); void showFrameInternal(const uint8 *pSrc, uint16 x, uint16 y, uint8 effectsFlag, uint8 width, uint8 height); diff --git a/engines/dreamweb/keypad.cpp b/engines/dreamweb/keypad.cpp index 2ab5835997..002588cb70 100644 --- a/engines/dreamweb/keypad.cpp +++ b/engines/dreamweb/keypad.cpp @@ -62,11 +62,11 @@ void DreamWebEngine::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 d readMouse(); showKeypad(); showPointer(); - vSync(); + waitForVSync(); if (_pressCount == 0) { _pressed = 255; _graphicPress = 255; - vSync(); + waitForVSync(); } else --_pressCount; @@ -252,7 +252,7 @@ void DreamWebEngine::useMenu() { showMenu(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpMenu(); dumpTextLine(); @@ -311,7 +311,7 @@ void DreamWebEngine::viewFolder() { delPointer(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); checkFolderCoords(); @@ -508,7 +508,7 @@ void DreamWebEngine::enterSymbol() { showSymbol(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); dumpSymbol(); @@ -743,7 +743,7 @@ void DreamWebEngine::useDiary() { readMouse(); showDiaryKeys(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpDiaryKeys(); dumpTextLine(); diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp index 25435ae0e9..4c66e7a599 100644 --- a/engines/dreamweb/monitor.cpp +++ b/engines/dreamweb/monitor.cpp @@ -202,7 +202,7 @@ void DreamWebEngine::input() { _cursLocY = _monAdY; while (true) { printCurs(); - vSync(); + waitForVSync(); delCurs(); readKey(); if (_quitRequested) @@ -318,8 +318,8 @@ void DreamWebEngine::accessLightOff() { void DreamWebEngine::randomAccess(uint16 count) { for (uint16 i = 0; i < count; ++i) { - vSync(); - vSync(); + waitForVSync(); + waitForVSync(); uint16 v = _rnd.getRandomNumber(15); if (v < 10) accessLightOff(); diff --git a/engines/dreamweb/newplace.cpp b/engines/dreamweb/newplace.cpp index 529c45bd4a..ab6537422a 100644 --- a/engines/dreamweb/newplace.cpp +++ b/engines/dreamweb/newplace.cpp @@ -65,7 +65,7 @@ void DreamWebEngine::selectLocation() { delPointer(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp index 443366561a..b42591ef91 100644 --- a/engines/dreamweb/object.cpp +++ b/engines/dreamweb/object.cpp @@ -147,7 +147,7 @@ void DreamWebEngine::examineOb(bool examineAgain) { readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); delPointer(); diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp index a6b93a5590..a96d1f9d58 100644 --- a/engines/dreamweb/print.cpp +++ b/engines/dreamweb/print.cpp @@ -197,7 +197,7 @@ uint8 DreamWebEngine::kernChars(uint8 firstChar, uint8 secondChar, uint8 width) uint16 DreamWebEngine::waitFrames() { readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); delPointer(); return _mouseButton; @@ -231,7 +231,7 @@ const char *DreamWebEngine::monPrint(const char *string) { _cursLocY = _monAdY; _mainTimer = 1; printCurs(); - vSync(); + waitForVSync(); lockMon(); delCurs(); } while (--count); @@ -261,9 +261,9 @@ void DreamWebEngine::rollEndCreditsGameWon() { // then move it up one pixel until we shifted it by a complete // line of text. for (int j = 0; j < linespacing; ++j) { - vSync(); + waitForVSync(); multiPut(_mapStore, 75, 20, 160, 160); - vSync(); + waitForVSync(); // Output up to 18 lines of text uint16 y = 10 - j; @@ -273,7 +273,7 @@ void DreamWebEngine::rollEndCreditsGameWon() { y += linespacing; } - vSync(); + waitForVSync(); multiDump(75, 20, 160, 160); } @@ -300,9 +300,9 @@ void DreamWebEngine::rollEndCreditsGameLost() { // then move it up one pixel until we shifted it by a complete // line of text. for (int j = 0; j < linespacing; ++j) { - vSync(); + waitForVSync(); multiPut(_mapStore, 25, 20, 160, 160); - vSync(); + waitForVSync(); // Output up to 18 lines of text uint16 y = 10 - j; @@ -312,7 +312,7 @@ void DreamWebEngine::rollEndCreditsGameLost() { y += linespacing; } - vSync(); + waitForVSync(); multiDump(25, 20, 160, 160); if (_lastHardKey == 1) diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index d30bf754de..8ed17c9348 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -136,7 +136,7 @@ void DreamWebEngine::doLoad(int savegameId) { delPointer(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); RectWithCallback loadlist[] = { @@ -227,7 +227,7 @@ void DreamWebEngine::saveGame() { checkInput(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); @@ -348,7 +348,7 @@ void DreamWebEngine::doSaveLoad() { readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); delPointer(); @@ -429,7 +429,7 @@ void DreamWebEngine::discOps() { delPointer(); readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); checkCoords(discOpsList); diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 750dafe7b4..e453fced5f 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -754,7 +754,7 @@ void DreamWebEngine::screenUpdate() { showPointer(); if ((_vars._watchingTime == 0) && (_newLocation != 0xff)) return; - vSync(); + waitForVSync(); uint16 mouseState = 0; mouseState |= readMouseState(); dumpPointer(); @@ -769,7 +769,7 @@ void DreamWebEngine::screenUpdate() { showPointer(); if (_wonGame) return; - vSync(); + waitForVSync(); mouseState |= readMouseState(); dumpPointer(); @@ -781,7 +781,7 @@ void DreamWebEngine::screenUpdate() { afterNewRoom(); showPointer(); - vSync(); + waitForVSync(); mouseState |= readMouseState(); dumpPointer(); @@ -790,7 +790,7 @@ void DreamWebEngine::screenUpdate() { delPointer(); showPointer(); - vSync(); + waitForVSync(); _oldButton = _mouseButton; mouseState |= readMouseState(); _mouseButton = mouseState; @@ -871,7 +871,7 @@ void DreamWebEngine::loadTextSegment(TextFile &file, Common::File &inFile, unsig void DreamWebEngine::hangOnCurs(uint16 frameCount) { for (uint16 i = 0; i < frameCount; ++i) { printCurs(); - vSync(); + waitForVSync(); delCurs(); } } @@ -1634,7 +1634,7 @@ bool DreamWebEngine::checkIfSet(uint8 x, uint8 y) { void DreamWebEngine::hangOn(uint16 frameCount) { while (frameCount) { - vSync(); + waitForVSync(); --frameCount; if (_quitRequested) break; @@ -1647,7 +1647,7 @@ void DreamWebEngine::hangOnW(uint16 frameCount) { readMouse(); animPointer(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); --frameCount; if (_quitRequested) @@ -1665,7 +1665,7 @@ void DreamWebEngine::hangOnP(uint16 count) { readMouse(); animPointer(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); count *= 3; @@ -1674,7 +1674,7 @@ void DreamWebEngine::hangOnP(uint16 count) { readMouse(); animPointer(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); if (_quitRequested) break; @@ -2132,7 +2132,7 @@ void DreamWebEngine::workToScreenM() { animPointer(); readMouse(); showPointer(); - vSync(); + waitForVSync(); workToScreen(); delPointer(); } @@ -2607,7 +2607,7 @@ void DreamWebEngine::decide() { readMouse(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); delPointer(); diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp index 0f59cad895..26eafdcb51 100644 --- a/engines/dreamweb/talk.cpp +++ b/engines/dreamweb/talk.cpp @@ -52,7 +52,7 @@ void DreamWebEngine::talk() { readMouse(); animPointer(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); _getBack = 0; @@ -211,7 +211,7 @@ bool DreamWebEngine::hangOnPQ() { readMouse(); animPointer(); showPointer(); - vSync(); + waitForVSync(); dumpPointer(); dumpTextLine(); checkCoords(quitList); diff --git a/engines/dreamweb/titles.cpp b/engines/dreamweb/titles.cpp index f7486ce687..3ed31fe13a 100644 --- a/engines/dreamweb/titles.cpp +++ b/engines/dreamweb/titles.cpp @@ -134,7 +134,7 @@ void DreamWebEngine::bibleQuote() { void DreamWebEngine::hangOne(uint16 delay) { do { - vSync(); + waitForVSync(); if (_lastHardKey == 1) return; // "hangonearly" } while (--delay); @@ -200,13 +200,13 @@ void DreamWebEngine::runIntroSeq() { _getBack = 0; do { - vSync(); + waitForVSync(); if (_lastHardKey == 1) break; spriteUpdate(); - vSync(); + waitForVSync(); if (_lastHardKey == 1) break; @@ -216,14 +216,14 @@ void DreamWebEngine::runIntroSeq() { reelsOnScreen(); afterIntroRoom(); useTimedText(); - vSync(); + waitForVSync(); if (_lastHardKey == 1) break; dumpMap(); dumpTimedText(); - vSync(); + waitForVSync(); if (_lastHardKey == 1) break; @@ -247,18 +247,18 @@ void DreamWebEngine::runEndSeq() { _getBack = 0; do { - vSync(); + waitForVSync(); spriteUpdate(); - vSync(); + waitForVSync(); delEverything(); printSprites(); reelsOnScreen(); afterIntroRoom(); useTimedText(); - vSync(); + waitForVSync(); dumpMap(); dumpTimedText(); - vSync(); + waitForVSync(); } while (_getBack != 1 && !_quitRequested); } diff --git a/engines/dreamweb/vgafades.cpp b/engines/dreamweb/vgafades.cpp index e8999ab18c..6f9fd5f53c 100644 --- a/engines/dreamweb/vgafades.cpp +++ b/engines/dreamweb/vgafades.cpp @@ -52,7 +52,7 @@ void DreamWebEngine::fadeDOS() { return; // FIXME later waitForVSync(); - //processEvents will be called from vsync + //processEvents will be called from waitForVSync uint8 *dst = _startPal; getPalette(dst, 0, 64); for (int fade = 0; fade < 64; ++fade) { diff --git a/engines/dreamweb/vgagrafx.cpp b/engines/dreamweb/vgagrafx.cpp index a66f156a1d..ec306c4924 100644 --- a/engines/dreamweb/vgagrafx.cpp +++ b/engines/dreamweb/vgagrafx.cpp @@ -144,10 +144,6 @@ void DreamWebEngine::doShake() { setShakePos(offset >= 0 ? offset : -offset); } -void DreamWebEngine::vSync() { - waitForVSync(); -} - void DreamWebEngine::setMode() { waitForVSync(); initGraphics(320, 200, false); -- cgit v1.2.3 From de904c59c4bde9060efeb36896f7105f4e286e27 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Thu, 31 May 2012 00:05:05 +1000 Subject: SCUMM: Fix global script 255 never been resumed by runScriptNested. Thanks to clone2727 for tracking down the problem in baseball2003. --- engines/scumm/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 39420ee974..a26c64e690 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -318,7 +318,7 @@ void ScummEngine::runScriptNested(int script) { nest = &vm.nest[vm.numNestedScripts]; if (_currentScript == 0xFF) { - nest->number = 0xFF; + nest->number = 0; nest->where = 0xFF; } else { // Store information about the currently running script @@ -338,7 +338,7 @@ void ScummEngine::runScriptNested(int script) { if (vm.numNestedScripts != 0) vm.numNestedScripts--; - if (nest->number != 0xFF) { + if (nest->number) { // Try to resume the script which called us, if its status has not changed // since it invoked us. In particular, we only resume it if it hasn't been // stopped in the meantime, and if it did not already move on. -- cgit v1.2.3 From 403b646c13f0729a32c21f89a2e9284d84df34cf Mon Sep 17 00:00:00 2001 From: Lars Skovlund Date: Wed, 30 May 2012 18:43:39 +0200 Subject: SCI32: Case-insensitive configuration getters --- engines/sci/engine/kmisc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 2be9432521..2911af97df 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -371,6 +371,8 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { // Anything below that makes Phantasmagoria awfully sluggish, so we're // setting everything to 500, which makes the game playable. + setting.toLowercase(); + if (setting == "videospeed") { s->_segMan->strcpy(data, "500"); } else if (setting == "cpu") { @@ -388,10 +390,12 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv) { Common::String category = s->_segMan->getString(argv[0]); // always "config" + category.toLowercase(); if (category != "config") error("GetSierraProfileInt: category isn't 'config', it's '%s'", category.c_str()); Common::String setting = s->_segMan->getString(argv[1]); + setting.toLowercase(); if (setting != "videospeed") error("GetSierraProfileInt: setting isn't 'videospeed', it's '%s'", setting.c_str()); -- cgit v1.2.3 From 29ebb2823dfe5fff95c47a2847f11e11bde95fd1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 31 May 2012 08:06:59 +1000 Subject: COMMON: Fix comment typo in coroutine comments --- common/coroutines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/coroutines.h b/common/coroutines.h index 5daec4b426..abc114e0cf 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -64,7 +64,7 @@ typedef CoroBaseContext *CoroContext; /** This is a special constant that can be temporarily used as a parameter to call coroutine-ised - * from methods from methods that haven't yet been converted to being a coroutine, so code at least + * methods from code that haven't yet been converted to being a coroutine, so code at least * compiles correctly. Be aware, though, that an error will occur if a coroutine that was passed * the nullContext tries to sleep or yield control. */ -- cgit v1.2.3 From 4aec92e5e9d00d7a9b38d893682823777e088256 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Thu, 31 May 2012 11:39:54 +1000 Subject: SCUMM: Backyard Baseball 2003 uses a unique variable for the subtitle setting, fixes changing subtitles via ScummVM. --- engines/scumm/detection_tables.h | 2 +- engines/scumm/scumm.cpp | 7 +++++++ engines/scumm/scumm.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 34ec6b6543..452a6f0960 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -382,7 +382,7 @@ static const GameSettings gameVariantsTable[] = { {"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, // Added the use of bink videos - {"Baseball2003", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, + {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index fc46f88df4..d0f46f3e56 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1917,6 +1917,13 @@ void ScummEngine::syncSoundSettings() { if (VAR_CHARINC != 0xFF) VAR(VAR_CHARINC) = _defaultTalkDelay; } + + // Backyard Baseball 2003 uses a unique subtitle variable, + // rather than VAR_SUBTITLES + if (_game.id == GID_BASEBALL2003) { + _scummVars[632] = ConfMan.getBool("subtitles"); + } + } void ScummEngine::setTalkSpeed(int talkspeed) { diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index cacf8c214e..8c0070b5f5 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -245,6 +245,7 @@ enum ScummGameId { GID_SOCCERMLS, GID_SOCCER2004, GID_BASEBALL2001, + GID_BASEBALL2003, GID_BASKETBALL, GID_MOONBASE, GID_HECUP // CUP demos -- cgit v1.2.3 From 8860a83bf8a3dc02394a210b29aa6871928a7914 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Wed, 30 May 2012 23:31:16 -0400 Subject: NEWS: Backyard Baseball 2003 is now supported --- NEWS | 1 + README | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 4b3203dc66..ed98cdc83f 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ For a more comprehensive changelog of the latest experimental code, see: 1.5.0 (????-??-??) New Games: + - Added support for Backyard Baseball 2003. - Added support for Blue Force. - Added support for Darby the Dragon. - Added support for Dreamweb. diff --git a/README b/README index 8afe8c9bc8..81b28830c2 100644 --- a/README +++ b/README @@ -272,6 +272,7 @@ Other Games: SCUMM Games by Humongous Entertainment: Backyard Baseball [baseball] Backyard Baseball 2001 [baseball2001] + Backyard Baseball 2003 [baseball2003] Backyard Football [football] Big Thinkers First Grade [thinker1] Big Thinkers Kindergarten [thinkerk] @@ -342,7 +343,6 @@ these at your own risk, and please do not file bug reports about them. If you want the latest updates on game compatibility, visit our web site and view the compatibility chart. - Backyard Baseball 2003 [baseball2003] Backyard Football 2002 [football2002] Backyard Soccer [soccer] Backyard Soccer MLS [soccermls] -- cgit v1.2.3 From 628cfa3d47fb7ebad8dd26cb59f485e5c70dacb5 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 31 May 2012 05:16:10 +0100 Subject: DREAMWEB: Objectify Sound functions & data into DreamWebSound class. This change should have no functional change, but makes the sound code more decoupled, modular and readable, prior to attempting a fix for bug #3528164 - "DREAMWEB: missing sound effects/music cues during main title". --- engines/dreamweb/dreamweb.cpp | 23 +++-------- engines/dreamweb/dreamweb.h | 43 ++------------------ engines/dreamweb/keypad.cpp | 11 +++--- engines/dreamweb/monitor.cpp | 7 ++-- engines/dreamweb/newplace.cpp | 3 +- engines/dreamweb/people.cpp | 16 ++++---- engines/dreamweb/print.cpp | 8 ++-- engines/dreamweb/rain.cpp | 7 ++-- engines/dreamweb/saveload.cpp | 4 +- engines/dreamweb/sound.cpp | 90 ++++++++++++++++++++++++++---------------- engines/dreamweb/sound.h | 91 +++++++++++++++++++++++++++++++++++++++++++ engines/dreamweb/sprite.cpp | 26 ++++++------- engines/dreamweb/stubs.cpp | 42 ++++++++++---------- engines/dreamweb/talk.cpp | 28 +++++++------ engines/dreamweb/titles.cpp | 50 +++++++++++------------- engines/dreamweb/use.cpp | 33 ++++++++-------- engines/dreamweb/vgafades.cpp | 3 +- 17 files changed, 276 insertions(+), 209 deletions(-) create mode 100644 engines/dreamweb/sound.h diff --git a/engines/dreamweb/dreamweb.cpp b/engines/dreamweb/dreamweb.cpp index 11e8e3f8cc..0ca98d5a7b 100644 --- a/engines/dreamweb/dreamweb.cpp +++ b/engines/dreamweb/dreamweb.cpp @@ -35,6 +35,7 @@ #include "graphics/palette.h" #include "graphics/surface.h" +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -46,21 +47,15 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam _roomDesc(kNumRoomTexts), _freeDesc(kNumFreeTexts), _personText(kNumPersonTexts) { - // Setup mixer - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - _vSyncInterrupt = false; _console = 0; + _sound = 0; DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag"); DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function"); _speed = 1; _turbo = false; _oldMouseState = 0; - _channel0 = 0; - _channel1 = 0; _datafilePrefix = "DREAMWEB."; _speechDirName = "SPEECH"; @@ -85,16 +80,6 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam _openChangeSize = kInventx+(4*kItempicsize); _quitRequested = false; - _currentSample = 0xff; - _channel0Playing = 0; - _channel0Repeat = 0; - _channel1Playing = 0xff; - - _volume = 0; - _volumeTo = 0; - _volumeDirection = 0; - _volumeCount = 0; - _speechLoaded = false; _backdropBlocks = 0; @@ -246,6 +231,7 @@ DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gam DreamWebEngine::~DreamWebEngine() { DebugMan.clearAllDebugChannels(); delete _console; + delete _sound; } static void vSyncInterrupt(void *refCon) { @@ -286,7 +272,7 @@ void DreamWebEngine::processEvents() { return; } - soundHandler(); + _sound->soundHandler(); Common::Event event; int softKey, hardKey; while (_eventMan->pollEvent(event)) { @@ -382,6 +368,7 @@ void DreamWebEngine::processEvents() { Common::Error DreamWebEngine::run() { syncSoundSettings(); _console = new DreamWebConsole(this); + _sound = new DreamWebSound(this); ConfMan.registerDefault("originalsaveload", "false"); ConfMan.registerDefault("bright_palette", true); diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h index 468a1f58a8..48d44c0380 100644 --- a/engines/dreamweb/dreamweb.h +++ b/engines/dreamweb/dreamweb.h @@ -99,10 +99,12 @@ enum { }; struct DreamWebGameDescription; +class DreamWebSound; class DreamWebEngine : public Engine { private: DreamWebConsole *_console; + DreamWebSound *_sound; bool _vSyncInterrupt; protected: @@ -142,7 +144,6 @@ public: void quit(); - void loadSounds(uint bank, const Common::String &suffix); bool loadSpeech(const Common::String &filename); void enableSavingOrLoading(bool enable = true) { _enableSavingOrLoading = enable; } @@ -151,15 +152,12 @@ public: uint8 modifyChar(uint8 c) const; Common::String modifyFileName(const char *); - void stopSound(uint8 channel); - const Common::String& getDatafilePrefix() { return _datafilePrefix; }; + const Common::String& getSpeechDirName() { return _speechDirName; }; private: void keyPressed(uint16 ascii); void setSpeed(uint speed); - void soundHandler(); - void playSound(uint8 channel, uint8 id, uint8 loops); const DreamWebGameDescription *_gameDescription; Common::RandomSource _rnd; @@ -171,22 +169,6 @@ private: uint _oldMouseState; bool _enableSavingOrLoading; - struct Sample { - uint offset; - uint size; - Sample(): offset(), size() {} - }; - - struct SoundData { - Common::Array samples; - Common::Array data; - }; - SoundData _soundData[2]; - Common::Array _speechData; - - Audio::SoundHandle _channelHandle[2]; - uint8 _channel0, _channel1; - protected: GameVars _vars; // saved variables @@ -327,16 +309,6 @@ public: // sound related uint8 _roomsSample; - uint8 _currentSample; - uint8 _channel0Playing; - uint8 _channel0Repeat; - uint8 _channel1Playing; - - uint8 _volume; - uint8 _volumeTo; - int8 _volumeDirection; - uint8 _volumeCount; - bool _speechLoaded; // misc variables @@ -715,15 +687,6 @@ public: void showSaveOps(); void showLoadOps(); - // from sound.cpp - bool loadSpeech(byte type1, int idx1, byte type2, int idx2); - void volumeAdjust(); - void cancelCh0(); - void cancelCh1(); - void loadRoomsSample(); - void playChannel0(uint8 index, uint8 repeat); - void playChannel1(uint8 index); - // from sprite.cpp void printSprites(); void printASprite(const Sprite *sprite); diff --git a/engines/dreamweb/keypad.cpp b/engines/dreamweb/keypad.cpp index 002588cb70..3580f8ad52 100644 --- a/engines/dreamweb/keypad.cpp +++ b/engines/dreamweb/keypad.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -85,7 +86,7 @@ void DreamWebEngine::enterCode(uint8 digit0, uint8 digit1, uint8 digit2, uint8 d if (_pressed == 11) { if (isItRight(digit0, digit1, digit2, digit3)) _vars._lockStatus = 0; - playChannel1(11); + _sound->playChannel1(11); _lightCount = 120; _pressPointer = 0; } @@ -180,7 +181,7 @@ void DreamWebEngine::buttonPress(uint8 buttonId) { _graphicPress = buttonId + 21; _pressCount = 40; if (buttonId != 11) - playChannel1(10); + _sound->playChannel1(10); } } @@ -532,7 +533,7 @@ void DreamWebEngine::enterSymbol() { _symbolGraphics.clear(); restoreReels(); workToScreenM(); - playChannel1(13); + _sound->playChannel1(13); } else { removeSetObject(46); placeSetObject(43); @@ -820,7 +821,7 @@ void DreamWebEngine::diaryKeyP() { _pressCount) return; // notkeyp - playChannel1(16); + _sound->playChannel1(16); _pressCount = 12; _pressed = 'P'; _diaryPage--; @@ -837,7 +838,7 @@ void DreamWebEngine::diaryKeyN() { _pressCount) return; // notkeyn - playChannel1(16); + _sound->playChannel1(16); _pressCount = 12; _pressed = 'N'; _diaryPage++; diff --git a/engines/dreamweb/monitor.cpp b/engines/dreamweb/monitor.cpp index 4c66e7a599..4e9d8eecc1 100644 --- a/engines/dreamweb/monitor.cpp +++ b/engines/dreamweb/monitor.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -97,7 +98,7 @@ void DreamWebEngine::useMon() { _textFile3.clear(); _getBack = 1; - playChannel1(26); + _sound->playChannel1(26); _manIsOffScreen = 0; restoreAll(); redrawMainScrn(); @@ -180,7 +181,7 @@ void DreamWebEngine::monitorLogo() { printLogo(); //fadeUpMon(); // FIXME: Commented out in ASM printLogo(); - playChannel1(26); + _sound->playChannel1(26); randomAccess(20); } else { printLogo(); @@ -288,7 +289,7 @@ void DreamWebEngine::scrollMonitor() { printLogo(); printUnderMonitor(); workToScreen(); - playChannel1(25); + _sound->playChannel1(25); } void DreamWebEngine::showCurrentFile() { diff --git a/engines/dreamweb/newplace.cpp b/engines/dreamweb/newplace.cpp index ab6537422a..5b4b0260f5 100644 --- a/engines/dreamweb/newplace.cpp +++ b/engines/dreamweb/newplace.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -55,7 +56,7 @@ void DreamWebEngine::selectLocation() { _pointerFrame = 0; showPointer(); workToScreen(); - playChannel0(9, 255); + _sound->playChannel0(9, 255); _newLocation = 255; while (_newLocation == 255) { diff --git a/engines/dreamweb/people.cpp b/engines/dreamweb/people.cpp index dfb5c62618..36a756a49b 100644 --- a/engines/dreamweb/people.cpp +++ b/engines/dreamweb/people.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -149,7 +150,7 @@ void DreamWebEngine::madmanText() { if (hasSpeech()) { if (_speechCount > 15) return; - if (_channel1Playing != 255) + if (_sound->isChannel1Playing()) return; origCount = _speechCount; ++_speechCount; @@ -250,7 +251,7 @@ bool DreamWebEngine::checkSpeed(ReelRoutine &routine) { void DreamWebEngine::sparkyDrip(ReelRoutine &routine) { if (checkSpeed(routine)) - playChannel0(14, 0); + _sound->playChannel0(14, 0); } void DreamWebEngine::genericPerson(ReelRoutine &routine) { @@ -430,7 +431,7 @@ void DreamWebEngine::drinker(ReelRoutine &routine) { void DreamWebEngine::alleyBarkSound(ReelRoutine &routine) { uint16 prevReelPointer = routine.reelPointer() - 1; if (prevReelPointer == 0) { - playChannel1(14); + _sound->playChannel1(14); routine.setReelPointer(1000); } else { routine.setReelPointer(prevReelPointer); @@ -523,7 +524,7 @@ void DreamWebEngine::gates(ReelRoutine &routine) { if (checkSpeed(routine)) { uint16 nextReelPointer = routine.reelPointer() + 1; if (nextReelPointer == 116) - playChannel1(17); + _sound->playChannel1(17); if (nextReelPointer >= 110) routine.period = 2; if (nextReelPointer == 120) { @@ -579,12 +580,12 @@ void DreamWebEngine::carParkDrip(ReelRoutine &routine) { if (!checkSpeed(routine)) return; // cantdrip2 - playChannel1(14); + _sound->playChannel1(14); } void DreamWebEngine::foghornSound(ReelRoutine &routine) { if (randomNumber() == 198) - playChannel1(13); + _sound->playChannel1(13); } void DreamWebEngine::train(ReelRoutine &routine) { @@ -1027,8 +1028,7 @@ void DreamWebEngine::endGameSeq(ReelRoutine &routine) { fadeScreenDownHalf(); } else if (nextReelPointer == 324) { fadeScreenDowns(); - _volumeTo = 7; - _volumeDirection = 1; + _sound->volumeChange(7, 1); } if (nextReelPointer == 340) diff --git a/engines/dreamweb/print.cpp b/engines/dreamweb/print.cpp index a96d1f9d58..3a2c45e07b 100644 --- a/engines/dreamweb/print.cpp +++ b/engines/dreamweb/print.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -246,10 +247,9 @@ const char *DreamWebEngine::monPrint(const char *string) { } void DreamWebEngine::rollEndCreditsGameWon() { - playChannel0(16, 255); - _volume = 7; - _volumeTo = 0; - _volumeDirection = -1; + _sound->playChannel0(16, 255); + _sound->volumeSet(7); + _sound->volumeChange(0, -1); multiGet(_mapStore, 75, 20, 160, 160); diff --git a/engines/dreamweb/rain.cpp b/engines/dreamweb/rain.cpp index 7db4744cbf..8e42e0c161 100644 --- a/engines/dreamweb/rain.cpp +++ b/engines/dreamweb/rain.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -50,7 +51,7 @@ void DreamWebEngine::showRain() { } } - if (_channel1Playing != 255) + if (_sound->isChannel1Playing()) return; if (_realLocation == 2 && _vars._beenMugged != 1) return; @@ -61,11 +62,11 @@ void DreamWebEngine::showRain() { return; uint8 soundIndex; - if (_channel0Playing != 6) + if (_sound->getChannel0Playing() != 6) soundIndex = 4; else soundIndex = 7; - playChannel1(soundIndex); + _sound->playChannel1(soundIndex); } uint8 DreamWebEngine::getBlockOfPixel(uint8 x, uint8 y) { diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index 8ed17c9348..c8fb537fec 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -20,7 +20,9 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" + #include "engines/metaengine.h" #include "graphics/thumbnail.h" #include "gui/saveload.h" @@ -181,7 +183,7 @@ void DreamWebEngine::doLoad(int savegameId) { _saveGraphics.clear(); startLoading(g_madeUpRoomDat); - loadRoomsSample(); + _sound->loadRoomsSample(_roomsSample); _roomLoaded = 1; _newLocation = 255; clearSprites(); diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp index fcbcb9d0a0..83ddebc552 100644 --- a/engines/dreamweb/sound.cpp +++ b/engines/dreamweb/sound.cpp @@ -20,27 +20,52 @@ * */ -#include "dreamweb/dreamweb.h" - -#include "audio/mixer.h" #include "audio/decoders/raw.h" - #include "common/config-manager.h" +#include "common/debug.h" +#include "common/file.h" + +#include "dreamweb/dreamweb.h" +#include "dreamweb/sound.h" namespace DreamWeb { -bool DreamWebEngine::loadSpeech(byte type1, int idx1, byte type2, int idx2) { +DreamWebSound::DreamWebSound(DreamWebEngine *vm) : _vm(vm) { + _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); + _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); + + _channel0 = 0; + _channel1 = 0; + + _currentSample = 0xff; + _channel0Playing = 0; + _channel0Repeat = 0; + _channel1Playing = 255; + + _volume = 0; + _volumeTo = 0; + _volumeDirection = 0; + _volumeCount = 0; +} + +DreamWebSound::~DreamWebSound() { +} + +bool DreamWebSound::loadSpeech(byte type1, int idx1, byte type2, int idx2) { cancelCh1(); Common::String name = Common::String::format("%c%02d%c%04d.RAW", type1, idx1, type2, idx2); - //debug("name = %s", name.c_str()); - bool result = loadSpeech(name); + debug(2, "loadSpeech() name:%s", name.c_str()); + return loadSpeech(name); +} - _speechLoaded = result; - return result; +void DreamWebSound::volumeChange(uint8 value, int8 direction) { + _volumeTo = value; + _volumeDirection = direction; } -void DreamWebEngine::volumeAdjust() { +void DreamWebSound::volumeAdjust() { if (_volumeDirection == 0) return; if (_volume != _volumeTo) { @@ -53,34 +78,33 @@ void DreamWebEngine::volumeAdjust() { } } -void DreamWebEngine::playChannel0(uint8 index, uint8 repeat) { +void DreamWebSound::playChannel0(uint8 index, uint8 repeat) { debug(1, "playChannel0(index:%d, repeat:%d)", index, repeat); _channel0Playing = index; _channel0Repeat = repeat; } -void DreamWebEngine::playChannel1(uint8 index) { +void DreamWebSound::playChannel1(uint8 index) { if (_channel1Playing == 7) return; _channel1Playing = index; } -void DreamWebEngine::cancelCh0() { +void DreamWebSound::cancelCh0() { debug(1, "cancelCh0()"); _channel0Playing = 255; _channel0Repeat = 0; stopSound(0); } -void DreamWebEngine::cancelCh1() { +void DreamWebSound::cancelCh1() { _channel1Playing = 255; stopSound(1); } -void DreamWebEngine::loadRoomsSample() { - debug(1, "loadRoomsSample() _roomsSample:%d", _roomsSample); - uint8 sample = _roomsSample; +void DreamWebSound::loadRoomsSample(uint8 sample) { + debug(1, "loadRoomsSample(sample:%d)", sample); if (sample == 255 || _currentSample == sample) return; // loaded already @@ -98,7 +122,7 @@ void DreamWebEngine::loadRoomsSample() { loadSounds(1, sampleSuffix.c_str()); } -void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) { +void DreamWebSound::playSound(uint8 channel, uint8 id, uint8 loops) { debug(1, "playSound(%u, %u, %u)", channel, id, loops); int bank = 0; @@ -149,27 +173,27 @@ void DreamWebEngine::playSound(uint8 channel, uint8 id, uint8 loops) { } else stream = raw; - if (_mixer->isSoundHandleActive(_channelHandle[channel])) - _mixer->stopHandle(_channelHandle[channel]); - _mixer->playStream(type, &_channelHandle[channel], stream); + if (_vm->_mixer->isSoundHandleActive(_channelHandle[channel])) + _vm->_mixer->stopHandle(_channelHandle[channel]); + _vm->_mixer->playStream(type, &_channelHandle[channel], stream); } -void DreamWebEngine::stopSound(uint8 channel) { +void DreamWebSound::stopSound(uint8 channel) { debug(1, "stopSound(%u)", channel); assert(channel == 0 || channel == 1); - _mixer->stopHandle(_channelHandle[channel]); + _vm->_mixer->stopHandle(_channelHandle[channel]); if (channel == 0) _channel0 = 0; else _channel1 = 0; } -bool DreamWebEngine::loadSpeech(const Common::String &filename) { - if (!hasSpeech()) +bool DreamWebSound::loadSpeech(const Common::String &filename) { + if (!_vm->hasSpeech()) return false; Common::File file; - if (!file.open(_speechDirName + "/" + filename)) + if (!file.open(_vm->getSpeechDirName() + "/" + filename)) return false; debug(1, "loadSpeech(%s)", filename.c_str()); @@ -181,13 +205,13 @@ bool DreamWebEngine::loadSpeech(const Common::String &filename) { return true; } -void DreamWebEngine::soundHandler() { +void DreamWebSound::soundHandler() { static uint8 volumeOld = 0, channel0Old = 0, channel0PlayingOld = 0; if (_volume != volumeOld || _channel0 != channel0Old || _channel0Playing != channel0PlayingOld) debug(1, "soundHandler() _volume: %d _channel0: %d _channel0Playing: %d", _volume, _channel0, _channel0Playing); volumeOld = _volume, channel0Old = _channel0, channel0PlayingOld = _channel0Playing; - _subtitles = ConfMan.getBool("subtitles"); + _vm->_subtitles = ConfMan.getBool("subtitles"); volumeAdjust(); uint volume = _volume; @@ -204,7 +228,7 @@ void DreamWebEngine::soundHandler() { if (volume >= 8) volume = 7; volume = (8 - volume) * Audio::Mixer::kMaxChannelVolume / 8; - _mixer->setChannelVolume(_channelHandle[0], volume); + _vm->_mixer->setChannelVolume(_channelHandle[0], volume); uint8 ch0 = _channel0Playing; if (ch0 == 255) @@ -226,20 +250,20 @@ void DreamWebEngine::soundHandler() { playSound(1, ch1, 1); } } - if (!_mixer->isSoundHandleActive(_channelHandle[0])) { + if (!_vm->_mixer->isSoundHandleActive(_channelHandle[0])) { if (_channel0Playing != 255 && _channel0 != 0) debug(1, "!_mixer->isSoundHandleActive _channelHandle[0] _channel0Playing:%d _channel0:%d", _channel0Playing, _channel0); _channel0Playing = 255; _channel0 = 0; } - if (!_mixer->isSoundHandleActive(_channelHandle[1])) { + if (!_vm->_mixer->isSoundHandleActive(_channelHandle[1])) { _channel1Playing = 255; _channel1 = 0; } } -void DreamWebEngine::loadSounds(uint bank, const Common::String &suffix) { - Common::String filename = getDatafilePrefix() + suffix; +void DreamWebSound::loadSounds(uint bank, const Common::String &suffix) { + Common::String filename = _vm->getDatafilePrefix() + suffix; debug(1, "loadSounds(%u, %s)", bank, filename.c_str()); Common::File file; if (!file.open(filename)) { diff --git a/engines/dreamweb/sound.h b/engines/dreamweb/sound.h new file mode 100644 index 0000000000..62def157e7 --- /dev/null +++ b/engines/dreamweb/sound.h @@ -0,0 +1,91 @@ +/* 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 DREAMWEB_SOUND_H +#define DREAMWEB_SOUND_H + +#include "common/array.h" +#include "common/str.h" +#include "audio/mixer.h" + +namespace DreamWeb { + +class DreamWebEngine; + +class DreamWebSound { +public: + DreamWebSound(DreamWebEngine *vm); + ~DreamWebSound(); + + bool loadSpeech(byte type1, int idx1, byte type2, int idx2); + void volumeSet(uint8 value) { _volume = value; } + void volumeChange(uint8 value, int8 direction); + void playChannel0(uint8 index, uint8 repeat); + void playChannel1(uint8 index); + uint8 getChannel0Playing() { return _channel0Playing; } + bool isChannel1Playing() { return _channel1Playing != 255; } + void cancelCh0(); + void cancelCh1(); + void loadRoomsSample(uint8 sample); + void soundHandler(); + void loadSounds(uint bank, const Common::String &suffix); + +private: + DreamWebEngine *_vm; + + struct Sample { + uint offset; + uint size; + Sample(): offset(), size() {} + }; + + struct SoundData { + Common::Array samples; + Common::Array data; + }; + + SoundData _soundData[2]; + Common::Array _speechData; + + Audio::SoundHandle _channelHandle[2]; + + uint8 _channel0, _channel1; + + uint8 _currentSample; + uint8 _channel0Playing; + uint8 _channel0Repeat; + uint8 _channel1Playing; + + uint8 _volume; + uint8 _volumeTo; + int8 _volumeDirection; + uint8 _volumeCount; + + void volumeAdjust(); + void playSound(uint8 channel, uint8 id, uint8 loops); + void stopSound(uint8 channel); + bool loadSpeech(const Common::String &filename); +}; + +} // End of namespace DreamWeb + +#endif diff --git a/engines/dreamweb/sprite.cpp b/engines/dreamweb/sprite.cpp index 3df324abe1..5b6cf6a6ac 100644 --- a/engines/dreamweb/sprite.cpp +++ b/engines/dreamweb/sprite.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -298,7 +299,7 @@ void DreamWebEngine::doDoor(Sprite *sprite, SetObject *objData, Common::Rect che soundIndex = 13; else soundIndex = 0; - playChannel1(soundIndex); + _sound->playChannel1(soundIndex); } if (objData->frames[sprite->animFrame] == 255) --sprite->animFrame; @@ -315,7 +316,7 @@ void DreamWebEngine::doDoor(Sprite *sprite, SetObject *objData, Common::Rect che soundIndex = 13; else soundIndex = 1; - playChannel1(soundIndex); + _sound->playChannel1(soundIndex); } if (sprite->animFrame != 0) --sprite->animFrame; @@ -346,7 +347,7 @@ void DreamWebEngine::lockedDoorway(Sprite *sprite, SetObject *objData) { if (openDoor) { if (sprite->animFrame == 1) { - playChannel1(0); + _sound->playChannel1(0); } if (sprite->animFrame == 6) @@ -367,7 +368,7 @@ void DreamWebEngine::lockedDoorway(Sprite *sprite, SetObject *objData) { // shut door if (sprite->animFrame == 5) { - playChannel1(1); + _sound->playChannel1(1); } if (sprite->animFrame != 0) @@ -505,7 +506,7 @@ void DreamWebEngine::intro1Text() { if (_introCount != 2 && _introCount != 4 && _introCount != 6) return; - if (hasSpeech() && _channel1Playing != 255) { + if (hasSpeech() && _sound->isChannel1Playing()) { _introCount--; } else { if (_introCount == 2) @@ -578,7 +579,7 @@ void DreamWebEngine::textForEnd() { } void DreamWebEngine::textForMonkHelper(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { - if (hasSpeech() && _channel1Playing != 255) + if (hasSpeech() && _sound->isChannel1Playing()) _introCount--; else setupTimedTemp(textIndex, voiceIndex, x, y, countToTimed, timeCount); @@ -614,8 +615,7 @@ void DreamWebEngine::textForMonk() { else if (_introCount == 53) { fadeScreenDowns(); if (hasSpeech()) { - _volumeTo = 7; - _volumeDirection = 1; + _sound->volumeChange(7, 1); } } } @@ -905,14 +905,14 @@ void DreamWebEngine::soundOnReels(uint16 reelPointer) { continue; _lastSoundReel = r->_reelPointer; if (r->_sample < 64) { - playChannel1(r->_sample); + _sound->playChannel1(r->_sample); return; } if (r->_sample < 128) { - playChannel0(r->_sample & 63, 0); + _sound->playChannel0(r->_sample & 63, 0); return; } - playChannel0(r->_sample & 63, 255); + _sound->playChannel0(r->_sample & 63, 255); } if (_lastSoundReel != reelPointer) @@ -955,9 +955,9 @@ void DreamWebEngine::getRidOfReels() { void DreamWebEngine::liftNoise(uint8 index) { if (_realLocation == 5 || _realLocation == 21) - playChannel1(13); // hiss noise + _sound->playChannel1(13); // hiss noise else - playChannel1(index); + _sound->playChannel1(index); } void DreamWebEngine::checkForExit(Sprite *sprite) { diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index e453fced5f..3aa8e6da74 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" #include "common/config-manager.h" @@ -578,7 +579,7 @@ void DreamWebEngine::dreamweb() { readSetData(); _wonGame = false; - loadSounds(0, "V99"); // basic sample + _sound->loadSounds(0, "V99"); // basic sample bool firstLoop = true; @@ -654,7 +655,7 @@ void DreamWebEngine::dreamweb() { _vars._location = 255; _vars._roomAfterDream = 1; _newLocation = 35; - _volume = 7; + _sound->volumeSet(7); loadRoom(); clearSprites(); initMan(); @@ -664,8 +665,7 @@ void DreamWebEngine::dreamweb() { initialInv(); _lastFlag = 32; startup1(); - _volumeTo = 0; - _volumeDirection = -1; + _sound->volumeChange(0, -1); _commandType = 255; } @@ -930,7 +930,7 @@ void DreamWebEngine::processTrigger() { void DreamWebEngine::useTimedText() { if (_previousTimedTemp._string) { // TODO: It might be nice to make subtitles wait for the speech - // to finish (_channel1Playing) when we're in speech+subtitles mode, + // to finish (_sound->isChannel1Playing()) when we're in speech+subtitles mode, // instead of waiting the pre-specified amount of time. @@ -967,9 +967,9 @@ void DreamWebEngine::useTimedText() { void DreamWebEngine::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) { if (hasSpeech() && voiceIndex != 0) { - if (loadSpeech('T', voiceIndex, 'T', textIndex)) { - playChannel1(50+12); - } + _speechLoaded = _sound->loadSpeech('T', voiceIndex, 'T', textIndex); + if (_speechLoaded) + _sound->playChannel1(50+12); if (_speechLoaded && !_subtitles) return; @@ -1846,7 +1846,7 @@ void DreamWebEngine::loadRoom() { _vars._location = _newLocation; const Room &room = g_roomData[_newLocation]; startLoading(room); - loadRoomsSample(); + _sound->loadRoomsSample(_roomsSample); switchRyanOn(); drawFlags(); @@ -2146,12 +2146,12 @@ void DreamWebEngine::atmospheres() { continue; if (a->_mapX != _mapX || a->_mapY != _mapY) continue; - if (a->_sound != _channel0Playing) { + if (a->_sound != _sound->getChannel0Playing()) { if (_vars._location == 45 && _vars._reelToWatch == 45) continue; // "web" - playChannel0(a->_sound, a->_repeat); + _sound->playChannel0(a->_sound, a->_repeat); // NB: The asm here reads // cmp reallocation,2 @@ -2161,21 +2161,21 @@ void DreamWebEngine::atmospheres() { // I'm interpreting this as if the cmp reallocation is below the jz if (_mapY == 0) { - _volume = 0; // "fullvol" + _sound->volumeSet(0); // "fullvol" return; } if (_realLocation == 2 && _mapX == 22 && _mapY == 10) - _volume = 5; // "louisvol" + _sound->volumeSet(5); // "louisvol" if (hasSpeech() && _realLocation == 14) { if (_mapX == 33) { - _volume = 0; // "ismad2" + _sound->volumeSet(0); // "ismad2" return; } if (_mapX == 22) { - _volume = 5; + _sound->volumeSet(5); return; } @@ -2184,19 +2184,19 @@ void DreamWebEngine::atmospheres() { if (_realLocation == 2) { if (_mapX == 22) { - _volume = 5; // "louisvol" + _sound->volumeSet(5); // "louisvol" return; } if (_mapX == 11) { - _volume = 0; // "fullvol" + _sound->volumeSet(0); // "fullvol" return; } } return; } - cancelCh0(); + _sound->cancelCh0(); } void DreamWebEngine::readKey() { @@ -2642,8 +2642,8 @@ void DreamWebEngine::showGun() { _numToFade = 128; hangOn(200); _roomsSample = 34; - loadRoomsSample(); - _volume = 0; + _sound->loadRoomsSample(_roomsSample); + _sound->volumeSet(0); GraphicsFile graphics; loadGraphicsFile(graphics, "G13"); createPanel2(); @@ -2653,7 +2653,7 @@ void DreamWebEngine::showGun() { graphics.clear(); fadeScreenUp(); hangOn(160); - playChannel0(12, 0); + _sound->playChannel0(12, 0); loadTempText("T83"); rollEndCreditsGameLost(); getRidOfTempText(); diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp index 26eafdcb51..ca99269cc8 100644 --- a/engines/dreamweb/talk.cpp +++ b/engines/dreamweb/talk.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -67,9 +68,8 @@ void DreamWebEngine::talk() { redrawMainScrn(); workToScreenM(); if (_speechLoaded) { - cancelCh1(); - _volumeDirection = -1; - _volumeTo = 0; + _sound->cancelCh1(); + _sound->volumeChange(0, -1); } } @@ -99,12 +99,10 @@ void DreamWebEngine::startTalk() { printDirect(&str, 66, &y, 241, true); if (hasSpeech()) { - _speechLoaded = false; - loadSpeech('R', _realLocation, 'C', 64*(_character & 0x7F)); + _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', 64*(_character & 0x7F)); if (_speechLoaded) { - _volumeDirection = 1; - _volumeTo = 6; - playChannel1(50 + 12); + _sound->volumeChange(6, 1); + _sound->playChannel1(50 + 12); } } } @@ -155,9 +153,9 @@ void DreamWebEngine::doSomeTalk() { printDirect(str, 164, 64, 144, false); - loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos); + _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos); if (_speechLoaded) - playChannel1(62); + _sound->playChannel1(62); _pointerMode = 3; workToScreenM(); @@ -181,9 +179,9 @@ void DreamWebEngine::doSomeTalk() { convIcons(); printDirect(str, 48, 128, 144, false); - loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos); + _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', (64 * (_character & 0x7F)) + _talkPos); if (_speechLoaded) - playChannel1(62); + _sound->playChannel1(62); _pointerMode = 3; workToScreenM(); @@ -220,11 +218,11 @@ bool DreamWebEngine::hangOnPQ() { // Quit conversation delPointer(); _pointerMode = 0; - cancelCh1(); + _sound->cancelCh1(); return true; } - if (_speechLoaded && _channel1Playing == 255) { + if (_speechLoaded && !_sound->isChannel1Playing()) { speechFlag++; if (speechFlag == 40) break; @@ -237,7 +235,7 @@ bool DreamWebEngine::hangOnPQ() { } void DreamWebEngine::redes() { - if (_channel1Playing != 255 || _talkMode != 2) { + if (_sound->isChannel1Playing() || _talkMode != 2) { blank(); return; } diff --git a/engines/dreamweb/titles.cpp b/engines/dreamweb/titles.cpp index 3ed31fe13a..fa6b1060fb 100644 --- a/engines/dreamweb/titles.cpp +++ b/engines/dreamweb/titles.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" #include "engines/util.h" @@ -32,38 +33,36 @@ void DreamWebEngine::endGame() { return; gettingShot(); getRidOfTempText(); - _volumeTo = 7; - _volumeDirection = 1; + _sound->volumeChange(7, 1); hangOn(200); } void DreamWebEngine::monkSpeaking() { _roomsSample = 35; - loadRoomsSample(); + _sound->loadRoomsSample(_roomsSample); GraphicsFile graphics; loadGraphicsFile(graphics, "G15"); clearWork(); showFrame(graphics, 160, 72, 0, 128); // show monk workToScreen(); - _volume = 7; - _volumeDirection = -1; - _volumeTo = hasSpeech() ? 5 : 0; - playChannel0(12, 255); + _sound->volumeSet(7); + _sound->volumeChange(hasSpeech() ? 5 : 0, -1); + _sound->playChannel0(12, 255); fadeScreenUps(); hangOn(300); // TODO: Subtitles+speech mode if (hasSpeech()) { for (int i = 40; i < 48; i++) { - loadSpeech('T', 83, 'T', i); + _speechLoaded = _sound->loadSpeech('T', 83, 'T', i); - playChannel1(50 + 12); + _sound->playChannel1(50 + 12); do { waitForVSync(); if (_quitRequested) return; - } while (_channel1Playing != 255); + } while (_sound->isChannel1Playing()); } } else { for (int i = 40; i <= 44; i++) { @@ -83,8 +82,7 @@ void DreamWebEngine::monkSpeaking() { } } - _volumeDirection = 1; - _volumeTo = 7; + _sound->volumeChange(7, 1); fadeScreenDowns(); hangOn(300); graphics.clear(); @@ -95,8 +93,7 @@ void DreamWebEngine::gettingShot() { clearPalette(); loadIntroRoom(); fadeScreenUps(); - _volumeTo = 0; - _volumeDirection = -1; + _sound->volumeChange(0, -1); runEndSeq(); clearBeforeLoad(); } @@ -127,7 +124,7 @@ void DreamWebEngine::bibleQuote() { return; // "biblequotearly" } - cancelCh0(); + _sound->cancelCh0(); _lastHardKey = 0; } @@ -147,10 +144,9 @@ void DreamWebEngine::intro() { _newLocation = 50; clearPalette(); loadIntroRoom(); - _volume = 7; - _volumeDirection = -1; - _volumeTo = hasSpeech() ? 4 : 0; - playChannel0(12, 255); + _sound->volumeSet(7); + _sound->volumeChange(hasSpeech() ? 4 : 0, -1); + _sound->playChannel0(12, 255); fadeScreenUps(); runIntroSeq(); @@ -286,14 +282,14 @@ void DreamWebEngine::set16ColPalette() { void DreamWebEngine::realCredits() { _roomsSample = 33; - loadRoomsSample(); - _volume = 0; + _sound->loadRoomsSample(_roomsSample); + _sound->volumeSet(0); initGraphics(640, 480, true); hangOn(35); showPCX("I01"); - playChannel0(12, 0); + _sound->playChannel0(12, 0); hangOne(2); @@ -319,7 +315,7 @@ void DreamWebEngine::realCredits() { } showPCX("I02"); - playChannel0(12, 0); + _sound->playChannel0(12, 0); hangOne(2); if (_lastHardKey == 1) { @@ -344,7 +340,7 @@ void DreamWebEngine::realCredits() { } showPCX("I03"); - playChannel0(12, 0); + _sound->playChannel0(12, 0); hangOne(2); if (_lastHardKey == 1) { @@ -369,7 +365,7 @@ void DreamWebEngine::realCredits() { } showPCX("I04"); - playChannel0(12, 0); + _sound->playChannel0(12, 0); hangOne(2); if (_lastHardKey == 1) { @@ -394,7 +390,7 @@ void DreamWebEngine::realCredits() { } showPCX("I05"); - playChannel0(12, 0); + _sound->playChannel0(12, 0); hangOne(2); if (_lastHardKey == 1) { @@ -427,7 +423,7 @@ void DreamWebEngine::realCredits() { return; // "realcreditsearly" } - playChannel0(13, 0); + _sound->playChannel0(13, 0); hangOne(350); if (_lastHardKey == 1) { diff --git a/engines/dreamweb/use.cpp b/engines/dreamweb/use.cpp index e59843539f..995eef04cd 100644 --- a/engines/dreamweb/use.cpp +++ b/engines/dreamweb/use.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -201,13 +202,13 @@ void DreamWebEngine::edensCDPlayer() { } void DreamWebEngine::hotelBell() { - playChannel1(12); + _sound->playChannel1(12); showFirstUse(); putBackObStuff(); } void DreamWebEngine::playGuitar() { - playChannel1(14); + _sound->playChannel1(14); showFirstUse(); putBackObStuff(); } @@ -273,13 +274,13 @@ void DreamWebEngine::useHatch() { } void DreamWebEngine::wheelSound() { - playChannel1(17); + _sound->playChannel1(17); showFirstUse(); putBackObStuff(); } void DreamWebEngine::callHotelLift() { - playChannel1(12); + _sound->playChannel1(12); showFirstUse(); _vars._countToOpen = 8; _getBack = 1; @@ -382,7 +383,7 @@ void DreamWebEngine::sitDownInBar() { } void DreamWebEngine::useDryer() { - playChannel1(12); + _sound->playChannel1(12); showFirstUse(); _getBack = 1; } @@ -887,7 +888,7 @@ void DreamWebEngine::usePlate() { if (compare(_withObject, _withType, "SCRW")) { // Unscrew plate - playChannel1(20); + _sound->playChannel1(20); showFirstUse(); placeSetObject(28); placeSetObject(24); @@ -992,7 +993,7 @@ void DreamWebEngine::useCart() { removeSetObject(_command); placeSetObject(_command + 1); _vars._progressPoints++; - playChannel1(17); + _sound->playChannel1(17); showFirstUse(); _getBack = 1; } @@ -1035,7 +1036,7 @@ void DreamWebEngine::openHotelDoor() { if (defaultUseHandler("KEYA")) return; - playChannel1(16); + _sound->playChannel1(16); showFirstUse(); _vars._lockStatus = 0; _getBack = 1; @@ -1045,7 +1046,7 @@ void DreamWebEngine::openHotelDoor2() { if (defaultUseHandler("KEYA")) return; - playChannel1(16); + _sound->playChannel1(16); showFirstUse(); putBackObStuff(); } @@ -1067,7 +1068,7 @@ void DreamWebEngine::usePoolReader() { showSecondUse(); putBackObStuff(); } else { - playChannel1(17); + _sound->playChannel1(17); showFirstUse(); _vars._countToOpen = 6; _getBack = 1; @@ -1088,7 +1089,7 @@ void DreamWebEngine::useCardReader1() { putBackObStuff(); } else { // Get cash - playChannel1(16); + _sound->playChannel1(16); showPuzText(18, 300); _vars._progressPoints++; _vars._card1Money = 12432; @@ -1113,7 +1114,7 @@ void DreamWebEngine::useCardReader2() { showPuzText(22, 300); putBackObStuff(); } else { - playChannel1(18); + _sound->playChannel1(18); showPuzText(19, 300); placeSetObject(94); _vars._gunPassFlag = 1; @@ -1136,7 +1137,7 @@ void DreamWebEngine::useCardReader3() { showPuzText(26, 300); putBackObStuff(); } else { - playChannel1(16); + _sound->playChannel1(16); showPuzText(25, 300); _vars._progressPoints++; _vars._card1Money -= 8300; @@ -1232,7 +1233,7 @@ void DreamWebEngine::useControl() { } if (compare(_withObject, _withType, "KEYA")) { // Right key - playChannel1(16); + _sound->playChannel1(16); if (_vars._location == 21) { // Going down showPuzText(3, 300); _newLocation = 30; @@ -1257,7 +1258,7 @@ void DreamWebEngine::useControl() { placeSetObject(30); removeSetObject(16); removeSetObject(17); - playChannel1(14); + _sound->playChannel1(14); showPuzText(10, 300); _vars._progressPoints++; _getBack = 1; @@ -1375,7 +1376,7 @@ void DreamWebEngine::runTap() { // Fill cup from tap DynObject *exObject = getExAd(_withObject); exObject->objId[3] = 'F'-'A'; // CUPE (empty cup) -> CUPF (full cup) - playChannel1(8); + _sound->playChannel1(8); showPuzText(57, 300); putBackObStuff(); return; diff --git a/engines/dreamweb/vgafades.cpp b/engines/dreamweb/vgafades.cpp index 6f9fd5f53c..c8f05641b5 100644 --- a/engines/dreamweb/vgafades.cpp +++ b/engines/dreamweb/vgafades.cpp @@ -20,6 +20,7 @@ * */ +#include "dreamweb/sound.h" #include "dreamweb/dreamweb.h" namespace DreamWeb { @@ -123,7 +124,7 @@ void DreamWebEngine::fadeUpMonFirst() { _colourPos = 0; _numToFade = 128; hangOn(64); - playChannel1(26); + _sound->playChannel1(26); hangOn(64); } -- cgit v1.2.3 From 6691424397bd9db6e022e64ca0b5c91e24d8d35d Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 31 May 2012 05:39:08 +0100 Subject: DREAMWEB: Remove irrelevant additions in SFX id 62 usage. --- engines/dreamweb/stubs.cpp | 2 +- engines/dreamweb/talk.cpp | 2 +- engines/dreamweb/titles.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engines/dreamweb/stubs.cpp b/engines/dreamweb/stubs.cpp index 3aa8e6da74..4515939ebc 100644 --- a/engines/dreamweb/stubs.cpp +++ b/engines/dreamweb/stubs.cpp @@ -969,7 +969,7 @@ void DreamWebEngine::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, if (hasSpeech() && voiceIndex != 0) { _speechLoaded = _sound->loadSpeech('T', voiceIndex, 'T', textIndex); if (_speechLoaded) - _sound->playChannel1(50+12); + _sound->playChannel1(62); if (_speechLoaded && !_subtitles) return; diff --git a/engines/dreamweb/talk.cpp b/engines/dreamweb/talk.cpp index ca99269cc8..2629c23355 100644 --- a/engines/dreamweb/talk.cpp +++ b/engines/dreamweb/talk.cpp @@ -102,7 +102,7 @@ void DreamWebEngine::startTalk() { _speechLoaded = _sound->loadSpeech('R', _realLocation, 'C', 64*(_character & 0x7F)); if (_speechLoaded) { _sound->volumeChange(6, 1); - _sound->playChannel1(50 + 12); + _sound->playChannel1(62); } } } diff --git a/engines/dreamweb/titles.cpp b/engines/dreamweb/titles.cpp index fa6b1060fb..f005279ba0 100644 --- a/engines/dreamweb/titles.cpp +++ b/engines/dreamweb/titles.cpp @@ -56,7 +56,7 @@ void DreamWebEngine::monkSpeaking() { for (int i = 40; i < 48; i++) { _speechLoaded = _sound->loadSpeech('T', 83, 'T', i); - _sound->playChannel1(50 + 12); + _sound->playChannel1(62); do { waitForVSync(); -- cgit v1.2.3 From 5de3f9c765ff50ffb386bf62213c882bd5c93cf1 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 31 May 2012 10:30:29 +0200 Subject: ALL: Correct spelling of "Mac OS X" in various places --- backends/graphics/openglsdl/openglsdl-graphics.cpp | 2 +- backends/graphics/surfacesdl/surfacesdl-graphics.cpp | 2 +- common/taskbar.h | 2 +- common/updates.h | 2 +- configure | 4 ++-- dists/scummvm.6 | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index b37d631c6d..67041ae17b 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -160,7 +160,7 @@ void OpenGLSdlGraphicsManager::detectSupportedFormats() { _hwscreen->format->Rshift, _hwscreen->format->Gshift, _hwscreen->format->Bshift, _hwscreen->format->Ashift); - // Workaround to MacOSX SDL not providing an accurate Aloss value. + // Workaround to SDL not providing an accurate Aloss value on Mac OS X. if (_hwscreen->format->Amask == 0) format.aLoss = 8; diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index 9631c3c07e..e841ecb834 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -458,7 +458,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() { _hwscreen->format->Rshift, _hwscreen->format->Gshift, _hwscreen->format->Bshift, _hwscreen->format->Ashift); - // Workaround to MacOSX SDL not providing an accurate Aloss value. + // Workaround to SDL not providing an accurate Aloss value on Mac OS X. if (_hwscreen->format->Amask == 0) format.aLoss = 8; diff --git a/common/taskbar.h b/common/taskbar.h index ba99d4e487..6f28028e74 100644 --- a/common/taskbar.h +++ b/common/taskbar.h @@ -34,7 +34,7 @@ namespace Common { * The TaskbarManager allows interaction with the ScummVM application icon: * - in the taskbar on Windows 7 and later * - in the launcher for Unity - * - in the dock on MacOSX + * - in the dock on Mac OS X * - ... * * This allows GUI code and engines to display a progress bar, an overlay icon and/or count diff --git a/common/updates.h b/common/updates.h index 1e0babdf6d..4d58a216fb 100644 --- a/common/updates.h +++ b/common/updates.h @@ -30,7 +30,7 @@ namespace Common { /** * The UpdateManager allows configuring of the automatic update checking * for systems that support it: - * - using Sparkle on MacOSX + * - using Sparkle on Mac OS X * - using WinSparkle on Windows * * Most of the update checking is completely automated and this class only diff --git a/configure b/configure index d310148f06..5905f408a0 100755 --- a/configure +++ b/configure @@ -835,8 +835,8 @@ Optional Libraries: installed (optional) --disable-fluidsynth disable fluidsynth MIDI driver [autodetect] - --with-sparkle-prefix=DIR Prefix where sparkle is installed (MacOSX only - optional) - --disable-sparkle disable sparkle automatic update support [MacOSX only - autodetect] + --with-sparkle-prefix=DIR Prefix where sparkle is installed (Mac OS X only - optional) + --disable-sparkle disable sparkle automatic update support [Mac OS X only - autodetect] --with-sdl-prefix=DIR Prefix where the sdl-config script is installed (optional) diff --git a/dists/scummvm.6 b/dists/scummvm.6 index b192104684..2075a5c8f5 100644 --- a/dists/scummvm.6 +++ b/dists/scummvm.6 @@ -37,7 +37,7 @@ Output using ALSA sequencer device .It Em amidi Use the MorphOS MIDI system, for MorphOS users .It Em core -CoreAudio sound, for MacOS X users +CoreAudio sound, for Mac OS X users .It Em mt32 MT-32 emulation .It Em null -- cgit v1.2.3 From dfa5405db8c33f91936d022954175799ea54658d Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Thu, 31 May 2012 18:53:47 +1000 Subject: SCUMM: Change the nest.number default to zero in stopScript and stopObjectScript too. --- engines/scumm/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index a26c64e690..d8c4948ea8 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -250,7 +250,7 @@ void ScummEngine::stopScript(int script) { if (vm.nest[i].number == script && (vm.nest[i].where == WIO_GLOBAL || vm.nest[i].where == WIO_LOCAL)) { nukeArrays(vm.nest[i].slot); - vm.nest[i].number = 0xFF; + vm.nest[i].number = 0; vm.nest[i].slot = 0xFF; vm.nest[i].where = 0xFF; } @@ -284,7 +284,7 @@ void ScummEngine::stopObjectScript(int script) { if (vm.nest[i].number == script && (vm.nest[i].where == WIO_ROOM || vm.nest[i].where == WIO_INVENTORY || vm.nest[i].where == WIO_FLOBJECT)) { nukeArrays(vm.nest[i].slot); - vm.nest[i].number = 0xFF; + vm.nest[i].number = 0; vm.nest[i].slot = 0xFF; vm.nest[i].where = 0xFF; } -- cgit v1.2.3 From 79f6f63daf1c3f33631748234ba4b582bdc2a219 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Fri, 1 Jun 2012 14:30:47 +1000 Subject: SCUMM: Add debugInput opcode difference in Backyard Basketball. --- engines/scumm/he/script_v100he.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index 56ea10f507..d2e01a6564 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -2339,6 +2339,12 @@ void ScummEngine_v100he::o100_writeFile() { } void ScummEngine_v100he::o100_debugInput() { + // Backyard Basketball uses older code for this opcode + if (_game.id == GID_BASKETBALL) { + ScummEngine_v72he::o72_debugInput(); + return; + } + byte subOp = fetchScriptByte(); switch (subOp) { -- cgit v1.2.3 From d9983a6224dcc82d56a7b3d6d2aaad79def96766 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sat, 2 Jun 2012 07:03:40 +0100 Subject: DREAMWEB: Cleanup of debugging code and formatting in sound code. This commit removes various temporary debugging output, cleans up some points of formatting and replaces some hexadecimal sizes and offsets with decimal for readability. --- engines/dreamweb/sound.cpp | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp index 83ddebc552..4b636d4789 100644 --- a/engines/dreamweb/sound.cpp +++ b/engines/dreamweb/sound.cpp @@ -85,6 +85,7 @@ void DreamWebSound::playChannel0(uint8 index, uint8 repeat) { } void DreamWebSound::playChannel1(uint8 index) { + debug(1, "playChannel1(index:%d)", index); if (_channel1Playing == 7) return; @@ -99,6 +100,7 @@ void DreamWebSound::cancelCh0() { } void DreamWebSound::cancelCh1() { + debug(1, "cancelCh1()"); _channel1Playing = 255; stopSound(1); } @@ -123,7 +125,7 @@ void DreamWebSound::loadRoomsSample(uint8 sample) { } void DreamWebSound::playSound(uint8 channel, uint8 id, uint8 loops) { - debug(1, "playSound(%u, %u, %u)", channel, id, loops); + debug(1, "playSound(channel:%u, id:%u, loops:%u)", channel, id, loops); int bank = 0; bool speech = false; @@ -153,23 +155,18 @@ void DreamWebSound::playSound(uint8 channel, uint8 id, uint8 loops) { error("out of memory: cannot allocate memory for sound(%u bytes)", sample.size); memcpy(buffer, data.data.begin() + sample.offset, sample.size); - raw = Audio::makeRawStream( - buffer, - sample.size, 22050, Audio::FLAG_UNSIGNED); + raw = Audio::makeRawStream(buffer, sample.size, 22050, Audio::FLAG_UNSIGNED); } else { uint8 *buffer = (uint8 *)malloc(_speechData.size()); if (!buffer) error("out of memory: cannot allocate memory for sound(%u bytes)", _speechData.size()); memcpy(buffer, _speechData.begin(), _speechData.size()); - raw = Audio::makeRawStream( - buffer, - _speechData.size(), 22050, Audio::FLAG_UNSIGNED); - + raw = Audio::makeRawStream(buffer, _speechData.size(), 22050, Audio::FLAG_UNSIGNED); } Audio::AudioStream *stream; if (loops > 1) { - stream = new Audio::LoopingAudioStream(raw, loops < 255? loops: 0); + stream = new Audio::LoopingAudioStream(raw, (loops < 255) ? loops : 0); } else stream = raw; @@ -206,11 +203,6 @@ bool DreamWebSound::loadSpeech(const Common::String &filename) { } void DreamWebSound::soundHandler() { - static uint8 volumeOld = 0, channel0Old = 0, channel0PlayingOld = 0; - if (_volume != volumeOld || _channel0 != channel0Old || _channel0Playing != channel0PlayingOld) - debug(1, "soundHandler() _volume: %d _channel0: %d _channel0Playing: %d", _volume, _channel0, _channel0Playing); - volumeOld = _volume, channel0Old = _channel0, channel0PlayingOld = _channel0Playing; - _vm->_subtitles = ConfMan.getBool("subtitles"); volumeAdjust(); @@ -250,9 +242,8 @@ void DreamWebSound::soundHandler() { playSound(1, ch1, 1); } } + if (!_vm->_mixer->isSoundHandleActive(_channelHandle[0])) { - if (_channel0Playing != 255 && _channel0 != 0) - debug(1, "!_mixer->isSoundHandleActive _channelHandle[0] _channel0Playing:%d _channel0:%d", _channel0Playing, _channel0); _channel0Playing = 255; _channel0 = 0; } @@ -271,9 +262,9 @@ void DreamWebSound::loadSounds(uint bank, const Common::String &suffix) { return; } - uint8 header[0x60]; + uint8 header[96]; file.read(header, sizeof(header)); - uint tablesize = READ_LE_UINT16(header + 0x32); + uint tablesize = READ_LE_UINT16(header + 50); debug(1, "table size = %u", tablesize); SoundData &soundData = _soundData[bank]; @@ -283,8 +274,8 @@ void DreamWebSound::loadSounds(uint bank, const Common::String &suffix) { uint8 entry[6]; Sample &sample = soundData.samples[i]; file.read(entry, sizeof(entry)); - sample.offset = entry[0] * 0x4000 + READ_LE_UINT16(entry + 1); - sample.size = READ_LE_UINT16(entry + 3) * 0x800; + sample.offset = entry[0] * 16384 + READ_LE_UINT16(entry + 1); + sample.size = READ_LE_UINT16(entry + 3) * 2048; total += sample.size; debug(1, "offset: %08x, size: %u", sample.offset, sample.size); } -- cgit v1.2.3 From c1dd3d5c2986f6c688eaf5ea80034658840b2828 Mon Sep 17 00:00:00 2001 From: Lars Skovlund Date: Sat, 2 Jun 2012 18:50:46 +0200 Subject: SCI32: Implement GetConfig("language") --- engines/sci/engine/kmisc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 2911af97df..9a113bc5f9 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -381,6 +381,9 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { s->_segMan->strcpy(data, "586"); } else if (setting == "cpuspeed") { s->_segMan->strcpy(data, "500"); + } else if (setting == "language") { + Common::String languageId = Common::String::format("%d", g_sci->getSciLanguage()); + s->_segMan->strcpy(data, languageId.c_str()); } else { error("GetConfig: Unknown configuration setting %s", setting.c_str()); } -- cgit v1.2.3 From 3eeb3d74163f2682bc27968df5e5e389174cdc1e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 2 Jun 2012 20:50:18 +0200 Subject: GOB: Correctly name the Penetration script variables --- engines/gob/inter_geisha.cpp | 10 +++++----- engines/gob/minigames/geisha/penetration.cpp | 2 +- engines/gob/minigames/geisha/penetration.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 7f21ceb91d..99f834d4d7 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -272,12 +272,12 @@ void Inter_Geisha::oGeisha_writeData(OpFuncParams ¶ms) { } void Inter_Geisha::oGeisha_gamePenetration(OpGobParams ¶ms) { - uint16 var1 = _vm->_game->_script->readUint16(); - uint16 var2 = _vm->_game->_script->readUint16(); - uint16 var3 = _vm->_game->_script->readUint16(); - uint16 resultVar = _vm->_game->_script->readUint16(); + uint16 hasAccessPass = _vm->_game->_script->readUint16(); + uint16 hasMaxEnergy = _vm->_game->_script->readUint16(); + uint16 testMode = _vm->_game->_script->readUint16(); + uint16 resultVar = _vm->_game->_script->readUint16(); - bool result = _penetration->play(var1, var2, var3); + bool result = _penetration->play(hasAccessPass, hasMaxEnergy, testMode); WRITE_VAR_UINT32(resultVar, result ? 1 : 0); } diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 121a45bc40..153f2a6766 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -62,7 +62,7 @@ Penetration::~Penetration() { delete _background; } -bool Penetration::play(uint16 var1, uint16 var2, uint16 var3) { +bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { init(); initScreen(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index c346a7bf5a..3f9aac7963 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -39,7 +39,7 @@ public: Penetration(GobEngine *vm); ~Penetration(); - bool play(uint16 var1, uint16 var2, uint16 var3); + bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode); private: GobEngine *_vm; -- cgit v1.2.3 From 585ceb566f27880ae7ea426efc70192b03a26d8d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 2 Jun 2012 22:12:25 +0200 Subject: GOB: Add animation handling frame to Penetration --- engines/gob/minigames/geisha/penetration.cpp | 60 ++++++++++++++++++++++++++-- engines/gob/minigames/geisha/penetration.h | 9 +++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 153f2a6766..1bdc574aa3 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -25,7 +25,9 @@ #include "gob/draw.h" #include "gob/video.h" #include "gob/decfile.h" +#include "gob/cmpfile.h" #include "gob/anifile.h" +#include "gob/aniobject.h" #include "gob/minigames/geisha/penetration.h" @@ -52,7 +54,7 @@ static const byte kPalette[48] = { 0x15, 0x3F, 0x15 }; -Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _objects(0) { +Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0) { _background = new Surface(320, 200, 1); } @@ -68,11 +70,28 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_draw->blitInvalidated(); _vm->_video->retrace(); - while (!_vm->_util->keyPressed() && !_vm->shouldQuit()) - _vm->_util->longDelay(1); + + while (!_vm->shouldQuit()) { + updateAnims(); + + // Draw and wait for the end of the frame + _vm->_draw->blitInvalidated(); + _vm->_util->waitEndFrame(); + + // Handle input + _vm->_util->processInput(); + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + // Aborting the game + if (key == kKeyEscape) + break; + } deinit(); - return true; + return false; } void Penetration::init() { @@ -80,13 +99,18 @@ void Penetration::init() { _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background); + _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200); _objects = new ANIFile(_vm, "tcite.ani", 320); } void Penetration::deinit() { + _anims.clear(); + delete _objects; + delete _sprites; _objects = 0; + _sprites = 0; } void Penetration::initScreen() { @@ -101,6 +125,34 @@ void Penetration::initScreen() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } +int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) { + _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons); + + return _vm->_util->checkKey(); +} + +void Penetration::updateAnims() { + int16 left, top, right, bottom; + + // Clear the previous animation frames + for (Common::List::iterator a = _anims.reverse_begin(); + a != _anims.end(); --a) { + + (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + } + + // Draw the current animation frames + for (Common::List::iterator a = _anims.begin(); + a != _anims.end(); ++a) { + + (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + (*a)->advance(); + } +} + } // End of namespace Geisha } // End of namespace Gob diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 3f9aac7963..9bf87503f0 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -24,11 +24,13 @@ #define GOB_MINIGAMES_GEISHA_PENETRATION_H #include "common/system.h" +#include "common/list.h" namespace Gob { class GobEngine; class Surface; +class CMPFile; class ANIFile; namespace Geisha { @@ -45,13 +47,20 @@ private: GobEngine *_vm; Surface *_background; + CMPFile *_sprites; ANIFile *_objects; + Common::List _anims; + void init(); void deinit(); void initScreen(); + + void updateAnims(); + + int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); }; } // End of namespace Geisha -- cgit v1.2.3 From 030509c8eb4544885dabf67b85f83d3b296230de Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 2 Jun 2012 23:12:25 +0200 Subject: GOB: Draw the shield and health meters in Penetration --- engines/gob/minigames/geisha/meter.cpp | 4 +++ engines/gob/minigames/geisha/meter.h | 2 ++ engines/gob/minigames/geisha/penetration.cpp | 39 +++++++++++++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 8 ++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp index e3b9bd1ccf..9dcc717e48 100644 --- a/engines/gob/minigames/geisha/meter.cpp +++ b/engines/gob/minigames/geisha/meter.cpp @@ -42,6 +42,10 @@ Meter::~Meter() { delete _surface; } +int32 Meter::getMaxValue() const { + return _maxValue; +} + int32 Meter::getValue() const { return _value; } diff --git a/engines/gob/minigames/geisha/meter.h b/engines/gob/minigames/geisha/meter.h index a9bdb14d0f..d3e82cb32e 100644 --- a/engines/gob/minigames/geisha/meter.h +++ b/engines/gob/minigames/geisha/meter.h @@ -44,6 +44,8 @@ public: Direction direction); ~Meter(); + /** Return the max value the meter is measuring. */ + int32 getMaxValue() const; /** Return the current value the meter is measuring. */ int32 getValue() const; diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 1bdc574aa3..8b5de27ad2 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -30,6 +30,7 @@ #include "gob/aniobject.h" #include "gob/minigames/geisha/penetration.h" +#include "gob/minigames/geisha/meter.h" namespace Gob { @@ -54,17 +55,29 @@ static const byte kPalette[48] = { 0x15, 0x3F, 0x15 }; -Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0) { +Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), + _shieldMeter(0), _healthMeter(0) { + _background = new Surface(320, 200, 1); + + _shieldMeter = new Meter(11, 119, 92, 3, 11, 10, 1020, Meter::kFillToRight); + _healthMeter = new Meter(11, 137, 92, 3, 15, 10, 1020, Meter::kFillToRight); } Penetration::~Penetration() { deinit(); + delete _shieldMeter; + delete _healthMeter; + delete _background; } bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { + _hasAccessPass = hasAccessPass; + _hasMaxEnergy = hasMaxEnergy; + _testMode = testMode; + init(); initScreen(); @@ -101,6 +114,23 @@ void Penetration::init() { _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200); _objects = new ANIFile(_vm, "tcite.ani", 320); + + // Draw the shield meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame + _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield + + // Draw the health meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame + _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart + + // The shield starts down + _shieldMeter->setValue(0); + + // If we don't have the max energy tokens, the health starts at 1/3 strength + if (_hasMaxEnergy) + _healthMeter->setMaxValue(); + else + _healthMeter->setValue(_healthMeter->getMaxValue() / 3); } void Penetration::deinit() { @@ -151,6 +181,13 @@ void Penetration::updateAnims() { (*a)->advance(); } + + // Draw the meters + _shieldMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + _healthMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } } // End of namespace Geisha diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 9bf87503f0..6c32d28942 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -35,6 +35,8 @@ class ANIFile; namespace Geisha { +class Meter; + /** Geisha's "Penetration" minigame. */ class Penetration { public: @@ -46,12 +48,18 @@ public: private: GobEngine *_vm; + bool _hasAccessPass; + bool _hasMaxEnergy; + bool _testMode; + Surface *_background; CMPFile *_sprites; ANIFile *_objects; Common::List _anims; + Meter *_shieldMeter; + Meter *_healthMeter; void init(); void deinit(); -- cgit v1.2.3 From db77b9e4a7f8491d45b47b539af2077fb15e9376 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sat, 2 Jun 2012 22:28:34 +0100 Subject: DREAMWEB: Modify sound code to prevent missing sound effects. This should fix bug #3528164 "DREAMWEB: missing sound effects/music cues during main title" by preventing repeated calls of SFX id 12 being lost if the next call is made before the sound handler has cleared the previous one. --- engines/dreamweb/sound.cpp | 10 +++++++++- engines/dreamweb/sound.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp index 4b636d4789..76c734e932 100644 --- a/engines/dreamweb/sound.cpp +++ b/engines/dreamweb/sound.cpp @@ -41,6 +41,7 @@ DreamWebSound::DreamWebSound(DreamWebEngine *vm) : _vm(vm) { _currentSample = 0xff; _channel0Playing = 0; _channel0Repeat = 0; + _channel0NewSound = false; _channel1Playing = 255; _volume = 0; @@ -80,6 +81,12 @@ void DreamWebSound::volumeAdjust() { void DreamWebSound::playChannel0(uint8 index, uint8 repeat) { debug(1, "playChannel0(index:%d, repeat:%d)", index, repeat); + + if (index == _channel0Playing) { + warning("playChannel0(index: %d) already playing! Forcing restart...", index); + _channel0NewSound = true; + } + _channel0Playing = index; _channel0Repeat = repeat; } @@ -230,8 +237,9 @@ void DreamWebSound::soundHandler() { ch1 = 0; uint8 ch0loop = _channel0Repeat; - if (_channel0 != ch0) { + if (_channel0 != ch0 || _channel0NewSound) { _channel0 = ch0; + _channel0NewSound = false; if (ch0) { playSound(0, ch0, ch0loop); } diff --git a/engines/dreamweb/sound.h b/engines/dreamweb/sound.h index 62def157e7..a38dbf3c1a 100644 --- a/engines/dreamweb/sound.h +++ b/engines/dreamweb/sound.h @@ -73,6 +73,7 @@ private: uint8 _currentSample; uint8 _channel0Playing; uint8 _channel0Repeat; + bool _channel0NewSound; uint8 _channel1Playing; uint8 _volume; -- cgit v1.2.3 From 43abb525d4004cb0816c8ea506b0b963d784ccf3 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 00:20:39 +0200 Subject: GOB: Draw the map in a separate surface Still hidden for now. --- engines/gob/minigames/geisha/penetration.cpp | 236 +++++++++++++++++++++++++-- engines/gob/minigames/geisha/penetration.h | 15 ++ 2 files changed, 241 insertions(+), 10 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 8b5de27ad2..77edebce48 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -55,18 +55,137 @@ static const byte kPalette[48] = { 0x15, 0x3F, 0x15 }; +static const int kColorShield = 11; +static const int kColorHealth = 15; +static const int kColorBlack = 10; +static const int kColorFloor = 13; + +static const int kMapTileWidth = 24; +static const int kMapTileHeight = 24; + +static const int kPlayAreaX = 120; +static const int kPlayAreaY = 7; +static const int kPlayAreaWidth = 192; +static const int kPlayAreaHeight = 113; + +static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2; +static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2; + +const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = { + { + { // Real mode, floor 0 + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 0, 50, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 50, 0, 0, 50, 50, 50, 50, 0, 54, 55, 0, 0, 50, 0, 50, + 50, 0, 50, 49, 0, 50, 0, 52, 53, 0, 50, 50, 50, 0, 0, 0, 50, + 50, 57, 0, 50, 0, 0, 0, 50, 50, 50, 0, 0, 56, 50, 54, 55, 50, + 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 0, 50, 0, 0, 50, 0, 50, + 50, 51, 50, 0, 54, 55, 0, 0, 50, 50, 50, 50, 52, 53, 50, 0, 50, + 50, 0, 50, 0, 0, 0, 0, 0, 54, 55, 0, 0, 0, 50, 0, 0, 50, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, + 50, 50, 0, 52, 53, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 50, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0 + }, + { // Real mode, floor 1 + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 50, 51, 52, 53, 0, 0, 52, 53, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 50, 0, 50, 0, 50, 0, 50, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 52, 53, 0, 0, 0, 0, 0, 52, 53, 0, 52, 53, 50, + 50, 57, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 50, 52, 53, 0, 0, 52, 53, 0, 0, 0, 0, 0, 54, 55, 50, + 50, 0, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 0, 50, 50, 50, + 50, 0, 50, 49, 0, 0, 52, 53, 0, 52, 53, 0, 0, 0, 50, 56, 50, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 0, 0, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0 + }, + { // Real mode, floor 2 + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 52, 53, 0, 0, 0, 0, 50, 50, 50, 0, 0, 0, 0, 52, 53, 50, + 50, 0, 50, 50, 50, 0, 0, 0, 50, 0, 0, 0, 50, 50, 50, 0, 50, + 50, 0, 50, 52, 53, 50, 50, 52, 53, 0, 50, 50, 54, 55, 50, 0, 50, + 50, 0, 50, 0, 0, 0, 0, 50, 0, 50, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 52, 53, 50, + 0, 50, 0, 50, 50, 50, 0, 57, 50, 51, 0, 50, 50, 50, 0, 50, 0, + 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 52, 53, 50, 0, 0, 0, 50, + 50, 0, 50, 0, 0, 0, 0, 50, 56, 50, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 50, 54, 55, 50, 50, 0, 0, 0, 50, 50, 54, 55, 50, 0, 50, + 50, 0, 50, 50, 50, 0, 0, 0, 50, 0, 0, 0, 50, 50, 50, 0, 50, + 50, 52, 53, 0, 0, 0, 0, 50, 50, 50, 0, 0, 0, 0, 52, 53, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0 + } + }, + { + { // Test mode, floor 0 + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 56, 0, 50, 0, 0, 52, 53, 0, 0, 0, 0, 52, 53, 0, 51, 50, + 50, 0, 0, 50, 0, 0, 0, 50, 0, 54, 55, 50, 0, 50, 50, 50, 50, + 50, 52, 53, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, 0, 0, 50, + 50, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 50, 49, 50, 0, 0, 50, + 50, 0, 54, 55, 0, 50, 50, 54, 55, 0, 50, 50, 50, 0, 0, 0, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 54, 55, 50, + 50, 0, 50, 0, 50, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0, 0, 50, + 50, 0, 50, 0, 50, 54, 55, 50, 0, 50, 50, 50, 0, 50, 0, 0, 50, + 50, 50, 50, 50, 50, 0, 0, 50, 0, 0, 0, 0, 0, 50, 54, 55, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 0, 0, 50, + 50, 57, 0, 52, 53, 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + }, + { // Test mode, floor 1 + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 54, 55, 0, 50, + 50, 0, 50, 52, 53, 0, 0, 50, 0, 0, 54, 55, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 0, 52, 53, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 50, 50, 50, 50, 49, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 51, 0, 0, 52, 53, 50, 0, 50, 0, 50, + 50, 57, 50, 0, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, + 50, 50, 50, 0, 50, 56, 0, 0, 0, 54, 55, 0, 0, 0, 50, 0, 50, + 50, 56, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + }, + { // Test mode, floor 2 + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 57, 50, 54, 55, 0, 50, 54, 55, 0, 50, 0, 52, 53, 50, 51, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 52, 53, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50, + 50, 0, 0, 0, 50, 52, 53, 0, 50, 52, 53, 56, 50, 0, 54, 55, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + } + } +}; + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _shieldMeter(0), _healthMeter(0) { _background = new Surface(320, 200, 1); - _shieldMeter = new Meter(11, 119, 92, 3, 11, 10, 1020, Meter::kFillToRight); - _healthMeter = new Meter(11, 137, 92, 3, 15, 10, 1020, Meter::kFillToRight); + _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 1020, Meter::kFillToRight); + _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 1020, Meter::kFillToRight); + + _map = new Surface(kMapWidth * kMapTileWidth + kPlayAreaWidth , + kMapHeight * kMapTileHeight + kPlayAreaHeight, 1); } Penetration::~Penetration() { deinit(); + delete _map; + delete _shieldMeter; delete _healthMeter; @@ -115,14 +234,6 @@ void Penetration::init() { _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200); _objects = new ANIFile(_vm, "tcite.ani", 320); - // Draw the shield meter - _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame - _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield - - // Draw the health meter - _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame - _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart - // The shield starts down _shieldMeter->setValue(0); @@ -131,6 +242,10 @@ void Penetration::init() { _healthMeter->setMaxValue(); else _healthMeter->setValue(_healthMeter->getMaxValue() / 3); + + _floor = 0; + + createMap(); } void Penetration::deinit() { @@ -143,6 +258,99 @@ void Penetration::deinit() { _sprites = 0; } +void Penetration::createMap() { + if (_floor >= kFloorCount) + error("Geisha: Invalid floor %d in minigame penetration", _floor); + + // Copy the correct map + memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); + + _map->fill(kColorBlack); + + // Draw the map tiles + for (int y = 0; y < kMapHeight; y++) { + for (int x = 0; x < kMapWidth; x++) { + byte *mapTile = _mapTiles + (y * kMapWidth + x); + + const int posX = kPlayAreaBorderWidth + x * kMapTileWidth; + const int posY = kPlayAreaBorderHeight + y * kMapTileHeight; + + switch (*mapTile) { + case 0: // Floor + _sprites->draw(*_map, 30, posX, posY); + break; + + case 49: // Emergency exit (needs access pass) + + if (_hasAccessPass) { + // Draw an exit. Now works like a regular exit + _sprites->draw(*_map, 29, posX, posY); + *mapTile = 51; + } else + // Draw a wall + _sprites->draw(*_map, 31, posX, posY); + + break; + + case 50: // Wall + _sprites->draw(*_map, 31, posX, posY); + break; + + case 51: // Regular exit + + if (!_testMode) { + // When we're not in test mode, the last exit only works with an access pass + + if (_floor == 2) { + if (!_hasAccessPass) { + // It's now a wall + _sprites->draw(*_map, 31, posX, posY); + *mapTile = 50; + } else + _sprites->draw(*_map, 29, posX, posY); + + } else + _sprites->draw(*_map, 29, posX, posY); + + } else + // Always works in test mode + _sprites->draw(*_map, 29, posX, posY); + + break; + + case 52: // Left side of biting mouth + _sprites->draw(*_map, 32, posX, posY); + break; + + case 53: // Right side of biting mouth + *mapTile = 0; // Works like a floor + break; + + case 54: // Left side of kissing mouth + _sprites->draw(*_map, 33, posX, posY); + break; + + case 55: // Right side of kissing mouth + *mapTile = 0; // Works like a floor + break; + + case 56: // Shield lying on the floor + _sprites->draw(*_map, 30, posX , posY ); // Floor + _sprites->draw(*_map, 25, posX + 4, posY + 8); // Shield + + _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield + _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield + break; + + case 57: // Start position + _sprites->draw(*_map, 30, posX, posY); + *mapTile = 0; + break; + } + } + } +} + void Penetration::initScreen() { _vm->_util->setFrameRate(15); @@ -151,6 +359,14 @@ void Penetration::initScreen() { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + // Draw the shield meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame + _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield + + // Draw the health meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame + _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart + _vm->_draw->_backSurface->blit(*_background); _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 6c32d28942..897b10940c 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -46,6 +46,14 @@ public: bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode); private: + static const int kModeCount = 2; + static const int kFloorCount = 3; + + static const int kMapWidth = 17; + static const int kMapHeight = 13; + + static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; + GobEngine *_vm; bool _hasAccessPass; @@ -61,9 +69,16 @@ private: Meter *_shieldMeter; Meter *_healthMeter; + uint8 _floor; + + Surface *_map; + byte _mapTiles[kMapWidth * kMapHeight]; + void init(); void deinit(); + void createMap(); + void initScreen(); void updateAnims(); -- cgit v1.2.3 From 8dcb93f2ce04df49dea38f56bc97aef900a05122 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 01:12:21 +0200 Subject: GOB: Draw the Penetration map and do basic movement --- engines/gob/minigames/geisha/penetration.cpp | 44 +++++++++++++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 10 +++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 77edebce48..41346a896f 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -170,7 +170,8 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), - _shieldMeter(0), _healthMeter(0) { + _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), + _subTileX(0), _subTileY(0) { _background = new Surface(320, 200, 1); @@ -220,6 +221,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Aborting the game if (key == kKeyEscape) break; + + // Handle the sub movement + handleSub(key); } deinit(); @@ -345,10 +349,18 @@ void Penetration::createMap() { case 57: // Start position _sprites->draw(*_map, 30, posX, posY); *mapTile = 0; + + _subTileX = x; + _subTileY = y; + + _mapX = _subTileX * kMapTileWidth; + _mapY = _subTileY * kMapTileHeight; break; } } } + + _mapUpdate = true; } void Penetration::initScreen() { @@ -377,6 +389,27 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB return _vm->_util->checkKey(); } +void Penetration::handleSub(int16 key) { + if (key == kKeyLeft) + moveSub(-5, 0); + else if (key == kKeyRight) + moveSub( 5, 0); + else if (key == kKeyUp) + moveSub( 0, -5); + else if (key == kKeyDown) + moveSub( 0, 5); +} + +void Penetration::moveSub(int x, int y) { + _mapX = CLIP(_mapX + x, 0, kMapWidth * kMapTileWidth); + _mapY = CLIP(_mapY + y, 0, kMapHeight * kMapTileHeight); + + _subTileX = _mapX / kMapTileWidth; + _subTileY = _mapY / kMapTileHeight; + + _mapUpdate = true; +} + void Penetration::updateAnims() { int16 left, top, right, bottom; @@ -388,6 +421,15 @@ void Penetration::updateAnims() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } + if (_mapUpdate) { + _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, + _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, + kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); + } + + _mapUpdate = false; + // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); a != _anims.end(); ++a) { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 897b10940c..72201d21d8 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -74,6 +74,13 @@ private: Surface *_map; byte _mapTiles[kMapWidth * kMapHeight]; + bool _mapUpdate; + uint16 _mapX; + uint16 _mapY; + + uint8 _subTileX; + uint8 _subTileY; + void init(); void deinit(); @@ -84,6 +91,9 @@ private: void updateAnims(); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + + void handleSub(int16 key); + void moveSub(int x, int y); }; } // End of namespace Geisha -- cgit v1.2.3 From 95e467d82cb36ee0d98624dd2cdd6d79b544c50c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 01:29:09 +0200 Subject: GOB: Display the Penetration submarine --- engines/gob/minigames/geisha/penetration.cpp | 49 ++++++++++++++++++++++++---- engines/gob/minigames/geisha/penetration.h | 4 ++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 41346a896f..377835c45f 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -60,6 +60,30 @@ static const int kColorHealth = 15; static const int kColorBlack = 10; static const int kColorFloor = 13; +enum Animation { + kAnimationDriveS = 4, + kAnimationDriveE = 5, + kAnimationDriveN = 6, + kAnimationDriveW = 7, + kAnimationDriveSE = 8, + kAnimationDriveNE = 9, + kAnimationDriveSW = 10, + kAnimationDriveNW = 11, + kAnimationShootS = 12, + kAnimationShootN = 13, + kAnimationShootW = 14, + kAnimationShootE = 15, + kAnimationShootNE = 16, + kAnimationShootSE = 17, + kAnimationShootSW = 18, + kAnimationShootNW = 19, + kAnimationExplodeN = 28, + kAnimationExplodeS = 29, + kAnimationExplodeW = 30, + kAnimationExplodeE = 31, + kAnimationExit = 32 +}; + static const int kMapTileWidth = 24; static const int kMapTileHeight = 24; @@ -169,7 +193,7 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = }; -Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), +Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), _subTileX(0), _subTileY(0) { @@ -250,11 +274,21 @@ void Penetration::init() { _floor = 0; createMap(); + + _sub = new ANIObject(*_objects); + + _sub->setAnimation(kAnimationDriveN); + _sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight); + _sub->setVisible(true); + + _anims.push_back(_sub); } void Penetration::deinit() { _anims.clear(); + delete _sub; + delete _objects; delete _sprites; @@ -391,16 +425,16 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB void Penetration::handleSub(int16 key) { if (key == kKeyLeft) - moveSub(-5, 0); + moveSub(-5, 0, kAnimationDriveW); else if (key == kKeyRight) - moveSub( 5, 0); + moveSub( 5, 0, kAnimationDriveE); else if (key == kKeyUp) - moveSub( 0, -5); + moveSub( 0, -5, kAnimationDriveN); else if (key == kKeyDown) - moveSub( 0, 5); + moveSub( 0, 5, kAnimationDriveS); } -void Penetration::moveSub(int x, int y) { +void Penetration::moveSub(int x, int y, uint16 animation) { _mapX = CLIP(_mapX + x, 0, kMapWidth * kMapTileWidth); _mapY = CLIP(_mapY + y, 0, kMapHeight * kMapTileHeight); @@ -408,6 +442,9 @@ void Penetration::moveSub(int x, int y) { _subTileY = _mapY / kMapTileHeight; _mapUpdate = true; + + if (_sub->getAnimation() != animation) + _sub->setAnimation(animation); } void Penetration::updateAnims() { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 72201d21d8..28a288928b 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -64,6 +64,8 @@ private: CMPFile *_sprites; ANIFile *_objects; + ANIObject *_sub; + Common::List _anims; Meter *_shieldMeter; @@ -93,7 +95,7 @@ private: int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); void handleSub(int16 key); - void moveSub(int x, int y); + void moveSub(int x, int y, uint16 animation); }; } // End of namespace Geisha -- cgit v1.2.3 From a401f0a19e09d7d00a3ee94d928db82e658b7b48 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 3 Jun 2012 02:02:57 +0200 Subject: ALL: Replace cursorTargetScale in OSystem API with a simple "do not scale" logic. All uses of the old target scale API actually wanted to disallow scaling of the mouse cursor. This commit adapts our API to this and thus simplifies backend implementations. Some backends, most notable the Wii and Android, did some implementation of the cursor target scale, which I didn't adapt yet. I added a TODO for the porters there. --- backends/graphics/graphics.h | 2 +- backends/graphics/null/null-graphics.h | 2 +- backends/graphics/opengl/opengl-graphics.cpp | 54 +- backends/graphics/opengl/opengl-graphics.h | 4 +- .../graphics/surfacesdl/surfacesdl-graphics.cpp | 94 +-- backends/graphics/surfacesdl/surfacesdl-graphics.h | 4 +- backends/graphics/wincesdl/wincesdl-graphics.cpp | 2 +- backends/graphics/wincesdl/wincesdl-graphics.h | 2 +- backends/modular-backend.cpp | 4 +- backends/modular-backend.h | 2 +- backends/platform/android/android.h | 2 +- backends/platform/android/gfx.cpp | 7 +- backends/platform/dc/dc.h | 2 +- backends/platform/dc/display.cpp | 2 +- backends/platform/ds/arm9/source/osystem_ds.cpp | 6 +- backends/platform/ds/arm9/source/osystem_ds.h | 2 +- backends/platform/iphone/osys_main.h | 2 +- backends/platform/iphone/osys_video.mm | 4 +- backends/platform/n64/osys_n64.h | 2 +- backends/platform/n64/osys_n64_base.cpp | 2 +- backends/platform/ps2/systemps2.cpp | 2 +- backends/platform/ps2/systemps2.h | 2 +- backends/platform/psp/osys_psp.cpp | 6 +- backends/platform/psp/osys_psp.h | 2 +- backends/platform/wii/osystem.h | 2 +- backends/platform/wii/osystem_gfx.cpp | 5 +- common/system.h | 5 +- engines/gob/draw_v1.cpp | 2 +- engines/gob/draw_v2.cpp | 2 +- engines/groovie/cursor.cpp | 2 +- engines/lastexpress/data/cursor.cpp | 2 +- engines/mohawk/cursors.cpp | 2 +- engines/scumm/cursor.cpp | 4 +- graphics/cursorman.cpp | 20 +- graphics/cursorman.h | 14 +- gui/ThemeEngine.cpp | 7 +- gui/ThemeEngine.h | 6 +- gui/ThemeParser.cpp | 7 +- gui/ThemeParser.h | 1 - gui/themes/default.inc | 784 ++++++++++----------- gui/themes/scummclassic.zip | Bin 93390 -> 93390 bytes gui/themes/scummclassic/THEMERC | 2 +- gui/themes/scummmodern.zip | Bin 1449894 -> 1449870 bytes gui/themes/scummmodern/THEMERC | 2 +- gui/themes/scummmodern/scummmodern_gfx.stx | 4 +- 45 files changed, 532 insertions(+), 554 deletions(-) diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h index 3f282df587..0d6fa30418 100644 --- a/backends/graphics/graphics.h +++ b/backends/graphics/graphics.h @@ -80,7 +80,7 @@ public: virtual bool showMouse(bool visible) = 0; virtual void warpMouse(int x, int y) = 0; - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0; + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0; virtual void setCursorPalette(const byte *colors, uint start, uint num) = 0; virtual void displayMessageOnOSD(const char *msg) {} diff --git a/backends/graphics/null/null-graphics.h b/backends/graphics/null/null-graphics.h index 2e6b24d147..2f8baae3e8 100644 --- a/backends/graphics/null/null-graphics.h +++ b/backends/graphics/null/null-graphics.h @@ -78,7 +78,7 @@ public: bool showMouse(bool visible) { return !visible; } void warpMouse(int x, int y) {} - void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) {} + void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) {} void setCursorPalette(const byte *colors, uint start, uint num) {} }; diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index cd820ae3b2..8449048997 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -49,7 +49,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager() _transactionMode(kTransactionNone), _cursorNeedsRedraw(false), _cursorPaletteDisabled(true), _cursorVisible(false), _cursorKeyColor(0), - _cursorTargetScale(1), + _cursorDontScale(false), _formatBGR(false), _displayX(0), _displayY(0), _displayWidth(0), _displayHeight(0) { @@ -591,7 +591,7 @@ void OpenGLGraphicsManager::warpMouse(int x, int y) { setInternalMousePosition(scaledX, scaledY); } -void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { #ifdef USE_RGB_COLOR if (format) _cursorFormat = *format; @@ -616,7 +616,7 @@ void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int _cursorState.hotX = hotspotX; _cursorState.hotY = hotspotY; _cursorKeyColor = keycolor; - _cursorTargetScale = cursorTargetScale; + _cursorDontScale = dontScale; _cursorNeedsRedraw = true; refreshCursorScale(); @@ -829,28 +829,19 @@ void OpenGLGraphicsManager::refreshCursor() { } void OpenGLGraphicsManager::refreshCursorScale() { - // Calculate the scale factors of the screen. We limit ourselves to 3 at - // most here to avoid really big (and ugly) cursors for big resolutions. - // It might be noteworthy that 3 is the (current) target scale for the - // modern theme and thus assures the cursor is *never* scaled. + // Calculate the scale factors of the screen. // We also totally ignore the aspect of the overlay cursor, since aspect // ratio correction only applies to the game screen. - uint screenScaleFactorX = MIN(30000, _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth); - uint screenScaleFactorY = MIN(30000, _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight); - - // Apply the target scale factor to the cursor. - // It might be noteworthy we only apply any scaling to the cursor in case - // the current scale factor is bigger than the target scale to match - // SurfaceSdlGraphicsManager's behavior. Otherwise we would downscale the - // GUI cursor of the modern theme for example. - if (screenScaleFactorX > uint(_cursorTargetScale * 10000)) - screenScaleFactorX /= _cursorTargetScale; - else + // TODO: It might make sense to always ignore scaling of the mouse cursor + // when the overlay is visible. + uint screenScaleFactorX = _videoMode.hardwareWidth * 10000 / _videoMode.screenWidth; + uint screenScaleFactorY = _videoMode.hardwareHeight * 10000 / _videoMode.screenHeight; + + // Ignore scaling when the cursor should not be scaled. + if (_cursorDontScale) { screenScaleFactorX = 10000; - if (screenScaleFactorY > uint(_cursorTargetScale * 10000)) - screenScaleFactorY /= _cursorTargetScale; - else screenScaleFactorY = 10000; + } // Apply them (without any possible) aspect ratio correction to the // overlay. @@ -859,16 +850,19 @@ void OpenGLGraphicsManager::refreshCursorScale() { _cursorState.rHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000); _cursorState.rHotY = (int16)(_cursorState.hotY * screenScaleFactorY / 10000); - // Make sure we properly scale the cursor according to the desired aspect. - // It might be noteworthy that, unlike with the overlay, we do not limit - // the scale factor here to avoid odd looks if the game uses items as - // mouse cursor, which would otherwise suddenly be smaller. - int width, height; - calculateDisplaySize(width, height); - screenScaleFactorX = (width * 10000 / _videoMode.screenWidth) / _cursorTargetScale; - screenScaleFactorY = (height * 10000 / _videoMode.screenHeight) / _cursorTargetScale; + // Only apply scaling when it's desired. + if (_cursorDontScale) { + screenScaleFactorX = 10000; + screenScaleFactorY = 10000; + } else { + // Make sure we properly scale the cursor according to the desired aspect. + int width, height; + calculateDisplaySize(width, height); + screenScaleFactorX = (width * 10000 / _videoMode.screenWidth); + screenScaleFactorY = (height * 10000 / _videoMode.screenHeight); + } - // Always scale the cursor for the game. + // Apply the scale cursor scaling for the game screen. _cursorState.vW = (int16)(_cursorState.w * screenScaleFactorX / 10000); _cursorState.vH = (int16)(_cursorState.h * screenScaleFactorY / 10000); _cursorState.vHotX = (int16)(_cursorState.hotX * screenScaleFactorX / 10000); diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index ad8765bab1..956722c08f 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -104,7 +104,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); virtual void setCursorPalette(const byte *colors, uint start, uint num); virtual void displayMessageOnOSD(const char *msg); @@ -283,7 +283,7 @@ protected: MousePos _cursorState; bool _cursorVisible; uint32 _cursorKeyColor; - int _cursorTargetScale; + bool _cursorDontScale; bool _cursorNeedsRedraw; /** diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp index e841ecb834..652c08dc45 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp @@ -63,17 +63,12 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Normal (no scaling)", "lowres") -// Table of relative scalers magnitudes -// [definedScale - 1][scaleFactor - 1] -static ScalerProc *scalersMagn[3][3] = { +// Table of the cursor scalers [scaleFactor - 1] +static ScalerProc *scalersMagn[3] = { #ifdef USE_SCALERS - { Normal1x, AdvMame2x, AdvMame3x }, - { Normal1x, Normal1x, Normal1o5x }, - { Normal1x, Normal1x, Normal1x } + Normal1x, AdvMame2x, AdvMame3x #else // remove dependencies on other scalers - { Normal1x, Normal1x, Normal1x }, - { Normal1x, Normal1x, Normal1x }, - { Normal1x, Normal1x, Normal1x } + Normal1x, Normal1x, Normal1x #endif }; @@ -135,7 +130,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou _overlayscreen(0), _tmpscreen2(0), _scalerProc(0), _screenChangeCount(0), _mouseVisible(false), _mouseNeedsRedraw(false), _mouseData(0), _mouseSurface(0), - _mouseOrigSurface(0), _cursorTargetScale(1), _cursorPaletteDisabled(true), + _mouseOrigSurface(0), _cursorDontScale(false), _cursorPaletteDisabled(true), _currentShakePos(0), _newShakePos(0), _paletteDirtyStart(0), _paletteDirtyEnd(0), _screenIsLocked(false), @@ -1718,7 +1713,7 @@ void SurfaceSdlGraphicsManager::warpMouse(int x, int y) { } } -void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { #ifdef USE_RGB_COLOR if (!format) _cursorFormat = Graphics::PixelFormat::createFormatCLUT8(); @@ -1739,7 +1734,7 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, _mouseKeyColor = keycolor; - _cursorTargetScale = cursorTargetScale; + _cursorDontScale = dontScale; if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) { _mouseCurState.w = w; @@ -1847,51 +1842,34 @@ void SurfaceSdlGraphicsManager::blitCursor() { } int rW, rH; + int cursorScale; - if (_cursorTargetScale >= _videoMode.scaleFactor) { - // The cursor target scale is greater or equal to the scale at - // which the rest of the screen is drawn. We do not downscale - // the cursor image, we draw it at its original size. It will - // appear too large on screen. - - rW = w; - rH = h; - _mouseCurState.rHotX = _mouseCurState.hotX; - _mouseCurState.rHotY = _mouseCurState.hotY; - - // The virtual dimensions may be larger than the original. - - _mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor; - _mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor; - _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale / - _videoMode.scaleFactor; - _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale / - _videoMode.scaleFactor; + if (_cursorDontScale) { + // Don't scale the cursor at all if the user requests this behavior. + cursorScale = 1; } else { - // The cursor target scale is smaller than the scale at which - // the rest of the screen is drawn. We scale up the cursor - // image to make it appear correct. + // Scale the cursor with the game screen scale factor. + cursorScale = _videoMode.scaleFactor; + } - rW = w * _videoMode.scaleFactor / _cursorTargetScale; - rH = h * _videoMode.scaleFactor / _cursorTargetScale; - _mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor / - _cursorTargetScale; - _mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor / - _cursorTargetScale; + // Adapt the real hotspot according to the scale factor. + rW = w * cursorScale; + rH = h * cursorScale; + _mouseCurState.rHotX = _mouseCurState.hotX * cursorScale; + _mouseCurState.rHotY = _mouseCurState.hotY * cursorScale; - // The virtual dimensions will be the same as the original. + // The virtual dimensions will be the same as the original. - _mouseCurState.vW = w; - _mouseCurState.vH = h; - _mouseCurState.vHotX = _mouseCurState.hotX; - _mouseCurState.vHotY = _mouseCurState.hotY; - } + _mouseCurState.vW = w; + _mouseCurState.vH = h; + _mouseCurState.vHotX = _mouseCurState.hotX; + _mouseCurState.vHotY = _mouseCurState.hotY; #ifdef USE_SCALERS int rH1 = rH; // store original to pass to aspect-correction function later #endif - if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1) { + if (!_cursorDontScale && _videoMode.aspectRatioCorrection) { rH = real2Aspect(rH - 1) + 1; _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY); } @@ -1922,21 +1900,25 @@ void SurfaceSdlGraphicsManager::blitCursor() { ScalerProc *scalerProc; - // If possible, use the same scaler for the cursor as for the rest of - // the game. This only works well with the non-blurring scalers so we - // actually only use the 1x, 1.5x, 2x and AdvMame scalers. - - if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE)) - scalerProc = _scalerProc; - else - scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1]; + // Only apply scaling, when the user allows it. + if (!_cursorDontScale) { + // If possible, use the same scaler for the cursor as for the rest of + // the game. This only works well with the non-blurring scalers so we + // actually only use the 1x, 2x and AdvMame scalers. + if (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE) + scalerProc = _scalerProc; + else + scalerProc = scalersMagn[_videoMode.scaleFactor - 1]; + } else { + scalerProc = Normal1x; + } scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2, _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch, _mouseCurState.w, _mouseCurState.h); #ifdef USE_SCALERS - if (_videoMode.aspectRatioCorrection && _cursorTargetScale == 1) + if (!_cursorDontScale && _videoMode.aspectRatioCorrection) cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0); #endif diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h index f71096d43e..32fb219bcd 100644 --- a/backends/graphics/surfacesdl/surfacesdl-graphics.h +++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h @@ -131,7 +131,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); virtual void setCursorPalette(const byte *colors, uint start, uint num); #ifdef USE_OSD @@ -281,7 +281,7 @@ protected: #else byte _mouseKeyColor; #endif - int _cursorTargetScale; + bool _cursorDontScale; bool _cursorPaletteDisabled; SDL_Surface *_mouseOrigSurface; SDL_Surface *_mouseSurface; diff --git a/backends/graphics/wincesdl/wincesdl-graphics.cpp b/backends/graphics/wincesdl/wincesdl-graphics.cpp index 58b735ef8b..bb79813f3b 100644 --- a/backends/graphics/wincesdl/wincesdl-graphics.cpp +++ b/backends/graphics/wincesdl/wincesdl-graphics.cpp @@ -1128,7 +1128,7 @@ void WINCESdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x SDL_UnlockSurface(_screen); } -void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +void WINCESdlGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { undrawMouse(); if (w == 0 || h == 0) diff --git a/backends/graphics/wincesdl/wincesdl-graphics.h b/backends/graphics/wincesdl/wincesdl-graphics.h index 2e8c3313b3..7cff8a16d9 100644 --- a/backends/graphics/wincesdl/wincesdl-graphics.h +++ b/backends/graphics/wincesdl/wincesdl-graphics.h @@ -73,7 +73,7 @@ public: void internDrawMouse(); void undrawMouse(); bool showMouse(bool visible); - void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend + void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format); // overloaded by CE backend void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); void copyRectToScreen(const byte *src, int pitch, int x, int y, int w, int h); // overloaded by CE backend (FIXME) Graphics::Surface *lockScreen(); diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp index 525170d685..f133c65ed5 100644 --- a/backends/modular-backend.cpp +++ b/backends/modular-backend.cpp @@ -195,8 +195,8 @@ void ModularBackend::warpMouse(int x, int y) { _graphicsManager->warpMouse(x, y); } -void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { - _graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format); +void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { + _graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format); } void ModularBackend::setCursorPalette(const byte *colors, uint start, uint num) { diff --git a/backends/modular-backend.h b/backends/modular-backend.h index 072ee805b6..150c12c3c8 100644 --- a/backends/modular-backend.h +++ b/backends/modular-backend.h @@ -100,7 +100,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); virtual void setCursorPalette(const byte *colors, uint start, uint num); //@} diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h index 47a6515a2a..4dad1ee7ed 100644 --- a/backends/platform/android/android.h +++ b/backends/platform/android/android.h @@ -269,7 +269,7 @@ public: virtual void warpMouse(int x, int y); virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, - int cursorTargetScale, + bool dontScale, const Graphics::PixelFormat *format); virtual void setCursorPalette(const byte *colors, uint start, uint num); diff --git a/backends/platform/android/gfx.cpp b/backends/platform/android/gfx.cpp index 8bc914f567..304031b4ba 100644 --- a/backends/platform/android/gfx.cpp +++ b/backends/platform/android/gfx.cpp @@ -687,10 +687,10 @@ bool OSystem_Android::showMouse(bool visible) { void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, - uint32 keycolor, int cursorTargetScale, + uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { ENTER("%p, %u, %u, %d, %d, %u, %d, %p", buf, w, h, hotspotX, hotspotY, - keycolor, cursorTargetScale, format); + keycolor, dontScale, format); GLTHREADCHECK; @@ -766,7 +766,8 @@ void OSystem_Android::setMouseCursor(const byte *buf, uint w, uint h, } _mouse_hotspot = Common::Point(hotspotX, hotspotY); - _mouse_targetscale = cursorTargetScale; + // TODO: Adapt to the new "do not scale" cursor logic. + _mouse_targetscale = 1; } void OSystem_Android::setCursorPaletteInternal(const byte *colors, diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h index 8ca48bf19e..ffe003ea1d 100644 --- a/backends/platform/dc/dc.h +++ b/backends/platform/dc/dc.h @@ -142,7 +142,7 @@ public: void warpMouse(int x, int y); // Set the bitmap that's used when drawing the cursor. - void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); + void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format); // Replace the specified range of cursor the palette with new colors. void setCursorPalette(const byte *colors, uint start, uint num); diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp index e886b55869..e4e9a94ec8 100644 --- a/backends/platform/dc/display.cpp +++ b/backends/platform/dc/display.cpp @@ -293,7 +293,7 @@ void OSystem_Dreamcast::warpMouse(int x, int y) void OSystem_Dreamcast::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, - uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) + uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { _ms_cur_w = w; _ms_cur_h = h; diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp index 73340ed18a..a6b85f207f 100644 --- a/backends/platform/ds/arm9/source/osystem_ds.cpp +++ b/backends/platform/ds/arm9/source/osystem_ds.cpp @@ -580,7 +580,7 @@ bool OSystem_DS::showMouse(bool visible) { void OSystem_DS::warpMouse(int x, int y) { } -void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, int targetCursorScale, const Graphics::PixelFormat *format) { +void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { if ((w > 0) && (w < 64) && (h > 0) && (h < 64)) { memcpy(_cursorImage, buf, w * h); _cursorW = w; @@ -588,7 +588,9 @@ void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, i _cursorHotX = hotspotX; _cursorHotY = hotspotY; _cursorKey = keycolor; - _cursorScale = targetCursorScale; + // TODO: The old target scales was saved, but never used. Should the + // new "do not scale" logic be implemented? + //_cursorScale = targetCursorScale; refreshCursor(); } } diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h index 6aa3731916..11b0988666 100644 --- a/backends/platform/ds/arm9/source/osystem_ds.h +++ b/backends/platform/ds/arm9/source/osystem_ds.h @@ -114,7 +114,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, int targetCursorScale, const Graphics::PixelFormat *format); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format); virtual bool pollEvent(Common::Event &event); virtual uint32 getMillis(); diff --git a/backends/platform/iphone/osys_main.h b/backends/platform/iphone/osys_main.h index b443e22f56..e06c7973ab 100644 --- a/backends/platform/iphone/osys_main.h +++ b/backends/platform/iphone/osys_main.h @@ -161,7 +161,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL); virtual void setCursorPalette(const byte *colors, uint start, uint num); virtual bool pollEvent(Common::Event &event); diff --git a/backends/platform/iphone/osys_video.mm b/backends/platform/iphone/osys_video.mm index c6b6e6d757..ddfa8f5030 100644 --- a/backends/platform/iphone/osys_video.mm +++ b/backends/platform/iphone/osys_video.mm @@ -398,8 +398,8 @@ void OSystem_IPHONE::dirtyFullOverlayScreen() { } } -void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { - //printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, (const void *)format); +void OSystem_IPHONE::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { + //printf("setMouseCursor(%p, %u, %u, %i, %i, %u, %d, %p)\n", (const void *)buf, w, h, hotspotX, hotspotY, keycolor, dontScale, (const void *)format); const Graphics::PixelFormat pixelFormat = format ? *format : Graphics::PixelFormat::createFormatCLUT8(); #if 0 diff --git a/backends/platform/n64/osys_n64.h b/backends/platform/n64/osys_n64.h index 4788beb1ca..b8519eeea6 100644 --- a/backends/platform/n64/osys_n64.h +++ b/backends/platform/n64/osys_n64.h @@ -182,7 +182,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format); virtual void setCursorPalette(const byte *colors, uint start, uint num); virtual bool pollEvent(Common::Event &event); diff --git a/backends/platform/n64/osys_n64_base.cpp b/backends/platform/n64/osys_n64_base.cpp index c3adb9691c..f36f7399e1 100644 --- a/backends/platform/n64/osys_n64_base.cpp +++ b/backends/platform/n64/osys_n64_base.cpp @@ -773,7 +773,7 @@ void OSystem_N64::warpMouse(int x, int y) { _dirtyOffscreen = true; } -void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +void OSystem_N64::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { if (!w || !h) return; _mouseHotspotX = hotspotX; diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index d4e993da63..668ac93a07 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -618,7 +618,7 @@ void OSystem_PS2::warpMouse(int x, int y) { _screen->setMouseXy(x, y); } -void OSystem_PS2::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +void OSystem_PS2::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { _screen->setMouseOverlay(buf, w, h, hotspot_x, hotspot_y, keycolor); } diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h index 3a0e247737..7bbe061e42 100644 --- a/backends/platform/ps2/systemps2.h +++ b/backends/platform/ps2/systemps2.h @@ -80,7 +80,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = 0); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = 0); virtual uint32 getMillis(); virtual void delayMillis(uint msecs); diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp index 5fa5110684..958a3a22c6 100644 --- a/backends/platform/psp/osys_psp.cpp +++ b/backends/platform/psp/osys_psp.cpp @@ -303,7 +303,7 @@ void OSystem_PSP::warpMouse(int x, int y) { _cursor.setXY(x, y); } -void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { +void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { DEBUG_ENTER_FUNC(); _displayManager.waitUntilRenderFinished(); _pendingUpdate = false; @@ -314,7 +314,9 @@ void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, } _cursor.setKeyColor(keycolor); - _cursor.setCursorTargetScale(cursorTargetScale); + // TODO: The old target scale was saved but never used. Should the new + // "do not scale" logic be implemented? + //_cursor.setCursorTargetScale(cursorTargetScale); _cursor.setSizeAndScummvmPixelFormat(w, h, format); _cursor.setHotspot(hotspotX, hotspotY); _cursor.clearKeyColor(); diff --git a/backends/platform/psp/osys_psp.h b/backends/platform/psp/osys_psp.h index e6b445e232..c72053f52c 100644 --- a/backends/platform/psp/osys_psp.h +++ b/backends/platform/psp/osys_psp.h @@ -118,7 +118,7 @@ public: // Mouse related bool showMouse(bool visible); void warpMouse(int x, int y); - void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); + void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format); // Events and input bool pollEvent(Common::Event &event); diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h index 64197f913a..b6784d59e4 100644 --- a/backends/platform/wii/osystem.h +++ b/backends/platform/wii/osystem.h @@ -189,7 +189,7 @@ public: virtual void warpMouse(int x, int y); virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, - int cursorTargetScale, + bool dontScale, const Graphics::PixelFormat *format); virtual bool pollEvent(Common::Event &event); diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp index 83607984cc..a00cea8252 100644 --- a/backends/platform/wii/osystem_gfx.cpp +++ b/backends/platform/wii/osystem_gfx.cpp @@ -644,7 +644,7 @@ void OSystem_Wii::warpMouse(int x, int y) { void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, - int cursorTargetScale, + bool dontScale, const Graphics::PixelFormat *format) { gfx_tex_format_t tex_format = GFX_TF_PALETTE_RGB5A3; uint tw, th; @@ -742,7 +742,8 @@ void OSystem_Wii::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, _mouseHotspotX = hotspotX; _mouseHotspotY = hotspotY; - _cursorScale = cursorTargetScale; + // TODO: Adapt to new dontScale logic! + _cursorScale = 1; if ((_texMouse.palette) && (oldKeycolor != _mouseKeyColor)) _cursorPaletteDirty = true; diff --git a/common/system.h b/common/system.h index dc74533861..976a3d2c4a 100644 --- a/common/system.h +++ b/common/system.h @@ -883,10 +883,11 @@ public: * @param keycolor transparency color value. This should not exceed the maximum color value of the specified format. * In case it does the behavior is undefined. The backend might just error out or simply ignore the * value. (The SDL backend will just assert to prevent abuse of this). - * @param cursorTargetScale scale factor which cursor is designed for + * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor + * would be too small to notice otherwise, these are allowed to scale the cursor anyway. * @param format pointer to the pixel format which cursor graphic uses (0 means CLUT8) */ - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0; + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL) = 0; /** * Replace the specified range of cursor the palette with new colors. diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index fb15fdbc19..878c1dc265 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -123,7 +123,7 @@ void Draw_v1::animateCursor(int16 cursor) { (cursorIndex + 1) * _cursorWidth - 1, _cursorHeight - 1, 0, 0); CursorMan.replaceCursor(_scummvmCursor->getData(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat()); + _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, false, &_vm->getPixelFormat()); if (_frontSurface != _backSurface) { _showCursor = 3; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index ab9a90de8f..d9b7a12639 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -161,7 +161,7 @@ void Draw_v2::animateCursor(int16 cursor) { keyColor = _cursorKeyColors[cursorIndex]; CursorMan.replaceCursor(_scummvmCursor->getData(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat()); + _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, false, &_vm->getPixelFormat()); if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) { CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3), diff --git a/engines/groovie/cursor.cpp b/engines/groovie/cursor.cpp index abefac54bd..6422570220 100644 --- a/engines/groovie/cursor.cpp +++ b/engines/groovie/cursor.cpp @@ -387,7 +387,7 @@ void Cursor_v2::enable() { void Cursor_v2::showFrame(uint16 frame) { int offset = _width * _height * frame * 2; - CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, 1, &_format); + CursorMan.replaceCursor((const byte *)(_img + offset), _width, _height, _width >> 1, _height >> 1, 0, false, &_format); } diff --git a/engines/lastexpress/data/cursor.cpp b/engines/lastexpress/data/cursor.cpp index 86a66b49d9..a3e7b773a7 100644 --- a/engines/lastexpress/data/cursor.cpp +++ b/engines/lastexpress/data/cursor.cpp @@ -93,7 +93,7 @@ void Cursor::setStyle(CursorStyle style) { Graphics::PixelFormat pf = g_system->getScreenFormat(); CursorMan.replaceCursor((const byte *)getCursorImage(style), 32, 32, _cursors[style].hotspotX, _cursors[style].hotspotY, - 0, 1, &pf); + 0, false, &pf); } const uint16 *Cursor::getCursorImage(CursorStyle style) const { diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp index 3cf5ac740e..47a7d0225b 100644 --- a/engines/mohawk/cursors.cpp +++ b/engines/mohawk/cursors.cpp @@ -125,7 +125,7 @@ void MystCursorManager::setCursor(uint16 id) { CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256); } else { Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); - CursorMan.replaceCursor((byte *)surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), 1, &pixelFormat); + CursorMan.replaceCursor((byte *)surface->pixels, surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat); } _vm->_needsUpdate = true; diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp index 42f11498d9..88681898f5 100644 --- a/engines/scumm/cursor.cpp +++ b/engines/scumm/cursor.cpp @@ -121,13 +121,13 @@ void ScummEngine::updateCursor() { CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height, _cursor.hotspotX, _cursor.hotspotY, (_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor), - (_game.heversion == 70 ? 2 : 1), + (_game.heversion == 70 ? true : false), &format); #else CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height, _cursor.hotspotX, _cursor.hotspotY, (_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor), - (_game.heversion == 70 ? 2 : 1)); + (_game.heversion == 70 ? true : false)); #endif } diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index 425714ea34..825b5c2e19 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -55,14 +55,14 @@ bool CursorManager::showMouse(bool visible) { return g_system->showMouse(visible); } -void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) { - Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format); +void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { + Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format); cur->_visible = isVisible(); _cursorStack.push(cur); if (buf) { - g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format); + g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format); } } @@ -75,7 +75,7 @@ void CursorManager::popCursor() { if (!_cursorStack.empty()) { cur = _cursorStack.top(); - g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale, &cur->_format); + g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_format); } g_system->showMouse(isVisible()); @@ -98,10 +98,10 @@ void CursorManager::popAllCursors() { g_system->showMouse(isVisible()); } -void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) { +void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { if (_cursorStack.empty()) { - pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale, format); + pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format); return; } @@ -131,7 +131,7 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, cur->_hotspotX = hotspotX; cur->_hotspotY = hotspotY; cur->_keycolor = keycolor; - cur->_targetScale = targetScale; + cur->_dontScale = dontScale; #ifdef USE_RGB_COLOR if (format) cur->_format = *format; @@ -139,7 +139,7 @@ void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, cur->_format = Graphics::PixelFormat::createFormatCLUT8(); #endif - g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale, format); + g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format); } bool CursorManager::supportsCursorPalettes() { @@ -225,7 +225,7 @@ void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint nu } } -CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale, const Graphics::PixelFormat *format) { +CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) { #ifdef USE_RGB_COLOR if (!format) _format = Graphics::PixelFormat::createFormatCLUT8(); @@ -245,7 +245,7 @@ CursorManager::Cursor::Cursor(const byte *data, uint w, uint h, int hotspotX, in _height = h; _hotspotX = hotspotX; _hotspotY = hotspotY; - _targetScale = targetScale; + _dontScale = dontScale; } CursorManager::Cursor::~Cursor() { diff --git a/graphics/cursorman.h b/graphics/cursorman.h index 543a5d0a5c..852109d7e6 100644 --- a/graphics/cursorman.h +++ b/graphics/cursorman.h @@ -63,14 +63,15 @@ public: * @param hotspotY the hotspot Y coordinate * @param keycolor the color value for the transparent color. This may not exceed * the maximum color value as defined by format. - * @param targetScale the scale for which the cursor is designed + * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor + * would be too small to notice otherwise, these are allowed to scale the cursor anyway. * @param format a pointer to the pixel format which the cursor graphic uses, * CLUT8 will be used if this is NULL or not specified. * @note It is ok for the buffer to be a NULL pointer. It is sometimes * useful to push a "dummy" cursor and modify it later. The * cursor will be added to the stack, but not to the backend. */ - void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL); + void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); /** * Pop a cursor from the stack, and restore the previous one to the @@ -90,11 +91,12 @@ public: * @param hotspotY the hotspot Y coordinate * @param keycolor the color value for the transparent color. This may not exceed * the maximum color value as defined by format. - * @param targetScale the scale for which the cursor is designed + * @param dontScale Whether the cursor should never be scaled. An exception are high ppi displays, where the cursor + * would be too small to notice otherwise, these are allowed to scale the cursor anyway. * @param format a pointer to the pixel format which the cursor graphic uses, * CLUT8 will be used if this is NULL or not specified. */ - void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL); + void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); /** * Pop all of the cursors and cursor palettes from their respective stacks. @@ -175,11 +177,11 @@ private: int _hotspotY; uint32 _keycolor; Graphics::PixelFormat _format; - int _targetScale; + bool _dontScale; uint _size; - Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int targetScale = 1, const Graphics::PixelFormat *format = NULL); + Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale = false, const Graphics::PixelFormat *format = NULL); ~Cursor(); }; diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index be0a5db601..1bf7ad3c85 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -454,7 +454,7 @@ void ThemeEngine::refresh() { if (_useCursor) { CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize); - CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale); + CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true); } } } @@ -465,7 +465,7 @@ void ThemeEngine::enable() { if (_useCursor) { CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize); - CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale); + CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, true); CursorMan.showMouse(true); } @@ -1287,7 +1287,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) { _vectorRenderer->setSurface(&_screen); } -bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale) { +bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY) { if (!_system->hasFeature(OSystem::kFeatureCursorPalette)) return true; @@ -1305,7 +1305,6 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int // Set up the cursor parameters _cursorHotspotX = hotspotX; _cursorHotspotY = hotspotY; - _cursorTargetScale = scale; _cursorWidth = cursor->w; _cursorHeight = cursor->h; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index acded085f5..67221d98ce 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -35,7 +35,7 @@ #include "graphics/pixelformat.h" -#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.12" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.13" class OSystem; @@ -495,9 +495,8 @@ public: * @param filename File name of the bitmap to load. * @param hotspotX X Coordinate of the bitmap which does the cursor click. * @param hotspotY Y Coordinate of the bitmap which does the cursor click. - * @param scale Scale at which the bitmap is supposed to be used. */ - bool createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale); + bool createCursor(const Common::String &filename, int hotspotX, int hotspotY); /** * Wrapper for restoring data from the Back Buffer to the screen. @@ -669,7 +668,6 @@ protected: bool _useCursor; int _cursorHotspotX, _cursorHotspotY; - int _cursorTargetScale; enum { MAX_CURS_COLORS = 255 }; diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 9ccdedd564..9a85399ed1 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -218,15 +218,12 @@ bool ThemeParser::parserCallback_cursor(ParserNode *node) { return true; } - int spotx, spoty, scale; + int spotx, spoty; if (!parseIntegerKey(node->values["hotspot"], 2, &spotx, &spoty)) return parserError("Error parsing cursor Hot Spot coordinates."); - if (!parseIntegerKey(node->values["scale"], 1, &scale)) - return parserError("Error parsing cursor scale."); - - if (!_theme->createCursor(node->values["file"], spotx, spoty, scale)) + if (!_theme->createCursor(node->values["file"], spotx, spoty)) return parserError("Error creating Bitmap Cursor."); return true; diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 4b7e88cbf3..82f774b803 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -85,7 +85,6 @@ protected: XML_KEY(cursor) XML_PROP(file, true) XML_PROP(hotspot, true) - XML_PROP(scale, true) XML_PROP(resolution, false) KEY_END() diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 5ee9b9202a..86d0061e1b 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -610,50 +610,48 @@ "/> " " " " " -" " +" " " " -" " -" " -" " -" " +" " +" " +" " +" " " " " " " " -" " -" " -" " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " -" " -" " -" " " " " " " " " " " " " " " " " " " " " " " " -" " +" " " " -" " +" " " " @@ -701,39 +699,38 @@ " " " " " " -" " +" " " " " " " " " " " " -" " -" " +" " " " " " " " " " " " " " " " -" " -" " +" " +" " " " @@ -741,7 +738,7 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -755,10 +752,10 @@ " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -779,7 +776,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -797,7 +794,7 @@ " " " " " " -" " +" " " " @@ -805,7 +802,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -813,7 +810,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -821,7 +818,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -835,7 +832,7 @@ "type='Radiobutton' " "/> " " " -" " +" " " " @@ -849,9 +846,8 @@ " " " " " " -" " -" " -" " +" " +" " " " @@ -862,7 +858,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -873,7 +869,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -884,8 +880,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -894,7 +890,7 @@ " " " " " " -" " +" " " " @@ -902,7 +898,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -917,7 +913,7 @@ " " -" " +" " " " @@ -933,7 +929,7 @@ " " " " " " -" " +" " " " @@ -951,7 +947,7 @@ " " " " " " -" " +" " " " @@ -963,7 +959,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -975,7 +971,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -999,7 +995,7 @@ " " " " " " -" " +" " " " @@ -1007,25 +1003,31 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " " " " " -" " +" " " " " " " " -" " +" " " " " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -1083,7 +1085,7 @@ " " " " " " -" " +" " " " @@ -1091,7 +1093,7 @@ " " " " " " -" " +" " " " @@ -1099,7 +1101,7 @@ " " " " " " -" " +" " " " @@ -1107,7 +1109,7 @@ " " " " " " -" " +" " " " @@ -1115,34 +1117,43 @@ " " " " " " -" " -" " +" " +" " " " " " " " -" " +" " " " " " " " -" " +" " +" " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " @@ -1164,7 +1175,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1176,7 +1187,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1187,7 +1198,7 @@ " " " " " " -" " +" " " " @@ -1212,57 +1223,55 @@ " " " " " " -" " +" " " " " " -" " -" " +" " " " " " -" " +" " " " " " " " +" " +" " -" " " " " " " " " " " " " " -" " -" " -" " +" " " " @@ -1273,7 +1282,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -1284,7 +1293,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -1295,33 +1304,34 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " " " -" " -" " -" " +" " " " +" " " " " " " " " " -" " +" " +" " +" " " " @@ -1332,8 +1342,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -1348,23 +1358,15 @@ " " " " " " -" " -" " -" " +" " +" " " " -" " -" " -" " +" " " " " " -" " +" " " " @@ -1374,16 +1376,16 @@ " " " " " " -" " -" " +" " +" " " " " " -" " +" " " " @@ -1400,7 +1402,7 @@ " " " " " " " " " " " " -" " +" " " " " " " " -" " +" " " " @@ -1442,20 +1444,20 @@ " " " " " " -" " +" " " " " " " " " " " " " " " " " " -" " +" " " " -" " +" " " " " " " " -" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " -" " " " " " " " " " " " " " -" " +" " " " -" " -" " -" " -" " +" " +" " +" " +" " " " " " " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " +" " +" " +" " " " " " " " " " " " " " " " " " " " " " " " -" " +" " " " -" " +" " " " @@ -1644,38 +1646,39 @@ " " " " " " -" " +" " " " " " " " " " " " -" " +" " +" " " " " " " " " " " " " " " " -" " -" " +" " +" " " " @@ -1683,7 +1686,7 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1697,10 +1700,10 @@ " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -1721,7 +1724,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1739,7 +1742,7 @@ " " " " " " -" " +" " " " @@ -1747,7 +1750,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1755,7 +1758,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1763,7 +1766,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1777,7 +1780,7 @@ "type='Radiobutton' " "/> " " " -" " +" " " " @@ -1791,8 +1794,9 @@ " " " " " " -" " -" " +" " +" " +" " " " @@ -1803,7 +1807,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -1814,7 +1818,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -1825,8 +1829,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -1835,7 +1839,7 @@ " " " " " " -" " +" " " " @@ -1843,7 +1847,7 @@ "type='PopUp' " "/> " " " -" " +" " " " @@ -1858,7 +1862,7 @@ " " -" " +" " " " @@ -1874,7 +1878,7 @@ " " " " " " -" " +" " " " @@ -1892,7 +1896,7 @@ " " " " " " -" " +" " " " @@ -1904,7 +1908,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1916,7 +1920,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -1940,7 +1944,7 @@ " " " " " " -" " +" " " " @@ -1948,31 +1952,25 @@ "height='Globals.Line.Height' " "/> " " " -" " +" " " " " " " " -" " +" " " " " " " " -" " +" " " " " " " " " " -" " +" " " " " " -" " +" " " " " " " " " " -" " +" " " " @@ -2030,7 +2028,7 @@ " " " " " " -" " +" " " " @@ -2038,7 +2036,7 @@ " " " " " " -" " +" " " " @@ -2046,7 +2044,7 @@ " " " " " " -" " +" " " " @@ -2054,7 +2052,7 @@ " " " " " " -" " +" " " " @@ -2062,43 +2060,34 @@ " " " " " " -" " -" " +" " +" " " " " " " " -" " +" " " " " " " " -" " -" " +" " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " @@ -2120,7 +2109,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -2132,7 +2121,7 @@ "width='Globals.Line.Height' " "/> " " " -" " +" " " " @@ -2143,7 +2132,7 @@ " " " " " " -" " +" " " " @@ -2168,55 +2157,57 @@ " " " " " " -" " +" " " " " " -" " +" " +" " " " " " -" " +" " " " " " " " -" " -" " +" " " " " " " " " " " " " " -" " +" " +" " +" " " " @@ -2227,7 +2218,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -2238,7 +2229,7 @@ "type='SmallLabel' " "/> " " " -" " +" " " " @@ -2249,34 +2240,33 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " " " -" " +" " +" " +" " " " -" " " " " " " " " " -" " -" " -" " +" " " " @@ -2287,8 +2277,8 @@ "type='SmallLabel' " "/> " " " -" " -" " +" " +" " " " @@ -2303,15 +2293,23 @@ " " " " " " -" " -" " +" " +" " +" " " " -" " +" " +" " +" " " " " " -" " +" " " " @@ -2321,16 +2319,16 @@ " " " " " " -" " -" " +" " +" " " " " " -" " +" " " " @@ -2347,7 +2345,7 @@ " " " " " " " " " " " " -" " +" " " " " " " " -" " +" " " " @@ -2389,20 +2387,20 @@ " " " " " " -" " +" " " " " " " " " " " " " " " " " " -" " +" " " " -" " +" " " " " " " " +" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " -" " +" " " " " " " " " " -" " -" " +" " +" " " " +" " " " " " " " " " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip index ec1728b778..d126ed0774 100644 Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC index 7cbed97e40..d4bed29cf8 100644 --- a/gui/themes/scummclassic/THEMERC +++ b/gui/themes/scummclassic/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.12:ScummVM Classic Theme:No Author] +[SCUMMVM_STX0.8.13:ScummVM Classic Theme:No Author] diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip index deae315e30..db116325e2 100644 Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC index 326993e98d..60744d386f 100644 --- a/gui/themes/scummmodern/THEMERC +++ b/gui/themes/scummmodern/THEMERC @@ -1 +1 @@ -[SCUMMVM_STX0.8.12:ScummVM Modern Theme:No Author] +[SCUMMVM_STX0.8.13:ScummVM Modern Theme:No Author] diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index 970d78a5ae..037c327235 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -187,8 +187,8 @@ - - + + -- cgit v1.2.3 From 627e870629cdab1009d3279453d082a3c44acd03 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 03:29:35 +0200 Subject: GOB: Limit Penetration movement to walkable tiles --- engines/gob/minigames/geisha/penetration.cpp | 36 ++++++++++++++++++++++++---- engines/gob/minigames/geisha/penetration.h | 2 ++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 377835c45f..c8fbe31249 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -423,6 +423,15 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB return _vm->_util->checkKey(); } +bool Penetration::isWalkable(byte tile) const { + // Only walls are nonwalkable + + if (tile == 50) + return false; + + return true; +} + void Penetration::handleSub(int16 key) { if (key == kKeyLeft) moveSub(-5, 0, kAnimationDriveW); @@ -435,11 +444,30 @@ void Penetration::handleSub(int16 key) { } void Penetration::moveSub(int x, int y, uint16 animation) { - _mapX = CLIP(_mapX + x, 0, kMapWidth * kMapTileWidth); - _mapY = CLIP(_mapY + y, 0, kMapHeight * kMapTileHeight); + // Limit the movement to walkable tiles + + int16 minX = 0; + if ((_subTileX > 0) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX - 1)])) + minX = _subTileX * kMapTileWidth; + + int16 maxX = kMapWidth * kMapTileWidth; + if ((_subTileX < (kMapWidth - 1)) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX + 1)])) + maxX = _subTileX * kMapTileWidth; + + int16 minY = 0; + if ((_subTileY > 0) && !isWalkable(_mapTiles[(_subTileY - 1) * kMapWidth + _subTileX])) + minY = _subTileY * kMapTileHeight; + + int16 maxY = kMapHeight * kMapTileHeight; + if ((_subTileY < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_subTileY + 1) * kMapWidth + _subTileX])) + maxY = _subTileY * kMapTileHeight; + + _mapX = CLIP(_mapX + x, minX, maxX); + _mapY = CLIP(_mapY + y, minY, maxY); - _subTileX = _mapX / kMapTileWidth; - _subTileY = _mapY / kMapTileHeight; + // The tile the sub is on is where its mid-point is + _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth; + _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight; _mapUpdate = true; diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 28a288928b..9109cb5c68 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -96,6 +96,8 @@ private: void handleSub(int16 key); void moveSub(int x, int y, uint16 animation); + + bool isWalkable(byte tile) const; }; } // End of namespace Geisha -- cgit v1.2.3 From 5a245bd4f2cbac8aee4efe7220533f41d6418312 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 03:40:04 +0200 Subject: GOB: Consume shields in Penetration --- engines/gob/minigames/geisha/penetration.cpp | 27 +++++++++++++++++++++++++++ engines/gob/minigames/geisha/penetration.h | 12 ++++++++++++ 2 files changed, 39 insertions(+) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index c8fbe31249..e4e7798216 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -193,6 +193,10 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = }; +Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), _subTileX(0), _subTileY(0) { @@ -303,6 +307,8 @@ void Penetration::createMap() { // Copy the correct map memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); + _shields.clear(); + _map->fill(kColorBlack); // Draw the map tiles @@ -378,6 +384,8 @@ void Penetration::createMap() { _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield + + _shields.push_back(Position(x, y)); break; case 57: // Start position @@ -473,6 +481,25 @@ void Penetration::moveSub(int x, int y, uint16 animation) { if (_sub->getAnimation() != animation) _sub->setAnimation(animation); + + checkShields(); +} + +void Penetration::checkShields() { + for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { + if ((pos->x == _subTileX) && (pos->y == _subTileY)) { + // Charge shields + _shieldMeter->setMaxValue(); + + // Erase the shield from the map + const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth; + const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight; + _sprites->draw(*_map, 30, mapX, mapY); + + _shields.erase(pos); + break; + } + } } void Penetration::updateAnims() { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 9109cb5c68..4d3455b638 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -54,6 +54,13 @@ private: static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; + struct Position { + uint16 x; + uint16 y; + + Position(uint16 pX, uint16 pY); + }; + GobEngine *_vm; bool _hasAccessPass; @@ -83,6 +90,9 @@ private: uint8 _subTileX; uint8 _subTileY; + Common::List _shields; + + void init(); void deinit(); @@ -98,6 +108,8 @@ private: void moveSub(int x, int y, uint16 animation); bool isWalkable(byte tile) const; + + void checkShields(); }; } // End of namespace Geisha -- cgit v1.2.3 From d124b87649c14e1851228821fcb6d3a523f1e0ae Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 17:15:18 +0200 Subject: GOB: Remove unnecessary include A remnant of when we were still doing dithering color LUT creation at startup --- engines/gob/video.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index c865b2b40e..3b1c6423bb 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -25,7 +25,6 @@ #include "engines/util.h" #include "graphics/cursorman.h" -#include "graphics/fontman.h" #include "graphics/palette.h" #include "graphics/surface.h" -- cgit v1.2.3 From db99d23717ce4f39f9d9f55ce1abf0d8b73cc630 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 18:58:03 +0200 Subject: GOB: Fix invalid reads in Geisha's minigames --- engines/gob/aniobject.cpp | 26 +++++++++++++++++--------- engines/gob/aniobject.h | 8 ++++---- engines/gob/minigames/geisha/diving.cpp | 8 ++++---- engines/gob/minigames/geisha/penetration.cpp | 12 +++++++----- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index 154f8e04ed..54534cd60b 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -167,19 +167,21 @@ bool ANIObject::isIn(const ANIObject &obj) const { obj.isIn(frameX + frameWidth - 1, frameY + frameHeight - 1); } -void ANIObject::draw(Surface &dest, int16 &left, int16 &top, +bool ANIObject::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_visible) - return; + return false; if (_cmp) - drawCMP(dest, left, top, right, bottom); + return drawCMP(dest, left, top, right, bottom); else if (_ani) - drawANI(dest, left, top, right, bottom); + return drawANI(dest, left, top, right, bottom); + + return false; } -void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, +bool ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_background) { @@ -209,9 +211,11 @@ void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, top = _backgroundTop; right = _backgroundRight; bottom = _backgroundBottom; + + return true; } -void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, +bool ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_background) { @@ -224,7 +228,7 @@ void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation); if (_frame >= animation.frameCount) - return; + return false; const ANIFile::FrameArea &area = animation.frameAreas[_frame]; @@ -244,13 +248,15 @@ void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, top = _backgroundTop; right = _backgroundRight; bottom = _backgroundBottom; + + return true; } -void ANIObject::clear(Surface &dest, int16 &left, int16 &top, +bool ANIObject::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_drawn) - return; + return false; const int16 bgRight = _backgroundRight - _backgroundLeft; const int16 bgBottom = _backgroundBottom - _backgroundTop; @@ -263,6 +269,8 @@ void ANIObject::clear(Surface &dest, int16 &left, int16 &top, top = _backgroundTop; right = _backgroundRight; bottom = _backgroundBottom; + + return true; } void ANIObject::advance() { diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index c101d747b7..bd4cf791a8 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -93,9 +93,9 @@ public: bool lastFrame() const; /** Draw the current frame onto the surface and return the affected rectangle. */ - void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); /** Draw the current frame from the surface and return the affected rectangle. */ - void clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom); + bool clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom); /** Advance the animation to the next frame. */ virtual void advance(); @@ -123,8 +123,8 @@ private: int16 _backgroundRight; ///< The right position of the saved background. int16 _backgroundBottom; ///< The bottom position of the saved background. - void drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); - void drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); }; } // End of namespace Gob diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp index 6f4c6e168a..56c7b5213c 100644 --- a/engines/gob/minigames/geisha/diving.cpp +++ b/engines/gob/minigames/geisha/diving.cpp @@ -706,16 +706,16 @@ void Diving::updateAnims() { for (Common::List::iterator a = _anims.reverse_begin(); a != _anims.end(); --a) { - (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); a != _anims.end(); ++a) { - (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); (*a)->advance(); } diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index e4e7798216..35802e6733 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -298,6 +298,8 @@ void Penetration::deinit() { _objects = 0; _sprites = 0; + + _sub = 0; } void Penetration::createMap() { @@ -503,14 +505,14 @@ void Penetration::checkShields() { } void Penetration::updateAnims() { - int16 left, top, right, bottom; + int16 left = 0, top = 0, right = 0, bottom = 0; // Clear the previous animation frames for (Common::List::iterator a = _anims.reverse_begin(); a != _anims.end(); --a) { - (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } if (_mapUpdate) { @@ -526,8 +528,8 @@ void Penetration::updateAnims() { for (Common::List::iterator a = _anims.begin(); a != _anims.end(); ++a) { - (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); (*a)->advance(); } -- cgit v1.2.3 From 7d29e4017d37f7aee4035b3d7288c8c5478633be Mon Sep 17 00:00:00 2001 From: D G Turner Date: Tue, 5 Jun 2012 01:00:01 +0100 Subject: DREAMWEB: Modify Sound code to better match original behaviour. This fixes bug #3531635 - "DREAMWEB: doors don't play "open" sound when opening". In addition, the resultant code is simpler and should better match the original behaviour and a basic playtest has not shown any regressions. --- engines/dreamweb/sound.cpp | 42 +++++++++++------------------------------- engines/dreamweb/sound.h | 3 +-- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/engines/dreamweb/sound.cpp b/engines/dreamweb/sound.cpp index 76c734e932..570f76f2f9 100644 --- a/engines/dreamweb/sound.cpp +++ b/engines/dreamweb/sound.cpp @@ -35,14 +35,12 @@ DreamWebSound::DreamWebSound(DreamWebEngine *vm) : _vm(vm) { _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - _channel0 = 0; - _channel1 = 0; - _currentSample = 0xff; - _channel0Playing = 0; + _channel0Playing = 255; _channel0Repeat = 0; _channel0NewSound = false; _channel1Playing = 255; + _channel1NewSound = false; _volume = 0; _volumeTo = 0; @@ -82,13 +80,9 @@ void DreamWebSound::volumeAdjust() { void DreamWebSound::playChannel0(uint8 index, uint8 repeat) { debug(1, "playChannel0(index:%d, repeat:%d)", index, repeat); - if (index == _channel0Playing) { - warning("playChannel0(index: %d) already playing! Forcing restart...", index); - _channel0NewSound = true; - } - _channel0Playing = index; _channel0Repeat = repeat; + _channel0NewSound = true; } void DreamWebSound::playChannel1(uint8 index) { @@ -97,6 +91,7 @@ void DreamWebSound::playChannel1(uint8 index) { return; _channel1Playing = index; + _channel1NewSound = true; } void DreamWebSound::cancelCh0() { @@ -186,10 +181,6 @@ void DreamWebSound::stopSound(uint8 channel) { debug(1, "stopSound(%u)", channel); assert(channel == 0 || channel == 1); _vm->_mixer->stopHandle(_channelHandle[channel]); - if (channel == 0) - _channel0 = 0; - else - _channel1 = 0; } bool DreamWebSound::loadSpeech(const Common::String &filename) { @@ -229,35 +220,24 @@ void DreamWebSound::soundHandler() { volume = (8 - volume) * Audio::Mixer::kMaxChannelVolume / 8; _vm->_mixer->setChannelVolume(_channelHandle[0], volume); - uint8 ch0 = _channel0Playing; - if (ch0 == 255) - ch0 = 0; - uint8 ch1 = _channel1Playing; - if (ch1 == 255) - ch1 = 0; - uint8 ch0loop = _channel0Repeat; - - if (_channel0 != ch0 || _channel0NewSound) { - _channel0 = ch0; + if (_channel0NewSound) { _channel0NewSound = false; - if (ch0) { - playSound(0, ch0, ch0loop); + if (_channel0Playing != 255) { + playSound(0, _channel0Playing, _channel0Repeat); } } - if (_channel1 != ch1) { - _channel1 = ch1; - if (ch1) { - playSound(1, ch1, 1); + if (_channel1NewSound) { + _channel1NewSound = false; + if (_channel1Playing != 255) { + playSound(1, _channel1Playing, 1); } } if (!_vm->_mixer->isSoundHandleActive(_channelHandle[0])) { _channel0Playing = 255; - _channel0 = 0; } if (!_vm->_mixer->isSoundHandleActive(_channelHandle[1])) { _channel1Playing = 255; - _channel1 = 0; } } diff --git a/engines/dreamweb/sound.h b/engines/dreamweb/sound.h index a38dbf3c1a..1ab06dc694 100644 --- a/engines/dreamweb/sound.h +++ b/engines/dreamweb/sound.h @@ -68,13 +68,12 @@ private: Audio::SoundHandle _channelHandle[2]; - uint8 _channel0, _channel1; - uint8 _currentSample; uint8 _channel0Playing; uint8 _channel0Repeat; bool _channel0NewSound; uint8 _channel1Playing; + bool _channel1NewSound; uint8 _volume; uint8 _volumeTo; -- cgit v1.2.3 From 25938316a881679a923bce1986f3a978432b0e76 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 5 Jun 2012 16:18:05 +0200 Subject: GOB: Animate mouths in Geisha's Penetration --- engines/gob/aniobject.h | 8 +- engines/gob/minigames/geisha/mouth.cpp | 170 +++++++++++++++++++++++++++ engines/gob/minigames/geisha/mouth.h | 75 ++++++++++++ engines/gob/minigames/geisha/penetration.cpp | 164 ++++++++++++++++++-------- engines/gob/minigames/geisha/penetration.h | 20 +++- engines/gob/module.mk | 1 + 6 files changed, 380 insertions(+), 58 deletions(-) create mode 100644 engines/gob/minigames/geisha/mouth.cpp create mode 100644 engines/gob/minigames/geisha/mouth.h diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index bd4cf791a8..5ea1f75401 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -61,9 +61,9 @@ public: void setMode(Mode mode); /** Set the current position to the animation's default. */ - void setPosition(); + virtual void setPosition(); /** Set the current position. */ - void setPosition(int16 x, int16 y); + virtual void setPosition(int16 x, int16 y); /** Return the current position. */ void getPosition(int16 &x, int16 &y) const; @@ -93,9 +93,9 @@ public: bool lastFrame() const; /** Draw the current frame onto the surface and return the affected rectangle. */ - bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + virtual bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); /** Draw the current frame from the surface and return the affected rectangle. */ - bool clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom); + virtual bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); /** Advance the animation to the next frame. */ virtual void advance(); diff --git a/engines/gob/minigames/geisha/mouth.cpp b/engines/gob/minigames/geisha/mouth.cpp new file mode 100644 index 0000000000..605ffe420f --- /dev/null +++ b/engines/gob/minigames/geisha/mouth.cpp @@ -0,0 +1,170 @@ +/* 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 "common/util.h" +#include "common/textconsole.h" + +#include "gob/minigames/geisha/mouth.h" + +namespace Gob { + +namespace Geisha { + +Mouth::Mouth(const ANIFile &ani, const CMPFile &cmp, + uint16 mouthAnim, uint16 mouthSprite, uint16 floorSprite) : ANIObject(ani) { + + _sprite = new ANIObject(cmp); + _sprite->setAnimation(mouthSprite); + _sprite->setVisible(true); + + for (int i = 0; i < kFloorCount; i++) { + _floor[i] = new ANIObject(cmp); + _floor[i]->setAnimation(floorSprite); + _floor[i]->setVisible(true); + } + + _state = kStateDeactivated; + + setAnimation(mouthAnim); + setMode(kModeOnce); + setPause(true); + setVisible(true); +} + +Mouth::~Mouth() { + for (int i = 0; i < kFloorCount; i++) + delete _floor[i]; + + delete _sprite; +} + +void Mouth::advance() { + if (_state != kStateActivated) + return; + + // Animation finished, set state to dead + if (isPaused()) { + _state = kStateDead; + return; + } + + ANIObject::advance(); +} + +void Mouth::activate() { + if (_state != kStateDeactivated) + return; + + _state = kStateActivated; + + setPause(false); +} + +bool Mouth::isDeactivated() const { + return _state == kStateDeactivated; +} + +void Mouth::setPosition(int16 x, int16 y) { + ANIObject::setPosition(x, y); + + int16 floorWidth, floorHeight; + _floor[0]->getFrameSize(floorWidth, floorHeight); + + _sprite->setPosition(x, y); + + for (int i = 0; i < kFloorCount; i++) + _floor[i]->setPosition(x + (i * floorWidth), y); +} + +bool Mouth::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + // If the mouth is deactivated, draw the default mouth sprite + if (_state == kStateDeactivated) + return _sprite->draw(dest, left, top, right, bottom); + + // If the mouth is activated, draw the current mouth animation sprite + if (_state == kStateActivated) + return ANIObject::draw(dest, left, top, right, bottom); + + // If the mouth is dead, draw the floor tiles + if (_state == kStateDead) { + int16 fLeft, fRight, fTop, fBottom; + bool drawn = false; + + left = 0x7FFF; + top = 0x7FFF; + right = 0; + bottom = 0; + + for (int i = 0; i < kFloorCount; i++) { + if (_floor[i]->draw(dest, fLeft, fTop, fRight, fBottom)) { + drawn = true; + left = MIN(left , fLeft); + top = MIN(top , fTop); + right = MAX(right , fRight); + bottom = MAX(bottom, fBottom); + } + } + + return drawn; + } + + return false; +} + +bool Mouth::clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom) { + // If the mouth is deactivated, clear the default mouth sprite + if (_state == kStateDeactivated) + return _sprite->clear(dest, left, top, right, bottom); + + // If the mouth is activated, clear the current mouth animation sprite + if (_state == kStateActivated) + return ANIObject::clear(dest, left, top, right, bottom); + + // If the mouth is clear, draw the floor tiles + if (_state == kStateDead) { + int16 fLeft, fRight, fTop, fBottom; + bool cleared = false; + + left = 0x7FFF; + top = 0x7FFF; + right = 0; + bottom = 0; + + for (int i = 0; i < kFloorCount; i++) { + if (_floor[i]->clear(dest, fLeft, fTop, fRight, fBottom)) { + cleared = true; + left = MIN(left , fLeft); + top = MIN(top , fTop); + right = MAX(right , fRight); + bottom = MAX(bottom, fBottom); + } + } + + return cleared; + } + + return false; +} + +} // End of namespace Geisha + +} // End of namespace Gob diff --git a/engines/gob/minigames/geisha/mouth.h b/engines/gob/minigames/geisha/mouth.h new file mode 100644 index 0000000000..2e0cfcd5d0 --- /dev/null +++ b/engines/gob/minigames/geisha/mouth.h @@ -0,0 +1,75 @@ +/* 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 GOB_MINIGAMES_GEISHA_MOUTH_H +#define GOB_MINIGAMES_GEISHA_MOUTH_H + +#include "gob/aniobject.h" + +namespace Gob { + +namespace Geisha { + +/** A kissing/biting mouth in Geisha's "Penetration" minigame. */ +class Mouth : public ANIObject { +public: + Mouth(const ANIFile &ani, const CMPFile &cmp, + uint16 mouthAnim, uint16 mouthSprite, uint16 floorSprite); + ~Mouth(); + + /** Advance the animation to the next frame. */ + void advance(); + + /** Active the mouth's animation. */ + void activate(); + + /** Is the mouth deactivated? */ + bool isDeactivated() const; + + /** Set the current position. */ + void setPosition(int16 x, int16 y); + + /** Draw the current frame onto the surface and return the affected rectangle. */ + bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + /** Draw the current frame from the surface and return the affected rectangle. */ + bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + +private: + static const int kFloorCount = 2; + + enum State { + kStateDeactivated, + kStateActivated, + kStateDead + }; + + ANIObject *_sprite; + ANIObject *_floor[kFloorCount]; + + State _state; +}; + +} // End of namespace Geisha + +} // End of namespace Gob + +#endif // GOB_MINIGAMES_GEISHA_MOUTH_H diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 35802e6733..c8f96f825a 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -31,6 +31,7 @@ #include "gob/minigames/geisha/penetration.h" #include "gob/minigames/geisha/meter.h" +#include "gob/minigames/geisha/mouth.h" namespace Gob { @@ -60,28 +61,39 @@ static const int kColorHealth = 15; static const int kColorBlack = 10; static const int kColorFloor = 13; +enum Sprite { + kSpriteFloorShield = 25, + kSpriteExit = 29, + kSpriteFloor = 30, + kSpriteWall = 31, + kSpriteMouthBite = 32, + kSpriteMouthKiss = 33 +}; + enum Animation { - kAnimationDriveS = 4, - kAnimationDriveE = 5, - kAnimationDriveN = 6, - kAnimationDriveW = 7, - kAnimationDriveSE = 8, - kAnimationDriveNE = 9, - kAnimationDriveSW = 10, - kAnimationDriveNW = 11, - kAnimationShootS = 12, - kAnimationShootN = 13, - kAnimationShootW = 14, - kAnimationShootE = 15, - kAnimationShootNE = 16, - kAnimationShootSE = 17, - kAnimationShootSW = 18, - kAnimationShootNW = 19, - kAnimationExplodeN = 28, - kAnimationExplodeS = 29, - kAnimationExplodeW = 30, - kAnimationExplodeE = 31, - kAnimationExit = 32 + kAnimationDriveS = 4, + kAnimationDriveE = 5, + kAnimationDriveN = 6, + kAnimationDriveW = 7, + kAnimationDriveSE = 8, + kAnimationDriveNE = 9, + kAnimationDriveSW = 10, + kAnimationDriveNW = 11, + kAnimationShootS = 12, + kAnimationShootN = 13, + kAnimationShootW = 14, + kAnimationShootE = 15, + kAnimationShootNE = 16, + kAnimationShootSE = 17, + kAnimationShootSW = 18, + kAnimationShootNW = 19, + kAnimationExplodeN = 28, + kAnimationExplodeS = 29, + kAnimationExplodeW = 30, + kAnimationExplodeE = 31, + kAnimationExit = 32, + kAnimationMouthKiss = 33, + kAnimationMouthBite = 34 }; static const int kMapTileWidth = 24; @@ -197,8 +209,17 @@ Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { } +Penetration::ManagedMouth::ManagedMouth(uint16 pX, uint16 pY, MouthType t) : + Position(pX, pY), mouth(0), type(t) { +} + +Penetration::ManagedMouth::~ManagedMouth() { + delete mouth; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), - _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), + _shieldMeter(0), _healthMeter(0), _floor(0), _mapX(0), _mapY(0), _subTileX(0), _subTileY(0) { _background = new Surface(320, 200, 1); @@ -279,6 +300,9 @@ void Penetration::init() { createMap(); + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) + _mapAnims.push_back(m->mouth); + _sub = new ANIObject(*_objects); _sub->setAnimation(kAnimationDriveN); @@ -289,8 +313,13 @@ void Penetration::init() { } void Penetration::deinit() { + _mapAnims.clear(); _anims.clear(); + _shields.clear(); + + _mouths.clear(); + delete _sub; delete _objects; @@ -311,6 +340,8 @@ void Penetration::createMap() { _shields.clear(); + _mouths.clear(); + _map->fill(kColorBlack); // Draw the map tiles @@ -323,23 +354,21 @@ void Penetration::createMap() { switch (*mapTile) { case 0: // Floor - _sprites->draw(*_map, 30, posX, posY); + _sprites->draw(*_map, kSpriteFloor, posX, posY); break; case 49: // Emergency exit (needs access pass) if (_hasAccessPass) { - // Draw an exit. Now works like a regular exit - _sprites->draw(*_map, 29, posX, posY); - *mapTile = 51; + _sprites->draw(*_map, kSpriteExit, posX, posY); + *mapTile = 51; // Now works like a normal exit } else - // Draw a wall - _sprites->draw(*_map, 31, posX, posY); + _sprites->draw(*_map, kSpriteWall, posX, posY); break; case 50: // Wall - _sprites->draw(*_map, 31, posX, posY); + _sprites->draw(*_map, kSpriteWall, posX, posY); break; case 51: // Regular exit @@ -349,23 +378,27 @@ void Penetration::createMap() { if (_floor == 2) { if (!_hasAccessPass) { - // It's now a wall - _sprites->draw(*_map, 31, posX, posY); - *mapTile = 50; + _sprites->draw(*_map, kSpriteWall, posX, posY); + *mapTile = 50; // It's now a wall } else - _sprites->draw(*_map, 29, posX, posY); + _sprites->draw(*_map, kSpriteExit, posX, posY); } else - _sprites->draw(*_map, 29, posX, posY); + _sprites->draw(*_map, kSpriteExit, posX, posY); } else // Always works in test mode - _sprites->draw(*_map, 29, posX, posY); + _sprites->draw(*_map, kSpriteExit, posX, posY); break; case 52: // Left side of biting mouth - _sprites->draw(*_map, 32, posX, posY); + _mouths.push_back(ManagedMouth(x, y, kMouthTypeBite)); + + _mouths.back().mouth = + new Mouth(*_objects, *_sprites, kAnimationMouthBite, kSpriteMouthBite, kSpriteFloor); + + _mouths.back().mouth->setPosition(posX, posY); break; case 53: // Right side of biting mouth @@ -373,7 +406,12 @@ void Penetration::createMap() { break; case 54: // Left side of kissing mouth - _sprites->draw(*_map, 33, posX, posY); + _mouths.push_back(ManagedMouth(x, y, kMouthTypeKiss)); + + _mouths.back().mouth = + new Mouth(*_objects, *_sprites, kAnimationMouthKiss, kSpriteMouthKiss, kSpriteFloor); + + _mouths.back().mouth->setPosition(posX, posY); break; case 55: // Right side of kissing mouth @@ -381,8 +419,8 @@ void Penetration::createMap() { break; case 56: // Shield lying on the floor - _sprites->draw(*_map, 30, posX , posY ); // Floor - _sprites->draw(*_map, 25, posX + 4, posY + 8); // Shield + _sprites->draw(*_map, kSpriteFloor , posX , posY ); // Floor + _sprites->draw(*_map, kSpriteFloorShield, posX + 4, posY + 8); // Shield _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield @@ -391,7 +429,7 @@ void Penetration::createMap() { break; case 57: // Start position - _sprites->draw(*_map, 30, posX, posY); + _sprites->draw(*_map, kSpriteFloor, posX, posY); *mapTile = 0; _subTileX = x; @@ -403,8 +441,6 @@ void Penetration::createMap() { } } } - - _mapUpdate = true; } void Penetration::initScreen() { @@ -479,12 +515,11 @@ void Penetration::moveSub(int x, int y, uint16 animation) { _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth; _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight; - _mapUpdate = true; - if (_sub->getAnimation() != animation) _sub->setAnimation(animation); checkShields(); + checkMouths(); } void Penetration::checkShields() { @@ -504,9 +539,37 @@ void Penetration::checkShields() { } } +void Penetration::checkMouths() { + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); ++m) { + if (!m->mouth->isDeactivated()) + continue; + + if ((( m->x == _subTileX) && (m->y == _subTileY)) || + (((m->x + 1) == _subTileX) && (m->y == _subTileY))) { + + m->mouth->activate(); + } + } +} + void Penetration::updateAnims() { int16 left = 0, top = 0, right = 0, bottom = 0; + // Clear the previous map animation frames + for (Common::List::iterator a = _mapAnims.reverse_begin(); + a != _mapAnims.end(); --a) { + + (*a)->clear(*_map, left, top, right, bottom); + } + + // Draw the current map animation frames + for (Common::List::iterator a = _mapAnims.begin(); + a != _mapAnims.end(); ++a) { + + (*a)->draw(*_map, left, top, right, bottom); + (*a)->advance(); + } + // Clear the previous animation frames for (Common::List::iterator a = _anims.reverse_begin(); a != _anims.end(); --a) { @@ -515,14 +578,11 @@ void Penetration::updateAnims() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } - if (_mapUpdate) { - _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, - _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, - kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); - } - - _mapUpdate = false; + // Draw the map + _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, + _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, + kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 4d3455b638..ef0e3b10f0 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -36,6 +36,7 @@ class ANIFile; namespace Geisha { class Meter; +class Mouth; /** Geisha's "Penetration" minigame. */ class Penetration { @@ -61,6 +62,19 @@ private: Position(uint16 pX, uint16 pY); }; + enum MouthType { + kMouthTypeBite, + kMouthTypeKiss + }; + + struct ManagedMouth : public Position { + Mouth *mouth; + MouthType type; + + ManagedMouth(uint16 pX, uint16 pY, MouthType t); + ~ManagedMouth(); + }; + GobEngine *_vm; bool _hasAccessPass; @@ -74,6 +88,7 @@ private: ANIObject *_sub; Common::List _anims; + Common::List _mapAnims; Meter *_shieldMeter; Meter *_healthMeter; @@ -83,14 +98,14 @@ private: Surface *_map; byte _mapTiles[kMapWidth * kMapHeight]; - bool _mapUpdate; uint16 _mapX; uint16 _mapY; uint8 _subTileX; uint8 _subTileY; - Common::List _shields; + Common::List _shields; + Common::List _mouths; void init(); @@ -110,6 +125,7 @@ private: bool isWalkable(byte tile) const; void checkShields(); + void checkMouths(); }; } // End of namespace Geisha diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 9da5a82de2..c5ae947a1c 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -80,6 +80,7 @@ MODULE_OBJS := \ minigames/geisha/oko.o \ minigames/geisha/meter.o \ minigames/geisha/diving.o \ + minigames/geisha/mouth.o \ minigames/geisha/penetration.o \ save/savefile.o \ save/savehandler.o \ -- cgit v1.2.3 From 73776406686709bc79ff9c6423937dce0e43c5d6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 5 Jun 2012 16:21:36 +0200 Subject: GOB: Play sounds for mouths and shields in Penetration --- engines/gob/minigames/geisha/penetration.cpp | 20 ++++++++++++++++++++ engines/gob/minigames/geisha/penetration.h | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index c8f96f825a..1321842d07 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -29,6 +29,8 @@ #include "gob/anifile.h" #include "gob/aniobject.h" +#include "gob/sound/sound.h" + #include "gob/minigames/geisha/penetration.h" #include "gob/minigames/geisha/meter.h" #include "gob/minigames/geisha/mouth.h" @@ -280,6 +282,11 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { } void Penetration::init() { + // Load sounds + _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); + _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); + _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); + _background->clear(); _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background); @@ -313,6 +320,10 @@ void Penetration::init() { } void Penetration::deinit() { + _soundShield.free(); + _soundBite.free(); + _soundKiss.free(); + _mapAnims.clear(); _anims.clear(); @@ -528,6 +539,9 @@ void Penetration::checkShields() { // Charge shields _shieldMeter->setMaxValue(); + // Play the shield sound + _vm->_sound->blasterPlay(&_soundShield, 1, 0); + // Erase the shield from the map const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth; const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight; @@ -548,6 +562,12 @@ void Penetration::checkMouths() { (((m->x + 1) == _subTileX) && (m->y == _subTileY))) { m->mouth->activate(); + + // Play the mouth sound + if (m->type == kMouthTypeBite) + _vm->_sound->blasterPlay(&_soundBite, 1, 0); + else if (m->type == kMouthTypeKiss) + _vm->_sound->blasterPlay(&_soundKiss, 1, 0); } } } diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index ef0e3b10f0..00ddb4bdba 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -26,6 +26,8 @@ #include "common/system.h" #include "common/list.h" +#include "gob/sound/sounddesc.h" + namespace Gob { class GobEngine; @@ -107,6 +109,10 @@ private: Common::List _shields; Common::List _mouths; + SoundDesc _soundShield; + SoundDesc _soundBite; + SoundDesc _soundKiss; + void init(); void deinit(); -- cgit v1.2.3 From 4392e4d7aab9114ff66a1fcda34d21f404b4ebcd Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 5 Jun 2012 17:01:40 +0200 Subject: GOB: Implement health gain/loss for mouths --- engines/gob/minigames/geisha/meter.cpp | 22 ++++++++++++++++++---- engines/gob/minigames/geisha/meter.h | 8 ++++---- engines/gob/minigames/geisha/penetration.cpp | 24 +++++++++++++++++++----- engines/gob/minigames/geisha/penetration.h | 3 +++ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp index 9dcc717e48..719ecf3d18 100644 --- a/engines/gob/minigames/geisha/meter.cpp +++ b/engines/gob/minigames/geisha/meter.cpp @@ -63,22 +63,36 @@ void Meter::setMaxValue() { setValue(_maxValue); } -void Meter::increase(int32 n) { +int32 Meter::increase(int32 n) { + if (n < 0) + return decrease(-n); + + int32 overflow = MAX(0, (_value + n) - _maxValue); + int32 value = CLIP(_value + n, 0, _maxValue); if (_value == value) - return; + return overflow; _value = value; _needUpdate = true; + + return overflow; } -void Meter::decrease(int32 n) { +int32 Meter::decrease(int32 n) { + if (n < 0) + return increase(-n); + + int32 underflow = -MIN(0, _value - n); + int32 value = CLIP(_value - n, 0, _maxValue); if (_value == value) - return; + return underflow; _value = value; _needUpdate = true; + + return underflow; } void Meter::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { diff --git a/engines/gob/minigames/geisha/meter.h b/engines/gob/minigames/geisha/meter.h index d3e82cb32e..30dc826de0 100644 --- a/engines/gob/minigames/geisha/meter.h +++ b/engines/gob/minigames/geisha/meter.h @@ -55,10 +55,10 @@ public: /** Set the current value the meter is measuring to the max value. */ void setMaxValue(); - /** Increase the current value the meter is measuring. */ - void increase(int32 n = 1); - /** Decrease the current value the meter is measuring. */ - void decrease(int32 n = 1); + /** Increase the current value the meter is measuring, returning the overflow. */ + int32 increase(int32 n = 1); + /** Decrease the current value the meter is measuring, returning the underflow. */ + int32 decrease(int32 n = 1); /** Draw the meter onto the surface and return the affected rectangle. */ void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 1321842d07..a188995372 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -226,8 +226,8 @@ Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _background = new Surface(320, 200, 1); - _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 1020, Meter::kFillToRight); - _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 1020, Meter::kFillToRight); + _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 920, Meter::kFillToRight); + _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 920, Meter::kFillToRight); _map = new Surface(kMapWidth * kMapTileWidth + kPlayAreaWidth , kMapHeight * kMapTileHeight + kPlayAreaHeight, 1); @@ -563,15 +563,29 @@ void Penetration::checkMouths() { m->mouth->activate(); - // Play the mouth sound - if (m->type == kMouthTypeBite) + // Play the mouth sound and do health gain/loss + if (m->type == kMouthTypeBite) { _vm->_sound->blasterPlay(&_soundBite, 1, 0); - else if (m->type == kMouthTypeKiss) + healthLose(230); + } else if (m->type == kMouthTypeKiss) { _vm->_sound->blasterPlay(&_soundKiss, 1, 0); + healthGain(120); + } } } } +void Penetration::healthGain(int amount) { + if (_shieldMeter->getValue() > 0) + _healthMeter->increase(_shieldMeter->increase(amount)); + else + _healthMeter->increase(amount); +} + +void Penetration::healthLose(int amount) { + _healthMeter->decrease(_shieldMeter->decrease(amount)); +} + void Penetration::updateAnims() { int16 left = 0, top = 0, right = 0, bottom = 0; diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 00ddb4bdba..488396ea32 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -132,6 +132,9 @@ private: void checkShields(); void checkMouths(); + + void healthGain(int amount); + void healthLose(int amount); }; } // End of namespace Geisha -- cgit v1.2.3 From 2aeb883123d01bd1dacc05627b610f0d2d9e7d08 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 5 Jun 2012 13:17:04 -0400 Subject: SCUMM: Show an error dialog when trying to run puttzoo ios lite The lite version contains the full game and we will not support it due to potential piracy. --- devtools/scumm-md5.txt | 1 + engines/scumm/detection.cpp | 8 ++++++++ engines/scumm/scumm-md5.h | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt index f08b7d29d2..5223d6785d 100644 --- a/devtools/scumm-md5.txt +++ b/devtools/scumm-md5.txt @@ -776,6 +776,7 @@ puttzoo Putt-Putt Saves the Zoo f3d55aea441e260e9e9c7d2a187097e0 14337 en Windows - Demo - khalek 65fa23d6884e8ca23d5d2406d70de7e8 -1 fr Windows - Demo - gist974 2a446817ffcabfef8716e0c456ecaf81 -1 de Windows - Demo - Joachim Eberhard + 4e859d3ef1e146b41e7d93c35cd6cc62 -1 en iOS HE 100 Lite - clone2727 PuttTime Putt-Putt Travels Through Time fcb78ebecab2757264c590890c319cc5 -1 nl All HE 85 - - adutchguy, daniel9 diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index cd878b49ae..95de1a8706 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -1079,6 +1079,14 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co debug(1, "Using MD5 '%s'", res.md5.c_str()); } + // We don't support the "Lite" version off puttzoo iOS because it contains + // the full game. + if (!strcmp(res.game.gameid, "puttzoo") && !strcmp(res.extra, "Lite")) { + GUIErrorMessage("The Lite version of Putt-Putt Saves the Zoo iOS is not supported to avoid piracy.\n" + "The full version is available for purchase from the iTunes Store."); + return Common::kUnsupportedGameidError; + } + // If the GUI options were updated, we catch this here and update them in the users config // file transparently. Common::updateGameGUIOptions(res.game.guioptions, getGameGUIOptionsDescriptionLanguage(res.language)); diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 946e954a46..9aac4a082f 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Tue May 29 00:49:03 2012 + This file was generated by the md5table tool on Tue Jun 5 16:56:40 2012 DO NOT EDIT MANUALLY! */ @@ -215,6 +215,7 @@ static const MD5Table md5table[] = { { "4dbff3787aedcd96b0b325f2d92d7ad9", "maze", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "4dc780f1bc587a193ce8a97652791438", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga }, { "4e5867848ee61bc30d157e2c94eee9b4", "PuttTime", "HE 90", "Demo", 18394, Common::EN_USA, Common::kPlatformUnknown }, + { "4e859d3ef1e146b41e7d93c35cd6cc62", "puttzoo", "HE 100", "Lite", -1, Common::EN_ANY, Common::kPlatformIOS }, { "4edbf9d03550f7ba01e7f34d69b678dd", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "4f04b321a95d4315ce6d65f8e1dd0368", "maze", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "4f138ac6f9b2ac5a41bc68b2c3296064", "freddi4", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows }, -- cgit v1.2.3 From d2c6525d881f5c391b0c94bcb2c10c328aa5492f Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Tue, 5 Jun 2012 22:26:51 +0100 Subject: SWORD1: Fix crash in demo when using French subtitles --- engines/sword1/text.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engines/sword1/text.cpp b/engines/sword1/text.cpp index 3bd2fdb2e6..f23ac5f182 100644 --- a/engines/sword1/text.cpp +++ b/engines/sword1/text.cpp @@ -156,6 +156,8 @@ uint16 Text::analyzeSentence(const uint8 *text, uint16 maxWidth, LineInfo *line) } uint16 Text::copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen) { + if (ch < SPACE) + ch = 64; FrameHeader *chFrame = _resMan->fetchFrame(_font, ch - SPACE); uint8 *chData = ((uint8 *)chFrame) + sizeof(FrameHeader); uint8 *dest = sprPtr; -- cgit v1.2.3 From ac76994781fedecbfa74cd43d0983dcd7b06f12c Mon Sep 17 00:00:00 2001 From: Thierry Crozat Date: Tue, 5 Jun 2012 22:34:37 +0100 Subject: SWORD1: Use _missingSubTitleStr when asking for an out of bound textId It was using textId 0, which is not the subtitle we want anyway. So instead of using the wrong subtitle, it is probably better to not display a subtitle at all. A test case for this is with the demo when using non-english language as several subtitles are missing toward the end. --- engines/sword1/objectman.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sword1/objectman.cpp b/engines/sword1/objectman.cpp index ed994a97fa..d0803590a7 100644 --- a/engines/sword1/objectman.cpp +++ b/engines/sword1/objectman.cpp @@ -105,7 +105,7 @@ char *ObjectMan::lockText(uint32 textId) { addr += sizeof(Header); if ((textId & ITM_ID) >= _resMan->readUint32(addr)) { warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, _resMan->readUint32(addr)); - textId = 0; // get first line instead + return _missingSubTitleStr; } uint32 offset = _resMan->readUint32(addr + ((textId & ITM_ID) + 1) * 4); if (offset == 0) { -- cgit v1.2.3 From 93dda1b227fa11d1da2d923ca63a580343f6ba4e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 01:47:43 +0200 Subject: GOB: const correctness --- engines/gob/minigames/geisha/evilfish.cpp | 2 +- engines/gob/minigames/geisha/evilfish.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/gob/minigames/geisha/evilfish.cpp b/engines/gob/minigames/geisha/evilfish.cpp index c7ef9d5622..05ae9d0ad4 100644 --- a/engines/gob/minigames/geisha/evilfish.cpp +++ b/engines/gob/minigames/geisha/evilfish.cpp @@ -171,7 +171,7 @@ void EvilFish::mutate(uint16 animSwimLeft, uint16 animSwimRight, } } -bool EvilFish::isDead() { +bool EvilFish::isDead() const { return !isVisible() || (_state == kStateNone) || (_state == kStateDie); } diff --git a/engines/gob/minigames/geisha/evilfish.h b/engines/gob/minigames/geisha/evilfish.h index 81efb676e2..4c82629461 100644 --- a/engines/gob/minigames/geisha/evilfish.h +++ b/engines/gob/minigames/geisha/evilfish.h @@ -58,7 +58,7 @@ public: uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie); /** Is the fish dead? */ - bool isDead(); + bool isDead() const; private: enum State { -- cgit v1.2.3 From b83ac21f6008287414d59ad7f9c88b63bd93bac5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 02:52:19 +0200 Subject: GOB: Implement Penetration submarine shooting and dying Shots don't result in bullets yet, though --- engines/gob/minigames/geisha/mouth.cpp | 1 - engines/gob/minigames/geisha/penetration.cpp | 149 +++++++++-------- engines/gob/minigames/geisha/penetration.h | 29 +++- engines/gob/minigames/geisha/submarine.cpp | 233 +++++++++++++++++++++++++++ engines/gob/minigames/geisha/submarine.h | 96 +++++++++++ engines/gob/module.mk | 1 + 6 files changed, 435 insertions(+), 74 deletions(-) create mode 100644 engines/gob/minigames/geisha/submarine.cpp create mode 100644 engines/gob/minigames/geisha/submarine.h diff --git a/engines/gob/minigames/geisha/mouth.cpp b/engines/gob/minigames/geisha/mouth.cpp index 605ffe420f..7ba9f86f8c 100644 --- a/engines/gob/minigames/geisha/mouth.cpp +++ b/engines/gob/minigames/geisha/mouth.cpp @@ -21,7 +21,6 @@ */ #include "common/util.h" -#include "common/textconsole.h" #include "gob/minigames/geisha/mouth.h" diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index a188995372..2c1a4918b9 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -73,27 +73,6 @@ enum Sprite { }; enum Animation { - kAnimationDriveS = 4, - kAnimationDriveE = 5, - kAnimationDriveN = 6, - kAnimationDriveW = 7, - kAnimationDriveSE = 8, - kAnimationDriveNE = 9, - kAnimationDriveSW = 10, - kAnimationDriveNW = 11, - kAnimationShootS = 12, - kAnimationShootN = 13, - kAnimationShootW = 14, - kAnimationShootE = 15, - kAnimationShootNE = 16, - kAnimationShootSE = 17, - kAnimationShootSW = 18, - kAnimationShootNW = 19, - kAnimationExplodeN = 28, - kAnimationExplodeS = 29, - kAnimationExplodeW = 30, - kAnimationExplodeE = 31, - kAnimationExit = 32, kAnimationMouthKiss = 33, kAnimationMouthBite = 34 }; @@ -220,9 +199,18 @@ Penetration::ManagedMouth::~ManagedMouth() { } +Penetration::ManagedSub::ManagedSub(uint16 pX, uint16 pY) : Position(pX, pY), sub(0) { + mapX = x * kMapTileWidth; + mapY = y * kMapTileHeight; +} + +Penetration::ManagedSub::~ManagedSub() { + delete sub; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), - _shieldMeter(0), _healthMeter(0), _floor(0), _mapX(0), _mapY(0), - _subTileX(0), _subTileY(0) { + _shieldMeter(0), _healthMeter(0), _floor(0) { _background = new Surface(320, 200, 1); @@ -255,7 +243,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_draw->blitInvalidated(); _vm->_video->retrace(); - while (!_vm->shouldQuit()) { + while (!_vm->shouldQuit() && !isDead() && !hasWon()) { updateAnims(); // Draw and wait for the end of the frame @@ -278,7 +266,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { } deinit(); - return false; + + return hasWon(); } void Penetration::init() { @@ -286,6 +275,7 @@ void Penetration::init() { _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); + _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); _background->clear(); @@ -310,19 +300,14 @@ void Penetration::init() { for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) _mapAnims.push_back(m->mouth); - _sub = new ANIObject(*_objects); - - _sub->setAnimation(kAnimationDriveN); - _sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight); - _sub->setVisible(true); - - _anims.push_back(_sub); + _anims.push_back(_sub->sub); } void Penetration::deinit() { _soundShield.free(); _soundBite.free(); _soundKiss.free(); + _soundShoot.free(); _mapAnims.clear(); _anims.clear(); @@ -349,8 +334,10 @@ void Penetration::createMap() { // Copy the correct map memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); - _shields.clear(); + delete _sub; + _sub = 0; + _shields.clear(); _mouths.clear(); _map->fill(kColorBlack); @@ -441,17 +428,22 @@ void Penetration::createMap() { case 57: // Start position _sprites->draw(*_map, kSpriteFloor, posX, posY); + *mapTile = 0; - _subTileX = x; - _subTileY = y; + delete _sub; + + _sub = new ManagedSub(x, y); - _mapX = _subTileX * kMapTileWidth; - _mapY = _subTileY * kMapTileHeight; + _sub->sub = new Submarine(*_objects); + _sub->sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight); break; } } } + + if (!_sub) + error("Geisha: No starting position in floor %d (testmode: %d", _floor, _testMode); } void Penetration::initScreen() { @@ -491,51 +483,64 @@ bool Penetration::isWalkable(byte tile) const { void Penetration::handleSub(int16 key) { if (key == kKeyLeft) - moveSub(-5, 0, kAnimationDriveW); + subMove(-5, 0, Submarine::kDirectionW); else if (key == kKeyRight) - moveSub( 5, 0, kAnimationDriveE); + subMove( 5, 0, Submarine::kDirectionE); else if (key == kKeyUp) - moveSub( 0, -5, kAnimationDriveN); + subMove( 0, -5, Submarine::kDirectionN); else if (key == kKeyDown) - moveSub( 0, 5, kAnimationDriveS); + subMove( 0, 5, Submarine::kDirectionS); + else if (key == kKeySpace) + subShoot(); } -void Penetration::moveSub(int x, int y, uint16 animation) { +void Penetration::subMove(int x, int y, Submarine::Direction direction) { + if (!_sub->sub->canMove()) + return; + // Limit the movement to walkable tiles int16 minX = 0; - if ((_subTileX > 0) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX - 1)])) - minX = _subTileX * kMapTileWidth; + if ((_sub->x > 0) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x - 1)])) + minX = _sub->x * kMapTileWidth; int16 maxX = kMapWidth * kMapTileWidth; - if ((_subTileX < (kMapWidth - 1)) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX + 1)])) - maxX = _subTileX * kMapTileWidth; + if ((_sub->x < (kMapWidth - 1)) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x + 1)])) + maxX = _sub->x * kMapTileWidth; int16 minY = 0; - if ((_subTileY > 0) && !isWalkable(_mapTiles[(_subTileY - 1) * kMapWidth + _subTileX])) - minY = _subTileY * kMapTileHeight; + if ((_sub->y > 0) && !isWalkable(_mapTiles[(_sub->y - 1) * kMapWidth + _sub->x])) + minY = _sub->y * kMapTileHeight; int16 maxY = kMapHeight * kMapTileHeight; - if ((_subTileY < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_subTileY + 1) * kMapWidth + _subTileX])) - maxY = _subTileY * kMapTileHeight; + if ((_sub->y < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_sub->y + 1) * kMapWidth + _sub->x])) + maxY = _sub->y * kMapTileHeight; - _mapX = CLIP(_mapX + x, minX, maxX); - _mapY = CLIP(_mapY + y, minY, maxY); + _sub->mapX = CLIP(_sub->mapX + x, minX, maxX); + _sub->mapY = CLIP(_sub->mapY + y, minY, maxY); // The tile the sub is on is where its mid-point is - _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth; - _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight; + _sub->x = (_sub->mapX + (kMapTileWidth / 2)) / kMapTileWidth; + _sub->y = (_sub->mapY + (kMapTileHeight / 2)) / kMapTileHeight; - if (_sub->getAnimation() != animation) - _sub->setAnimation(animation); + _sub->sub->turn(direction); checkShields(); checkMouths(); } +void Penetration::subShoot() { + if (!_sub->sub->canMove()) + return; + + _sub->sub->shoot(); + + _vm->_sound->blasterPlay(&_soundShoot, 1, 0); +} + void Penetration::checkShields() { for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { - if ((pos->x == _subTileX) && (pos->y == _subTileY)) { + if ((pos->x == _sub->x) && (pos->y == _sub->y)) { // Charge shields _shieldMeter->setMaxValue(); @@ -558,13 +563,13 @@ void Penetration::checkMouths() { if (!m->mouth->isDeactivated()) continue; - if ((( m->x == _subTileX) && (m->y == _subTileY)) || - (((m->x + 1) == _subTileX) && (m->y == _subTileY))) { + if ((( m->x == _sub->x) && (m->y == _sub->y)) || + (((m->x + 1) == _sub->x) && (m->y == _sub->y))) { m->mouth->activate(); // Play the mouth sound and do health gain/loss - if (m->type == kMouthTypeBite) { + if (m->type == kMouthTypeBite) { _vm->_sound->blasterPlay(&_soundBite, 1, 0); healthLose(230); } else if (m->type == kMouthTypeKiss) { @@ -584,6 +589,17 @@ void Penetration::healthGain(int amount) { void Penetration::healthLose(int amount) { _healthMeter->decrease(_shieldMeter->decrease(amount)); + + if (_healthMeter->getValue() == 0) + _sub->sub->die(); +} + +bool Penetration::isDead() const { + return _sub && _sub->sub->isDead(); +} + +bool Penetration::hasWon() const { + return _floor > kFloorCount; } void Penetration::updateAnims() { @@ -612,11 +628,14 @@ void Penetration::updateAnims() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } - // Draw the map - _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, - _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, - kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); + if (_sub) { + // Draw the map + + _vm->_draw->_backSurface->blit(*_map, _sub->mapX, _sub->mapY, + _sub->mapX + kPlayAreaWidth - 1, _sub->mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, + kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); + } // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 488396ea32..0582b99e83 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -28,6 +28,8 @@ #include "gob/sound/sounddesc.h" +#include "gob/minigames/geisha/submarine.h" + namespace Gob { class GobEngine; @@ -77,6 +79,18 @@ private: ~ManagedMouth(); }; + struct ManagedSub : public Position { + Submarine *sub; + + uint16 mapX; + uint16 mapY; + + ManagedSub(uint16 pX, uint16 pY); + ~ManagedSub(); + + void setPosition(uint16 pX, uint16 pY); + }; + GobEngine *_vm; bool _hasAccessPass; @@ -87,8 +101,6 @@ private: CMPFile *_sprites; ANIFile *_objects; - ANIObject *_sub; - Common::List _anims; Common::List _mapAnims; @@ -100,11 +112,7 @@ private: Surface *_map; byte _mapTiles[kMapWidth * kMapHeight]; - uint16 _mapX; - uint16 _mapY; - - uint8 _subTileX; - uint8 _subTileY; + ManagedSub *_sub; Common::List _shields; Common::List _mouths; @@ -112,6 +120,7 @@ private: SoundDesc _soundShield; SoundDesc _soundBite; SoundDesc _soundKiss; + SoundDesc _soundShoot; void init(); @@ -126,7 +135,8 @@ private: int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); void handleSub(int16 key); - void moveSub(int x, int y, uint16 animation); + void subMove(int x, int y, Submarine::Direction direction); + void subShoot(); bool isWalkable(byte tile) const; @@ -135,6 +145,9 @@ private: void healthGain(int amount); void healthLose(int amount); + + bool isDead() const; + bool hasWon() const; }; } // End of namespace Geisha diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp new file mode 100644 index 0000000000..4a18c6e043 --- /dev/null +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -0,0 +1,233 @@ +/* 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 "gob/minigames/geisha/submarine.h" + +namespace Gob { + +namespace Geisha { + +enum Animation { + kAnimationDriveS = 4, + kAnimationDriveE = 5, + kAnimationDriveN = 6, + kAnimationDriveW = 7, + kAnimationDriveSE = 8, + kAnimationDriveNE = 9, + kAnimationDriveSW = 10, + kAnimationDriveNW = 11, + kAnimationShootS = 12, + kAnimationShootN = 13, + kAnimationShootW = 14, + kAnimationShootE = 15, + kAnimationShootNE = 16, + kAnimationShootSE = 17, + kAnimationShootSW = 18, + kAnimationShootNW = 19, + kAnimationExplodeN = 28, + kAnimationExplodeS = 29, + kAnimationExplodeW = 30, + kAnimationExplodeE = 31, + kAnimationExit = 32 +}; + + +Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateNone) { + turn(kDirectionN); +} + +Submarine::~Submarine() { +} + +void Submarine::turn(Direction to) { + // Nothing to do + if ((_state == kStateMove) && (_direction == to)) + return; + + _state = kStateMove; + _direction = to; + + setAnimation(directionToMove(_direction)); + setMode(kModeContinuous); + setPause(false); + setVisible(true); +} + +void Submarine::shoot() { + _state = kStateShoot; + + setAnimation(directionToShoot(_direction)); + setMode(kModeOnce); + setPause(false); + setVisible(true); +} + +void Submarine::die() { + _state = kStateDie; + + setAnimation(directionToExplode(_direction)); + setMode(kModeOnce); + setPause(false); + setVisible(true); +} + +void Submarine::leave() { + _state = kStateExit; + + setAnimation(kAnimationExit); + setMode(kModeOnce); + setPause(false); + setVisible(true); +} + +void Submarine::advance() { + ANIObject::advance(); + + switch (_state) { + case kStateShoot: + if (isPaused()) + turn(_direction); + break; + + case kStateExit: + if (isPaused()) { + _state = kStateExited; + + setVisible(true); + } + + break; + + case kStateDie: + if (isPaused()) + _state = kStateDead; + break; + + default: + break; + } +} + +bool Submarine::canMove() const { + return (_state == kStateMove) || (_state == kStateShoot); +} + +bool Submarine::isDead() const { + return _state == kStateDead; +} + +uint16 Submarine::directionToMove(Direction direction) const { + switch (direction) { + case kDirectionN: + return kAnimationDriveN; + + case kDirectionNE: + return kAnimationDriveNE; + + case kDirectionE: + return kAnimationDriveE; + + case kDirectionSE: + return kAnimationDriveSE; + + case kDirectionS: + return kAnimationDriveS; + + case kDirectionSW: + return kAnimationDriveSW; + + case kDirectionW: + return kAnimationDriveW; + + case kDirectionNW: + return kAnimationDriveNW; + + default: + break; + } + + return 0; +} + +uint16 Submarine::directionToShoot(Direction direction) const { + switch (direction) { + case kDirectionN: + return kAnimationShootN; + + case kDirectionNE: + return kAnimationShootNE; + + case kDirectionE: + return kAnimationShootE; + + case kDirectionSE: + return kAnimationShootSE; + + case kDirectionS: + return kAnimationShootS; + + case kDirectionSW: + return kAnimationShootSW; + + case kDirectionW: + return kAnimationShootW; + + case kDirectionNW: + return kAnimationShootNW; + + default: + break; + } + + return 0; +} + +uint16 Submarine::directionToExplode(Direction direction) const { + // Only 4 exploding animations (spinning clockwise) + + switch (direction) { + case kDirectionNW: + case kDirectionN: + return kAnimationExplodeN; + + case kDirectionNE: + case kDirectionE: + return kAnimationExplodeE; + + case kDirectionSE: + case kDirectionS: + return kAnimationExplodeS; + + case kDirectionSW: + case kDirectionW: + return kAnimationExplodeW; + + default: + break; + } + + return 0; +} + +} // End of namespace Geisha + +} // End of namespace Gob diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h new file mode 100644 index 0000000000..e8ae72d996 --- /dev/null +++ b/engines/gob/minigames/geisha/submarine.h @@ -0,0 +1,96 @@ +/* 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 GOB_MINIGAMES_GEISHA_SUBMARINE_H +#define GOB_MINIGAMES_GEISHA_SUBMARINE_H + +#include "gob/aniobject.h" + +namespace Gob { + +namespace Geisha { + +/** The submarine Geisha's "Penetration" minigame. */ +class Submarine : public ANIObject { +public: + enum Direction { + kDirectionN, + kDirectionNE, + kDirectionE, + kDirectionSE, + kDirectionS, + kDirectionSW, + kDirectionW, + kDirectionNW + }; + + Submarine(const ANIFile &ani); + ~Submarine(); + + /** Turn to the specified direction. */ + void turn(Direction to); + + /** Play the shoot animation. */ + void shoot(); + + /** Play the exploding animation. */ + void die(); + + /** Play the exiting animation. */ + void leave(); + + /** Advance the animation to the next frame. */ + void advance(); + + /** Can the submarine move at the moment? */ + bool canMove() const; + + /** Is the submarine dead? */ + bool isDead() const; + +private: + enum State { + kStateNone = 0, + kStateMove, + kStateShoot, + kStateExit, + kStateExited, + kStateDie, + kStateDead + }; + + State _state; + Direction _direction; + + /** Map the directions to move animation indices. */ + uint16 directionToMove(Direction direction) const; + /** Map the directions to shoot animation indices. */ + uint16 directionToShoot(Direction direction) const; + /** Map the directions to explode animation indices. */ + uint16 directionToExplode(Direction direction) const; +}; + +} // End of namespace Geisha + +} // End of namespace Gob + +#endif // GOB_MINIGAMES_GEISHA_SUBMARINE_H diff --git a/engines/gob/module.mk b/engines/gob/module.mk index c5ae947a1c..b9680fad6b 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -81,6 +81,7 @@ MODULE_OBJS := \ minigames/geisha/meter.o \ minigames/geisha/diving.o \ minigames/geisha/mouth.o \ + minigames/geisha/submarine.o \ minigames/geisha/penetration.o \ save/savefile.o \ save/savehandler.o \ -- cgit v1.2.3 From 1782012f9f9ec368689fb2e232543a5aea3c1073 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 03:12:12 +0200 Subject: GOB: Clean up the Penetration map handling a bit --- engines/gob/minigames/geisha/penetration.cpp | 92 ++++++++++++++-------------- engines/gob/minigames/geisha/penetration.h | 6 +- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 2c1a4918b9..22cb06fed8 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -309,84 +309,88 @@ void Penetration::deinit() { _soundKiss.free(); _soundShoot.free(); + clearMap(); + + delete _objects; + delete _sprites; + + _objects = 0; + _sprites = 0; +} + +void Penetration::clearMap() { _mapAnims.clear(); _anims.clear(); + _exits.clear(); _shields.clear(); - _mouths.clear(); delete _sub; - delete _objects; - delete _sprites; - - _objects = 0; - _sprites = 0; - _sub = 0; + + _map->fill(kColorBlack); } void Penetration::createMap() { if (_floor >= kFloorCount) error("Geisha: Invalid floor %d in minigame penetration", _floor); - // Copy the correct map - memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); - - delete _sub; - _sub = 0; + clearMap(); - _shields.clear(); - _mouths.clear(); + const byte *mapTiles = kMaps[_testMode ? 1 : 0][_floor]; - _map->fill(kColorBlack); + bool exitWorks; // Draw the map tiles for (int y = 0; y < kMapHeight; y++) { for (int x = 0; x < kMapWidth; x++) { - byte *mapTile = _mapTiles + (y * kMapWidth + x); + const byte mapTile = mapTiles[y * kMapWidth + x]; + + bool *walkMap = _walkMap + (y * kMapWidth + x); const int posX = kPlayAreaBorderWidth + x * kMapTileWidth; const int posY = kPlayAreaBorderHeight + y * kMapTileHeight; - switch (*mapTile) { + *walkMap = true; + + switch (mapTile) { case 0: // Floor _sprites->draw(*_map, kSpriteFloor, posX, posY); break; case 49: // Emergency exit (needs access pass) - if (_hasAccessPass) { + exitWorks = _hasAccessPass; + if (exitWorks) { + _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); - *mapTile = 51; // Now works like a normal exit - } else + } else { _sprites->draw(*_map, kSpriteWall, posX, posY); + *walkMap = false; + } break; case 50: // Wall _sprites->draw(*_map, kSpriteWall, posX, posY); + *walkMap = false; break; case 51: // Regular exit - if (!_testMode) { - // When we're not in test mode, the last exit only works with an access pass - - if (_floor == 2) { - if (!_hasAccessPass) { - _sprites->draw(*_map, kSpriteWall, posX, posY); - *mapTile = 50; // It's now a wall - } else - _sprites->draw(*_map, kSpriteExit, posX, posY); - - } else - _sprites->draw(*_map, kSpriteExit, posX, posY); + // A regular exit works always in test mode. + // But if we're in real mode, and on the last floor, it needs an access pass + exitWorks = _testMode || (_floor < 2) || _hasAccessPass; - } else - // Always works in test mode + if (exitWorks) { + _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); + } else { + _sprites->draw(*_map, kSpriteWall, posX, posY); + *walkMap = false; + } break; @@ -400,7 +404,6 @@ void Penetration::createMap() { break; case 53: // Right side of biting mouth - *mapTile = 0; // Works like a floor break; case 54: // Left side of kissing mouth @@ -413,7 +416,6 @@ void Penetration::createMap() { break; case 55: // Right side of kissing mouth - *mapTile = 0; // Works like a floor break; case 56: // Shield lying on the floor @@ -429,8 +431,6 @@ void Penetration::createMap() { case 57: // Start position _sprites->draw(*_map, kSpriteFloor, posX, posY); - *mapTile = 0; - delete _sub; _sub = new ManagedSub(x, y); @@ -472,13 +472,11 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB return _vm->_util->checkKey(); } -bool Penetration::isWalkable(byte tile) const { - // Only walls are nonwalkable - - if (tile == 50) +bool Penetration::isWalkable(int16 x, int16 y) const { + if ((x < 0) || (x >= kMapWidth) || (y < 0) || (y >= kMapHeight)) return false; - return true; + return _walkMap[y * kMapWidth + x]; } void Penetration::handleSub(int16 key) { @@ -501,19 +499,19 @@ void Penetration::subMove(int x, int y, Submarine::Direction direction) { // Limit the movement to walkable tiles int16 minX = 0; - if ((_sub->x > 0) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x - 1)])) + if (!isWalkable(_sub->x - 1, _sub->y)) minX = _sub->x * kMapTileWidth; int16 maxX = kMapWidth * kMapTileWidth; - if ((_sub->x < (kMapWidth - 1)) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x + 1)])) + if (!isWalkable(_sub->x + 1, _sub->y)) maxX = _sub->x * kMapTileWidth; int16 minY = 0; - if ((_sub->y > 0) && !isWalkable(_mapTiles[(_sub->y - 1) * kMapWidth + _sub->x])) + if (!isWalkable(_sub->x, _sub->y - 1)) minY = _sub->y * kMapTileHeight; int16 maxY = kMapHeight * kMapTileHeight; - if ((_sub->y < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_sub->y + 1) * kMapWidth + _sub->x])) + if (!isWalkable(_sub->x, _sub->y + 1)) maxY = _sub->y * kMapTileHeight; _sub->mapX = CLIP(_sub->mapX + x, minX, maxX); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 0582b99e83..a5740382c6 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -110,10 +110,11 @@ private: uint8 _floor; Surface *_map; - byte _mapTiles[kMapWidth * kMapHeight]; + bool _walkMap[kMapWidth * kMapHeight]; ManagedSub *_sub; + Common::List _exits; Common::List _shields; Common::List _mouths; @@ -126,6 +127,7 @@ private: void init(); void deinit(); + void clearMap(); void createMap(); void initScreen(); @@ -138,7 +140,7 @@ private: void subMove(int x, int y, Submarine::Direction direction); void subShoot(); - bool isWalkable(byte tile) const; + bool isWalkable(int16 x, int16 y) const; void checkShields(); void checkMouths(); -- cgit v1.2.3 From 04d0ec8d03d46f59f950929321fef43b52ea740a Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 03:27:40 +0200 Subject: GOB: Implement exiting floors --- engines/gob/minigames/geisha/penetration.cpp | 47 +++++++++++++++++++++++----- engines/gob/minigames/geisha/penetration.h | 4 +++ engines/gob/minigames/geisha/submarine.cpp | 9 +++--- engines/gob/minigames/geisha/submarine.h | 3 ++ 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 22cb06fed8..856c063edf 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -263,6 +263,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Handle the sub movement handleSub(key); + + checkExited(); } deinit(); @@ -276,6 +278,7 @@ void Penetration::init() { _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); + _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); _background->clear(); @@ -296,11 +299,6 @@ void Penetration::init() { _floor = 0; createMap(); - - for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) - _mapAnims.push_back(m->mouth); - - _anims.push_back(_sub->sub); } void Penetration::deinit() { @@ -308,6 +306,7 @@ void Penetration::deinit() { _soundBite.free(); _soundKiss.free(); _soundShoot.free(); + _soundExit.free(); clearMap(); @@ -443,7 +442,12 @@ void Penetration::createMap() { } if (!_sub) - error("Geisha: No starting position in floor %d (testmode: %d", _floor, _testMode); + error("Geisha: No starting position in floor %d (testmode: %d)", _floor, _testMode); + + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) + _mapAnims.push_back(m->mouth); + + _anims.push_back(_sub->sub); } void Penetration::initScreen() { @@ -525,6 +529,7 @@ void Penetration::subMove(int x, int y, Submarine::Direction direction) { checkShields(); checkMouths(); + checkExits(); } void Penetration::subShoot() { @@ -578,6 +583,23 @@ void Penetration::checkMouths() { } } +void Penetration::checkExits() { + if (!_sub->sub->canMove()) + return; + + for (Common::List::iterator e = _exits.begin(); e != _exits.end(); ++e) { + if ((e->x == _sub->x) && (e->y == _sub->y)) { + _sub->mapX = e->x * kMapTileWidth; + _sub->mapY = e->y * kMapTileHeight; + + _sub->sub->leave(); + + _vm->_sound->blasterPlay(&_soundExit, 1, 0); + break; + } + } +} + void Penetration::healthGain(int amount) { if (_shieldMeter->getValue() > 0) _healthMeter->increase(_shieldMeter->increase(amount)); @@ -592,12 +614,23 @@ void Penetration::healthLose(int amount) { _sub->sub->die(); } +void Penetration::checkExited() { + if (_sub->sub->hasExited()) { + _floor++; + + if (_floor >= kFloorCount) + return; + + createMap(); + } +} + bool Penetration::isDead() const { return _sub && _sub->sub->isDead(); } bool Penetration::hasWon() const { - return _floor > kFloorCount; + return _floor >= kFloorCount; } void Penetration::updateAnims() { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index a5740382c6..f717e7219b 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -122,6 +122,7 @@ private: SoundDesc _soundBite; SoundDesc _soundKiss; SoundDesc _soundShoot; + SoundDesc _soundExit; void init(); @@ -142,12 +143,15 @@ private: bool isWalkable(int16 x, int16 y) const; + void checkExits(); void checkShields(); void checkMouths(); void healthGain(int amount); void healthLose(int amount); + void checkExited(); + bool isDead() const; bool hasWon() const; }; diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index 4a18c6e043..0f3f936ea6 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -109,12 +109,9 @@ void Submarine::advance() { break; case kStateExit: - if (isPaused()) { + if (isPaused()) _state = kStateExited; - setVisible(true); - } - break; case kStateDie: @@ -135,6 +132,10 @@ bool Submarine::isDead() const { return _state == kStateDead; } +bool Submarine::hasExited() const { + return _state == kStateExited; +} + uint16 Submarine::directionToMove(Direction direction) const { switch (direction) { case kDirectionN: diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index e8ae72d996..d14e4e953b 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -67,6 +67,9 @@ public: /** Is the submarine dead? */ bool isDead() const; + /** Has the submarine finished exiting the level? */ + bool hasExited() const; + private: enum State { kStateNone = 0, -- cgit v1.2.3 From 78c9c72691957ea8c6ed823b76b67a1c0e1d9a93 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 16:50:22 +0200 Subject: GOB: Set Penetration floor palettes and fade in/out --- engines/gob/minigames/geisha/penetration.cpp | 106 +++++++++++++++++++++------ engines/gob/minigames/geisha/penetration.h | 8 ++ 2 files changed, 90 insertions(+), 24 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 856c063edf..6d18a230a8 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -22,6 +22,7 @@ #include "gob/global.h" #include "gob/util.h" +#include "gob/palanim.h" #include "gob/draw.h" #include "gob/video.h" #include "gob/decfile.h" @@ -39,25 +40,6 @@ namespace Gob { namespace Geisha { -static const byte kPalette[48] = { - 0x16, 0x16, 0x16, - 0x12, 0x14, 0x16, - 0x34, 0x00, 0x25, - 0x1D, 0x1F, 0x22, - 0x24, 0x27, 0x2A, - 0x2C, 0x0D, 0x22, - 0x2B, 0x2E, 0x32, - 0x12, 0x09, 0x20, - 0x3D, 0x3F, 0x00, - 0x3F, 0x3F, 0x3F, - 0x00, 0x00, 0x00, - 0x15, 0x15, 0x3F, - 0x25, 0x22, 0x2F, - 0x1A, 0x14, 0x28, - 0x3F, 0x00, 0x00, - 0x15, 0x3F, 0x15 -}; - static const int kColorShield = 11; static const int kColorHealth = 15; static const int kColorBlack = 10; @@ -88,6 +70,63 @@ static const int kPlayAreaHeight = 113; static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2; static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2; +const byte Penetration::kPalettes[kFloorCount][3 * kPaletteSize] = { + { + 0x16, 0x16, 0x16, + 0x12, 0x14, 0x16, + 0x34, 0x00, 0x25, + 0x1D, 0x1F, 0x22, + 0x24, 0x27, 0x2A, + 0x2C, 0x0D, 0x22, + 0x2B, 0x2E, 0x32, + 0x12, 0x09, 0x20, + 0x3D, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x25, 0x22, 0x2F, + 0x1A, 0x14, 0x28, + 0x3F, 0x00, 0x00, + 0x15, 0x3F, 0x15 + }, + { + 0x16, 0x16, 0x16, + 0x12, 0x14, 0x16, + 0x37, 0x00, 0x24, + 0x1D, 0x1F, 0x22, + 0x24, 0x27, 0x2A, + 0x30, 0x0E, 0x16, + 0x2B, 0x2E, 0x32, + 0x22, 0x0E, 0x26, + 0x3D, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x36, 0x28, 0x36, + 0x30, 0x1E, 0x2A, + 0x3F, 0x00, 0x00, + 0x15, 0x3F, 0x15 + }, + { + 0x16, 0x16, 0x16, + 0x12, 0x14, 0x16, + 0x3F, 0x14, 0x22, + 0x1D, 0x1F, 0x22, + 0x24, 0x27, 0x2A, + 0x30, 0x10, 0x10, + 0x2B, 0x2E, 0x32, + 0x2A, 0x12, 0x12, + 0x3D, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x3F, 0x23, 0x31, + 0x39, 0x20, 0x2A, + 0x3F, 0x00, 0x00, + 0x15, 0x3F, 0x15 + } +}; + const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = { { { // Real mode, floor 0 @@ -246,8 +285,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { while (!_vm->shouldQuit() && !isDead() && !hasWon()) { updateAnims(); - // Draw and wait for the end of the frame + // Draw, fade in if necessary and wait for the end of the frame _vm->_draw->blitInvalidated(); + fadeIn(); _vm->_util->waitEndFrame(); // Handle input @@ -450,13 +490,30 @@ void Penetration::createMap() { _anims.push_back(_sub->sub); } +void Penetration::fadeIn() { + if (!_needFadeIn) + return; + + // Fade to palette + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + _needFadeIn = false; +} + +void Penetration::setPalette() { + // Fade to black + _vm->_palAnim->fade(0, 0, 0); + + // Set palette + memcpy(_vm->_draw->_vgaPalette , kPalettes[_floor], 3 * kPaletteSize); + memcpy(_vm->_draw->_vgaSmallPalette, kPalettes[_floor], 3 * kPaletteSize); + + _needFadeIn = true; +} + void Penetration::initScreen() { _vm->_util->setFrameRate(15); - memcpy(_vm->_draw->_vgaPalette , kPalette, 48); - memcpy(_vm->_draw->_vgaSmallPalette, kPalette, 48); - - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + setPalette(); // Draw the shield meter _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame @@ -621,6 +678,7 @@ void Penetration::checkExited() { if (_floor >= kFloorCount) return; + setPalette(); createMap(); } } diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index f717e7219b..f19e186d82 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -57,6 +57,9 @@ private: static const int kMapWidth = 17; static const int kMapHeight = 13; + static const int kPaletteSize = 16; + + static const byte kPalettes[kFloorCount][3 * kPaletteSize]; static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; struct Position { @@ -97,6 +100,8 @@ private: bool _hasMaxEnergy; bool _testMode; + bool _needFadeIn; + Surface *_background; CMPFile *_sprites; ANIFile *_objects; @@ -133,6 +138,9 @@ private: void initScreen(); + void setPalette(); + void fadeIn(); + void updateAnims(); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); -- cgit v1.2.3 From 5913b9b839edc2a2bb6caecaee3336bd4de5a673 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 19:03:23 +0200 Subject: GOB: Draw info texts in Penetration The German strings have been changed from the original, to fix the horribly broken German. Someone should probably check the Italian and Spanish strings too. --- engines/gob/minigames/geisha/penetration.cpp | 219 ++++++++++++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 5 + 2 files changed, 220 insertions(+), 4 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 6d18a230a8..8fe75b083e 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -40,10 +40,12 @@ namespace Gob { namespace Geisha { -static const int kColorShield = 11; -static const int kColorHealth = 15; -static const int kColorBlack = 10; -static const int kColorFloor = 13; +static const int kColorShield = 11; +static const int kColorHealth = 15; +static const int kColorBlack = 10; +static const int kColorFloor = 13; +static const int kColorFloorText = 14; +static const int kColorExitText = 15; enum Sprite { kSpriteFloorShield = 25, @@ -70,6 +72,13 @@ static const int kPlayAreaHeight = 113; static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2; static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2; +static const int kTextAreaLeft = 9; +static const int kTextAreaTop = 7; +static const int kTextAreaRight = 104; +static const int kTextAreaBottom = 107; + +static const int kTextAreaBigBottom = 142; + const byte Penetration::kPalettes[kFloorCount][3 * kPaletteSize] = { { 0x16, 0x16, 0x16, @@ -224,6 +233,122 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = } }; +static const int kLanguageCount = 5; +static const int kFallbackLanguage = 2; // English + +enum String { + kString3rdBasement = 0, + kString2ndBasement, + kString1stBasement, + kStringNoExit, + kStringYouHave, + kString2Exits, + kString1Exit, + kStringToReach, + kStringUpperLevel1, + kStringUpperLevel2, + kStringLevel0, + kStringPenetration, + kStringSuccessful, + kStringDanger, + kStringGynoides, + kStringActivated, + kStringCount +}; + +static const char *kStrings[kLanguageCount][kStringCount] = { + { // French + "3EME SOUS-SOL", + "2EME SOUS-SOL", + "1ER SOUS-SOL", + "SORTIE REFUSEE", + "Vous disposez", + "de deux sorties", + "d\'une sortie", + "pour l\'acc\212s au", + "niveau", + "sup\202rieur", + "- NIVEAU 0 -", + "PENETRATION", + "REUSSIE", + "DANGER", + "GYNOIDES", + "ACTIVEES" + }, + { // German + // NOTE: The original had very broken German there. We provide proper(ish) German instead. + "3. UNTERGESCHOSS", + "2. UNTERGESCHOSS", + "1. UNTERGESCHOSS", + "AUSGANG GESPERRT", + "Sie haben", + "zwei Ausg\204nge", + "einen Ausgang", + "um das obere", + "Stockwerk zu", + "erreichen", + "- STOCKWERK 0 -", + "PENETRATION", + "ERFOLGREICH", + "GEFAHR", + "GYNOIDE", + "AKTIVIERT", + }, + { // English + "3RD BASEMENT", + "2ND BASEMENT", + "1ST BASEMENT", + "NO EXIT", + "You have", + "2 exits", + "1 exit", + "to reach upper", + "level", + "", + "- 0 LEVEL -", + "PENETRATION", + "SUCCESSFUL", + "DANGER", + "GYNOIDES", + "ACTIVATED", + }, + { // Spanish + "3ER. SUBSUELO", + "2D. SUBSUELO", + "1ER. SUBSUELO", + "SALIDA RECHAZADA", + "Dispones", + "de dos salidas", + "de una salida", + "para acceso al", + "nivel", + "superior", + "- NIVEL 0 -", + "PENETRACION", + "CONSEGUIDA", + "PELIGRO", + "GYNOIDAS", + "ACTIVADAS", + }, + { // Italian + "SOTTOSUOLO 3", + "SOTTOSUOLO 2", + "SOTTOSUOLO 1", + "NON USCITA", + "avete", + "due uscite", + "un\' uscita", + "per accedere al", + "livello", + "superiore", + "- LIVELLO 0 -", + "PENETRAZIONE", + "RIUSCITA", + "PERICOLO", + "GYNOIDI", + "ATTIVATE", + } +}; Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { } @@ -279,6 +404,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { init(); initScreen(); + drawFloorText(); + _vm->_draw->blitInvalidated(); _vm->_video->retrace(); @@ -308,6 +435,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { } deinit(); + drawEndText(); return hasWon(); } @@ -490,6 +618,81 @@ void Penetration::createMap() { _anims.push_back(_sub->sub); } +void Penetration::drawFloorText() { + _vm->_draw->_backSurface->fillRect(kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBottom, kColorBlack); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBottom); + + const Font *font = _vm->_draw->_fonts[2]; + if (!font) + return; + + const char **strings = kStrings[getLanguage()]; + + const char *floorString = 0; + if (_floor == 0) + floorString = strings[kString3rdBasement]; + else if (_floor == 1) + floorString = strings[kString2ndBasement]; + else if (_floor == 2) + floorString = strings[kString1stBasement]; + + if (floorString) + _vm->_draw->drawString(floorString, 10, 15, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + if (_exits.size() > 0) { + int exitCount = kString2Exits; + if (_exits.size() == 1) + exitCount = kString1Exit; + + _vm->_draw->drawString(strings[kStringYouHave] , 10, 38, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[exitCount] , 10, 53, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringToReach] , 10, 68, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringUpperLevel1], 10, 84, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringUpperLevel2], 10, 98, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + } else + _vm->_draw->drawString(strings[kStringNoExit], 10, 53, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); +} + +void Penetration::drawEndText() { + // Only draw the end text when we've won and this isn't a test run + if (!hasWon() || _testMode) + return; + + _vm->_draw->_backSurface->fillRect(kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBigBottom, kColorBlack); + + const Font *font = _vm->_draw->_fonts[2]; + if (!font) + return; + + const char **strings = kStrings[getLanguage()]; + + _vm->_draw->drawString(strings[kStringLevel0] , 11, 21, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringPenetration], 11, 42, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringSuccessful] , 11, 58, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + _vm->_draw->drawString(strings[kStringDanger] , 11, 82, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringGynoides] , 11, 98, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringActivated], 11, 113, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBigBottom); + _vm->_draw->blitInvalidated(); + _vm->_video->retrace(); +} + void Penetration::fadeIn() { if (!_needFadeIn) return; @@ -680,6 +883,7 @@ void Penetration::checkExited() { setPalette(); createMap(); + drawFloorText(); } } @@ -691,6 +895,13 @@ bool Penetration::hasWon() const { return _floor >= kFloorCount; } +int Penetration::getLanguage() const { + if (_vm->_global->_language < kLanguageCount) + return _vm->_global->_language; + + return kFallbackLanguage; +} + void Penetration::updateAnims() { int16 left = 0, top = 0, right = 0, bottom = 0; diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index f19e186d82..3f03bfaf38 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -141,6 +141,9 @@ private: void setPalette(); void fadeIn(); + void drawFloorText(); + void drawEndText(); + void updateAnims(); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); @@ -162,6 +165,8 @@ private: bool isDead() const; bool hasWon() const; + + int getLanguage() const; }; } // End of namespace Geisha -- cgit v1.2.3 From 4288edd5236cb0c232dea0bd818779539e9bc6f2 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 19:21:21 +0200 Subject: GOB: Add the original broken German as comments --- engines/gob/minigames/geisha/penetration.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 8fe75b083e..1bcc42a329 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -277,19 +277,20 @@ static const char *kStrings[kLanguageCount][kStringCount] = { }, { // German // NOTE: The original had very broken German there. We provide proper(ish) German instead. - "3. UNTERGESCHOSS", - "2. UNTERGESCHOSS", - "1. UNTERGESCHOSS", + // B0rken text in the comments after each line + "3. UNTERGESCHOSS", // "3. U.-GESCHOSS"" + "2. UNTERGESCHOSS", // "2. U.-GESCHOSS" + "1. UNTERGESCHOSS", // "1. U.-GESCHOSS" "AUSGANG GESPERRT", "Sie haben", - "zwei Ausg\204nge", - "einen Ausgang", - "um das obere", - "Stockwerk zu", - "erreichen", - "- STOCKWERK 0 -", - "PENETRATION", - "ERFOLGREICH", + "zwei Ausg\204nge", // "zwei Ausgang" + "einen Ausgang", // "Fortsetztung" + "um das obere", // "" + "Stockwerk zu", // "" + "erreichen", // "" + "- STOCKWERK 0 -", // "0 - HOHE" + "PENETRATION", // "DURCHDRIGEN" + "ERFOLGREICH", // "ERFOLG" "GEFAHR", "GYNOIDE", "AKTIVIERT", -- cgit v1.2.3 From 8c3d2fc7410ab3f55735f6a78dadbeec23c59b6c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 00:21:54 +0200 Subject: GOB: Add a way to reopen currently opened IMD/VMD videos This is a workaround for how Lost in Time behaves in combination with changes I made to the DataIO code for running Urban Runner on low-memory devices. Urban Runner's intro are far to big to have them copied into memory for these devices, so I made the DataIO code return a SafeSeekableSubReadStream into the opened archive stream instead. Unfortunately, Lost in Time might not close a video file when it closes the data file which it was originally in, especially when loading a saved game. Since the video player needs to be able to gaplessly continue a video and there does not, by itself, close the video if not requested by the scripts, this leads to reading out of an already closed stream in certain cases. So, to worka round this issues, the video player tries to reopen each currently opened video after a data archive was closed, to make sure that that video is still available. If not, the video is closed. --- engines/gob/inter_v1.cpp | 9 ++++++-- engines/gob/inter_v2.cpp | 4 ++++ engines/gob/videoplayer.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++ engines/gob/videoplayer.h | 7 +++++++ video/coktel_decoder.cpp | 45 ++++++++++++++++++++++++++++++++++++++++ video/coktel_decoder.h | 9 ++++++++ 6 files changed, 122 insertions(+), 2 deletions(-) diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 9aa190a456..4aa54f720b 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1744,10 +1744,15 @@ void Inter_v1::o1_writeData(OpFuncParams ¶ms) { void Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { Common::String file = _vm->_game->_script->evalString(); - if (!file.empty()) + if (!file.empty()) { _vm->_dataIO->openArchive(file, true); - else + } else { _vm->_dataIO->closeArchive(true); + + // NOTE: Lost in Time might close a data file without explicitely closing a video in it. + // So we make sure that all open videos are still available. + _vm->_vidPlayer->reopenAll(); + } } void Inter_v1::o1_setState(OpGobParams ¶ms) { diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 1e5b7bb24c..54f6a1acc1 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1002,6 +1002,10 @@ void Inter_v2::o2_openItk() { void Inter_v2::o2_closeItk() { _vm->_dataIO->closeArchive(false); + + // NOTE: Lost in Time might close a data file without explicitely closing a video in it. + // So we make sure that all open videos are still available. + _vm->_vidPlayer->reopenAll(); } void Inter_v2::o2_setImdFrontSurf() { diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 221f5ab3c9..a478492ccc 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -234,6 +234,23 @@ void VideoPlayer::closeAll() { closeVideo(i); } +bool VideoPlayer::reopenVideo(int slot) { + Video *video = getVideoBySlot(slot); + if (!video) + return true; + + return reopenVideo(*video); +} + +bool VideoPlayer::reopenAll() { + bool all = true; + for (int i = 0; i < kVideoSlotCount; i++) + if (!reopenVideo(i)) + all = false; + + return all; +} + void VideoPlayer::pauseVideo(int slot, bool pause) { Video *video = getVideoBySlot(slot); if (!video || !video->decoder) @@ -850,6 +867,39 @@ Common::String VideoPlayer::findFile(const Common::String &file, Properties &pro return video; } +bool VideoPlayer::reopenVideo(Video &video) { + if (video.isEmpty()) + return true; + + if (video.fileName.empty()) { + video.close(); + return false; + } + + Properties properties; + + properties.type = video.properties.type; + + Common::String fileName = findFile(video.fileName, properties); + if (fileName.empty()) { + video.close(); + return false; + } + + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); + if (!stream) { + video.close(); + return false; + } + + if (!video.decoder->reloadStream(stream)) { + delete stream; + return false; + } + + return true; +} + void VideoPlayer::copyPalette(const Video &video, int16 palStart, int16 palEnd) { if (!video.decoder->hasPalette() || !video.decoder->isPaletted()) return; diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index bc7cb48768..129ccef67a 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -110,6 +110,9 @@ public: void closeLiveSound(); void closeAll(); + bool reopenVideo(int slot = 0); + bool reopenAll(); + void pauseVideo(int slot, bool pause); void pauseAll(bool pause); @@ -163,6 +166,8 @@ private: bool isEmpty() const; void close(); + + void reopen(); }; static const int kVideoSlotCount = 32; @@ -188,6 +193,8 @@ private: ::Video::CoktelDecoder *openVideo(const Common::String &file, Properties &properties); + bool reopenVideo(Video &video); + bool playFrame(int slot, Properties &properties); void checkAbort(Video &video, Properties &properties); diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp index be36874db4..0c7ade1b8a 100644 --- a/video/coktel_decoder.cpp +++ b/video/coktel_decoder.cpp @@ -646,6 +646,21 @@ PreIMDDecoder::~PreIMDDecoder() { close(); } +bool PreIMDDecoder::reloadStream(Common::SeekableReadStream *stream) { + if (!_stream) + return false; + + if (!stream->seek(_stream->pos())) { + close(); + return false; + } + + delete _stream; + _stream = stream; + + return true; +} + bool PreIMDDecoder::seek(int32 frame, int whence, bool restart) { if (!evaluateSeekFrame(frame, whence)) return false; @@ -840,6 +855,21 @@ IMDDecoder::~IMDDecoder() { close(); } +bool IMDDecoder::reloadStream(Common::SeekableReadStream *stream) { + if (!_stream) + return false; + + if (!stream->seek(_stream->pos())) { + close(); + return false; + } + + delete _stream; + _stream = stream; + + return true; +} + bool IMDDecoder::seek(int32 frame, int whence, bool restart) { if (!evaluateSeekFrame(frame, whence)) return false; @@ -1536,6 +1566,21 @@ VMDDecoder::~VMDDecoder() { close(); } +bool VMDDecoder::reloadStream(Common::SeekableReadStream *stream) { + if (!_stream) + return false; + + if (!stream->seek(_stream->pos())) { + close(); + return false; + } + + delete _stream; + _stream = stream; + + return true; +} + bool VMDDecoder::seek(int32 frame, int whence, bool restart) { if (!evaluateSeekFrame(frame, whence)) return false; diff --git a/video/coktel_decoder.h b/video/coktel_decoder.h index 68696d5ff3..c88d982191 100644 --- a/video/coktel_decoder.h +++ b/video/coktel_decoder.h @@ -79,6 +79,9 @@ public: Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); ~CoktelDecoder(); + /** Replace the current video stream with this identical one. */ + virtual bool reloadStream(Common::SeekableReadStream *stream) = 0; + virtual bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) = 0; /** Draw directly onto the specified video memory. */ @@ -237,6 +240,8 @@ public: Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); ~PreIMDDecoder(); + bool reloadStream(Common::SeekableReadStream *stream); + bool seek(int32 frame, int whence = SEEK_SET, bool restart = false); @@ -268,6 +273,8 @@ public: IMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); ~IMDDecoder(); + bool reloadStream(Common::SeekableReadStream *stream); + bool seek(int32 frame, int whence = SEEK_SET, bool restart = false); void setXY(uint16 x, uint16 y); @@ -364,6 +371,8 @@ public: VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); ~VMDDecoder(); + bool reloadStream(Common::SeekableReadStream *stream); + bool seek(int32 frame, int whence = SEEK_SET, bool restart = false); void setXY(uint16 x, uint16 y); -- cgit v1.2.3 From f3fba318466d8afdfe14d42e4ef9f1902375166d Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Wed, 6 Jun 2012 21:46:25 -0400 Subject: SCUMM: Implement football2002 u32 opcode 1028 Scoreboard transitions now play --- engines/scumm/he/logic/football.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp index f86f97eaf7..5a0d423508 100644 --- a/engines/scumm/he/logic/football.cpp +++ b/engines/scumm/he/logic/football.cpp @@ -45,6 +45,7 @@ private: int op_1022(int32 *args); int op_1023(int32 *args); int op_1024(int32 *args); + int op_1028(); }; int LogicHEfootball::versionID() { @@ -83,6 +84,11 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) { res = op_1024(args); break; + case 1028: + // Backyard Football 2002 only + res = op_1028(); + break; + case 8221968: // Someone had a fun and used his birthday as opcode number res = getFromArray(args[0], args[1], args[2]); @@ -281,6 +287,12 @@ int LogicHEfootball::op_1024(int32 *args) { return 1; } +int LogicHEfootball::op_1028() { + // Backyard Football 2002 only + writeScummVar(108, 100000000); + return 1; +} + LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm) { return new LogicHEfootball(vm); } -- cgit v1.2.3 From 95454ab52c3e8f251b08aa62b18f071374de85b9 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 04:02:42 +0200 Subject: GOB: Better controls in Geisha's Penetration You can actually move diagonally now --- engines/gob/minigames/geisha/penetration.cpp | 103 ++++++++++++++++++++------- engines/gob/minigames/geisha/penetration.h | 18 ++++- engines/gob/minigames/geisha/submarine.cpp | 2 +- engines/gob/minigames/geisha/submarine.h | 1 + 4 files changed, 96 insertions(+), 28 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 1bcc42a329..72c53cb5c3 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -20,6 +20,8 @@ * */ +#include "common/events.h" + #include "gob/global.h" #include "gob/util.h" #include "gob/palanim.h" @@ -410,7 +412,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_draw->blitInvalidated(); _vm->_video->retrace(); - while (!_vm->shouldQuit() && !isDead() && !hasWon()) { + while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) { updateAnims(); // Draw, fade in if necessary and wait for the end of the frame @@ -418,19 +420,11 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { fadeIn(); _vm->_util->waitEndFrame(); - // Handle input - _vm->_util->processInput(); - - int16 mouseX, mouseY; - MouseButtons mouseButtons; - - int16 key = checkInput(mouseX, mouseY, mouseButtons); - // Aborting the game - if (key == kKeyEscape) - break; + // Handle the input + checkInput(); // Handle the sub movement - handleSub(key); + handleSub(); checkExited(); } @@ -449,6 +443,10 @@ void Penetration::init() { _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); + _quit = false; + for (int i = 0; i < kKeyCount; i++) + _keys[i] = false; + _background->clear(); _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background); @@ -731,10 +729,44 @@ void Penetration::initScreen() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } -int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) { - _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons); +void Penetration::checkInput() { + Common::Event event; + Common::EventManager *eventMan = g_system->getEventManager(); + + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + _quit = true; + else if (event.kbd.keycode == Common::KEYCODE_UP) + _keys[kKeyUp ] = true; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keys[kKeyDown ] = true; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keys[kKeyLeft ] = true; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keys[kKeyRight] = true; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keys[kKeySpace] = true; + break; + + case Common::EVENT_KEYUP: + if (event.kbd.keycode == Common::KEYCODE_UP) + _keys[kKeyUp ] = false; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keys[kKeyDown ] = false; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keys[kKeyLeft ] = false; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keys[kKeyRight] = false; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keys[kKeySpace] = false; + break; - return _vm->_util->checkKey(); + default: + break; + } + } } bool Penetration::isWalkable(int16 x, int16 y) const { @@ -744,16 +776,13 @@ bool Penetration::isWalkable(int16 x, int16 y) const { return _walkMap[y * kMapWidth + x]; } -void Penetration::handleSub(int16 key) { - if (key == kKeyLeft) - subMove(-5, 0, Submarine::kDirectionW); - else if (key == kKeyRight) - subMove( 5, 0, Submarine::kDirectionE); - else if (key == kKeyUp) - subMove( 0, -5, Submarine::kDirectionN); - else if (key == kKeyDown) - subMove( 0, 5, Submarine::kDirectionS); - else if (key == kKeySpace) +void Penetration::handleSub() { + int x, y; + Submarine::Direction direction = getDirection(x, y); + + subMove(x, y, direction); + + if (_keys[kKeySpace]) subShoot(); } @@ -802,6 +831,30 @@ void Penetration::subShoot() { _vm->_sound->blasterPlay(&_soundShoot, 1, 0); } +Submarine::Direction Penetration::getDirection(int &x, int &y) const { + x = _keys[kKeyRight] ? 3 : (_keys[kKeyLeft] ? -3 : 0); + y = _keys[kKeyDown ] ? 3 : (_keys[kKeyUp ] ? -3 : 0); + + if ((x > 0) && (y > 0)) + return Submarine::kDirectionSE; + if ((x > 0) && (y < 0)) + return Submarine::kDirectionNE; + if ((x < 0) && (y > 0)) + return Submarine::kDirectionSW; + if ((x < 0) && (y < 0)) + return Submarine::kDirectionNW; + if (x > 0) + return Submarine::kDirectionE; + if (x < 0) + return Submarine::kDirectionW; + if (y > 0) + return Submarine::kDirectionS; + if (y < 0) + return Submarine::kDirectionN; + + return Submarine::kDirectionNone; +} + void Penetration::checkShields() { for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { if ((pos->x == _sub->x) && (pos->y == _sub->y)) { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 3f03bfaf38..0f36453017 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -94,6 +94,15 @@ private: void setPosition(uint16 pX, uint16 pY); }; + enum Keys { + kKeyUp = 0, + kKeyDown, + kKeyLeft, + kKeyRight, + kKeySpace, + kKeyCount + }; + GobEngine *_vm; bool _hasAccessPass; @@ -102,6 +111,9 @@ private: bool _needFadeIn; + bool _quit; + bool _keys[kKeyCount]; + Surface *_background; CMPFile *_sprites; ANIFile *_objects; @@ -146,12 +158,14 @@ private: void updateAnims(); - int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + void checkInput(); - void handleSub(int16 key); + void handleSub(); void subMove(int x, int y, Submarine::Direction direction); void subShoot(); + Submarine::Direction getDirection(int &x, int &y) const; + bool isWalkable(int16 x, int16 y) const; void checkExits(); diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index 0f3f936ea6..c61f49f22b 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -60,7 +60,7 @@ Submarine::~Submarine() { void Submarine::turn(Direction to) { // Nothing to do - if ((_state == kStateMove) && (_direction == to)) + if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to))) return; _state = kStateMove; diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index d14e4e953b..2455ef95c1 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -33,6 +33,7 @@ namespace Geisha { class Submarine : public ANIObject { public: enum Direction { + kDirectionNone, kDirectionN, kDirectionNE, kDirectionE, -- cgit v1.2.3 From 3d537e763c85bb3f16825c8b47894335568278a0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 04:20:41 +0200 Subject: GOB: Handle Penetration shooting animations more cleverly Still no bullets, though :P --- engines/gob/aniobject.cpp | 4 ++++ engines/gob/aniobject.h | 3 +++ engines/gob/minigames/geisha/penetration.cpp | 2 +- engines/gob/minigames/geisha/submarine.cpp | 27 +++++++++++++++++++++------ engines/gob/minigames/geisha/submarine.h | 5 +++++ 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index 54534cd60b..8d739fb3a4 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -76,6 +76,10 @@ void ANIObject::rewind() { _frame = 0; } +void ANIObject::setFrame(uint16 frame) { + _frame = frame % _ani->getAnimationInfo(_animation).frameCount; +} + void ANIObject::setPosition() { // CMP "animations" have no default position if (_cmp) diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index 5ea1f75401..00f42b43ce 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -84,6 +84,9 @@ public: /** Rewind the current animation to the first frame. */ void rewind(); + /** Set the animation to a specific frame. */ + void setFrame(uint16 frame); + /** Return the current animation number. */ uint16 getAnimation() const; /** Return the current frame number. */ diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 72c53cb5c3..e260d3cae2 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -823,7 +823,7 @@ void Penetration::subMove(int x, int y, Submarine::Direction direction) { } void Penetration::subShoot() { - if (!_sub->sub->canMove()) + if (!_sub->sub->canMove() || _sub->sub->isShooting()) return; _sub->sub->shoot(); diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index c61f49f22b..9c12a56a85 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -51,7 +51,7 @@ enum Animation { }; -Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateNone) { +Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) { turn(kDirectionN); } @@ -63,13 +63,21 @@ void Submarine::turn(Direction to) { if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to))) return; - _state = kStateMove; _direction = to; - setAnimation(directionToMove(_direction)); - setMode(kModeContinuous); + move(); +} + +void Submarine::move() { + uint16 frame = getFrame(); + uint16 anim = (_state == kStateShoot) ? directionToShoot(_direction) : directionToMove(_direction); + + setAnimation(anim); + setFrame(frame); setPause(false); setVisible(true); + + setMode((_state == kStateShoot) ? kModeOnce : kModeContinuous); } void Submarine::shoot() { @@ -104,8 +112,11 @@ void Submarine::advance() { switch (_state) { case kStateShoot: - if (isPaused()) - turn(_direction); + if (isPaused()) { + _state = kStateMove; + + move(); + } break; case kStateExit: @@ -132,6 +143,10 @@ bool Submarine::isDead() const { return _state == kStateDead; } +bool Submarine::isShooting() const { + return _state == kStateShoot; +} + bool Submarine::hasExited() const { return _state == kStateExited; } diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index 2455ef95c1..8a6d679bdd 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -68,6 +68,9 @@ public: /** Is the submarine dead? */ bool isDead() const; + /** Is the submarine shooting? */ + bool isShooting() const; + /** Has the submarine finished exiting the level? */ bool hasExited() const; @@ -91,6 +94,8 @@ private: uint16 directionToShoot(Direction direction) const; /** Map the directions to explode animation indices. */ uint16 directionToExplode(Direction direction) const; + + void move(); }; } // End of namespace Geisha -- cgit v1.2.3 From c37577a950f7337889d5c705c9bc67d434ed3670 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 04:29:10 +0200 Subject: GOB: Hook up the Penetration minigame in the cheater --- engines/gob/cheater.h | 6 ++++-- engines/gob/cheater_geisha.cpp | 11 +++++++++-- engines/gob/inter_geisha.cpp | 2 +- engines/gob/minigames/geisha/penetration.cpp | 18 +++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 5 +++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/engines/gob/cheater.h b/engines/gob/cheater.h index 334a5e88eb..bf6c1372fb 100644 --- a/engines/gob/cheater.h +++ b/engines/gob/cheater.h @@ -31,6 +31,7 @@ namespace Gob { namespace Geisha { class Diving; + class Penetration; } class GobEngine; @@ -48,13 +49,14 @@ protected: class Cheater_Geisha : public Cheater { public: - Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving); + Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving, Geisha::Penetration *penetration); ~Cheater_Geisha(); bool cheat(GUI::Debugger &console); private: - Geisha::Diving *_diving; + Geisha::Diving *_diving; + Geisha::Penetration *_penetration; }; } // End of namespace Gob diff --git a/engines/gob/cheater_geisha.cpp b/engines/gob/cheater_geisha.cpp index 3d8c56707d..567333c12f 100644 --- a/engines/gob/cheater_geisha.cpp +++ b/engines/gob/cheater_geisha.cpp @@ -27,11 +27,12 @@ #include "gob/inter.h" #include "gob/minigames/geisha/diving.h" +#include "gob/minigames/geisha/penetration.h" namespace Gob { -Cheater_Geisha::Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving) : - Cheater(vm), _diving(diving) { +Cheater_Geisha::Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving, Geisha::Penetration *penetration) : + Cheater(vm), _diving(diving), _penetration(penetration) { } @@ -45,6 +46,12 @@ bool Cheater_Geisha::cheat(GUI::Debugger &console) { return false; } + // A cheat to get around the Penetration minigame + if (_penetration->isPlaying()) { + _penetration->cheatWin(); + return false; + } + // A cheat to get around the mastermind puzzle if (_vm->isCurrentTot("hard.tot") && _vm->_inter->_variables) { uint32 digit1 = READ_VARO_UINT32(0x768); diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 99f834d4d7..75204a3f55 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -55,7 +55,7 @@ Inter_Geisha::Inter_Geisha(GobEngine *vm) : Inter_v1(vm), _diving = new Geisha::Diving(vm); _penetration = new Geisha::Penetration(vm); - _cheater = new Cheater_Geisha(vm, _diving); + _cheater = new Cheater_Geisha(vm, _diving, _penetration); _vm->_console->registerCheater(_cheater); } diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index e260d3cae2..9791757984 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -377,7 +377,7 @@ Penetration::ManagedSub::~ManagedSub() { Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), - _shieldMeter(0), _healthMeter(0), _floor(0) { + _shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) { _background = new Surface(320, 200, 1); @@ -404,6 +404,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _hasMaxEnergy = hasMaxEnergy; _testMode = testMode; + _isPlaying = true; + init(); initScreen(); @@ -432,9 +434,19 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { deinit(); drawEndText(); + _isPlaying = false; + return hasWon(); } +bool Penetration::isPlaying() const { + return _isPlaying; +} + +void Penetration::cheatWin() { + _floor = 3; +} + void Penetration::init() { // Load sounds _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); @@ -748,6 +760,10 @@ void Penetration::checkInput() { _keys[kKeyRight] = true; else if (event.kbd.keycode == Common::KEYCODE_SPACE) _keys[kKeySpace] = true; + else if (event.kbd.keycode == Common::KEYCODE_d) { + _vm->getDebugger()->attach(); + _vm->getDebugger()->onFrame(); + } break; case Common::EVENT_KEYUP: diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 0f36453017..0336ef8dcb 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -50,6 +50,9 @@ public: bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode); + bool isPlaying() const; + void cheatWin(); + private: static const int kModeCount = 2; static const int kFloorCount = 3; @@ -141,6 +144,8 @@ private: SoundDesc _soundShoot; SoundDesc _soundExit; + bool _isPlaying; + void init(); void deinit(); -- cgit v1.2.3 From e73f93e565fc0074da66429fd59db25114f84c12 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Thu, 7 Jun 2012 14:49:07 +1000 Subject: AGOS: Fix compiling AGOS game engine, when AGOS2 is disabled. --- engines/agos/charset-fontdata.cpp | 90 +++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/engines/agos/charset-fontdata.cpp b/engines/agos/charset-fontdata.cpp index 87f51cfad2..262ae44f01 100644 --- a/engines/agos/charset-fontdata.cpp +++ b/engines/agos/charset-fontdata.cpp @@ -681,6 +681,51 @@ static const byte feeble_windowFont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +void AGOSEngine_Feeble::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { + const byte *src; + byte color, *dst; + uint dstPitch, h, w, i; + + if (_noOracleScroll) + return; + + _videoLockOut |= 0x8000; + + dst = getBackGround(); + dstPitch = _backGroundBuf->pitch; + h = 13; + w = getFeebleFontSize(chr); + + if (_language == Common::PL_POL) { + if (!strcmp(getExtra(), "4CD")) + src = polish4CD_feeble_windowFont + (chr - 32) * 13; + else + src = polish2CD_feeble_windowFont + (chr - 32) * 13; + } else { + src = feeble_windowFont + (chr - 32) * 13; + } + dst += y * dstPitch + x + window->textColumnOffset; + + color = window->textColor; + + do { + int8 b = *src++; + i = 0; + do { + if (b < 0) { + if (dst[i] == 0) + dst[i] = color; + } + + b <<= 1; + } while (++i != w); + dst += dstPitch; + } while (--h); + + _videoLockOut &= ~0x8000; +} +#endif + static const byte english_simon1AGAFontData[] = { 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x20,0x10,0x40,0x88,0x30,0x40,0x00,0x88,0x20,0x00,0x00,0x50,0x20,0x00,0x00,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x50,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x30,0x00,0x10,0x20,0x48,0x10,0x20,0x00,0x48,0x20,0x40,0x00,0x90,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05, @@ -1253,51 +1298,6 @@ void AGOSEngine::renderString(uint vgaSpriteId, uint color, uint width, uint hei } } -void AGOSEngine_Feeble::windowDrawChar(WindowBlock *window, uint x, uint y, byte chr) { - const byte *src; - byte color, *dst; - uint dstPitch, h, w, i; - - if (_noOracleScroll) - return; - - _videoLockOut |= 0x8000; - - dst = getBackGround(); - dstPitch = _backGroundBuf->pitch; - h = 13; - w = getFeebleFontSize(chr); - - if (_language == Common::PL_POL) { - if (!strcmp(getExtra(), "4CD")) - src = polish4CD_feeble_windowFont + (chr - 32) * 13; - else - src = polish2CD_feeble_windowFont + (chr - 32) * 13; - } else { - src = feeble_windowFont + (chr - 32) * 13; - } - dst += y * dstPitch + x + window->textColumnOffset; - - color = window->textColor; - - do { - int8 b = *src++; - i = 0; - do { - if (b < 0) { - if (dst[i] == 0) - dst[i] = color; - } - - b <<= 1; - } while (++i != w); - dst += dstPitch; - } while (--h); - - _videoLockOut &= ~0x8000; -} -#endif - static const byte czech_simonFont[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, 0x70, 0x20, 0x20, 0x00, 0x20, 0x00, -- cgit v1.2.3 From dd558510dc60b61d9f960c7f49e8bc0327d8115b Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 7 Jun 2012 08:36:12 +0100 Subject: TOON: Move PathFindingHeap API to use int16 for x,y coordinates. The internal x,y point representation was already changed to int16 anyway, so this just harmonises this with the external API (and with Common::Point which uses int16). --- engines/toon/path.cpp | 12 +++++++----- engines/toon/path.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 2dd5fc45e2..540290d823 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -60,7 +60,7 @@ void PathFindingHeap::clear() { memset(_data, 0, sizeof(HeapDataGrid) * _size); } -void PathFindingHeap::push(int32 x, int32 y, int32 weight) { +void PathFindingHeap::push(int16 x, int16 y, int32 weight) { debugC(2, kDebugPath, "push(%d, %d, %d)", x, y, weight); if (_count == _size) { @@ -87,7 +87,7 @@ void PathFindingHeap::push(int32 x, int32 y, int32 weight) { int32 lMax = _count-1; int32 lT = 0; - while (1) { + while (true) { if (lMax <= 0) break; lT = (lMax-1) / 2; @@ -104,7 +104,7 @@ void PathFindingHeap::push(int32 x, int32 y, int32 weight) { } } -void PathFindingHeap::pop(int32 *x, int32 *y, int32 *weight) { +void PathFindingHeap::pop(int16 *x, int16 *y, int32 *weight) { debugC(2, kDebugPath, "pop(x, y, weight)"); if (!_count) { @@ -123,7 +123,7 @@ void PathFindingHeap::pop(int32 *x, int32 *y, int32 *weight) { int32 lMin = 0; int32 lT = 0; - while (1) { + while (true) { lT = (lMin << 1) + 1; if (lT < _count) { if (lT < _count-1) { @@ -315,7 +315,9 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { while (_heap->getCount()) { wei = 0; - _heap->pop(&curX, &curY, &curWeight); + int16 tempCurX, tempCurY; + _heap->pop(&tempCurX, &tempCurY, &curWeight); + curX = tempCurX, curY = tempCurY; // FIXME - Bodge to match heap->pop types int curNode = curX + curY * _width; int32 endX = MIN(curX + 1, _width - 1); diff --git a/engines/toon/path.h b/engines/toon/path.h index 2de58064f0..df2b2e94be 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -38,8 +38,8 @@ public: PathFindingHeap(); ~PathFindingHeap(); - void push(int32 x, int32 y, int32 weight); - void pop(int32 *x, int32 *y, int32 *weight); + void push(int16 x, int16 y, int32 weight); + void pop(int16 *x, int16 *y, int32 *weight); void init(int32 size); void clear(); void unload(); -- cgit v1.2.3 From de3f6a19ed6ca98ad152f5038c1db1f70f2c72ed Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 7 Jun 2012 11:26:32 +0300 Subject: SCI: Initial implementation of kScrollWindow, used in some SCI21 games This is used in LSL6 hires and SQ6. This initial implementation is hackish and only works in SQ6 (nothing is shown in LSL6) --- engines/sci/engine/kernel_tables.h | 2 +- engines/sci/engine/kgraphics32.cpp | 128 +++++++++++++++++-------------------- engines/sci/graphics/frameout.cpp | 45 +++++++++++++ engines/sci/graphics/frameout.h | 25 ++++++++ engines/sci/graphics/text32.cpp | 39 +++++++++-- engines/sci/graphics/text32.h | 6 +- 6 files changed, 169 insertions(+), 76 deletions(-) diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 4ddf0534ea..254a479e65 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -564,7 +564,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE, "rri", NULL, NULL }, { MAP_CALL(CelInfo), SIG_EVERYWHERE, "iiiiii", NULL, NULL }, { MAP_CALL(SetLanguage), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "io(.*)", NULL, NULL }, { MAP_CALL(SetFontRes), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(Font), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, { MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", NULL, NULL }, diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 2bb8288cb7..71c4949d65 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -308,103 +308,91 @@ reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) { } reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { - // Used by Phantasmagoria 1 and SQ6. In SQ6, it is used for the messages - // shown in the scroll window at the bottom of the screen. - - // TODO: This is all a stub/skeleton, thus we're invoking kStub() for now - kStub(s, argc, argv); - - switch (argv[0].toUint16()) { + // Used by SQ6 and LSL6 hires for the text area in the bottom of the + // screen. The relevant scripts also exist in Phantasmagoria 1, but they're + // unused. This is always called by scripts 64906 (ScrollerWindow) and + // 64907 (ScrollableWindow). + + reg_t kWindow = argv[1]; + uint16 op = argv[0].toUint16(); + switch (op) { case 0: // Init - // 2 parameters - // argv[1] points to the scroll object (e.g. textScroller in SQ6) - // argv[2] is an integer (e.g. 0x32) - break; - case 1: // Show message + g_sci->_gfxFrameout->initScrollText(argv[2].toUint16()); // maxItems + g_sci->_gfxFrameout->clearScrollTexts(); + return argv[1]; // kWindow + case 1: // Show message, called by ScrollableWindow::addString + case 14: // Modify message, called by ScrollableWindow::modifyString // 5 or 6 parameters // Seems to be called with 5 parameters when the narrator speaks, and // with 6 when Roger speaks - // argv[1] unknown (usually 0) - // argv[2] the text to show - // argv[3] a small integer (e.g. 0x32) - // argv[4] a small integer (e.g. 0x54) - // argv[5] optional, unknown (usually 0) - warning("kScrollWindow: '%s'", s->_segMan->getString(argv[2]).c_str()); - break; - case 2: // Clear - // 2 parameters - // TODO - break; - case 3: // Page up - // 2 parameters - // TODO - break; - case 4: // Page down - // 2 parameters - // TODO + { + Common::String text = s->_segMan->getString(argv[2]); + uint16 x = 0;//argv[3].toUint16(); // TODO: can't be x (values are all wrong) + uint16 y = 0;//argv[4].toUint16(); // TODO: can't be y (values are all wrong) + // TODO: argv[5] is an optional unknown parameter (an integer set to 0) + g_sci->_gfxFrameout->addScrollTextEntry(text, kWindow, x, y, (op == 14)); + } break; - case 5: // Up arrow - // 2 parameters - // TODO + case 2: // Clear, called by ScrollableWindow::erase + g_sci->_gfxFrameout->clearScrollTexts(); break; - case 6: // Down arrow - // 2 parameters + case 3: // Page up, called by ScrollableWindow::scrollTo // TODO + kStub(s, argc, argv); break; - case 7: // Home - // 2 parameters + case 4: // Page down, called by ScrollableWindow::scrollTo // TODO + kStub(s, argc, argv); break; - case 8: // End - // 2 parameters - // TODO + case 5: // Up arrow, called by ScrollableWindow::scrollTo + g_sci->_gfxFrameout->prevScrollText(); break; - case 9: // Resize - // 3 parameters - // TODO + case 6: // Down arrow, called by ScrollableWindow::scrollTo + g_sci->_gfxFrameout->nextScrollText(); break; - case 10: // Where - // 3 parameters - // TODO + case 7: // Home, called by ScrollableWindow::scrollTo + g_sci->_gfxFrameout->firstScrollText(); break; - case 11: // Go - // 4 parameters - // TODO + case 8: // End, called by ScrollableWindow::scrollTo + g_sci->_gfxFrameout->lastScrollText(); break; - case 12: // Insert - // 7 parameters + case 9: // Resize, called by ScrollableWindow::resize and ScrollerWindow::resize // TODO + kStub(s, argc, argv); break; - case 13: // Delete - // 3 parameters + case 10: // Where, called by ScrollableWindow::where // TODO + // argv[2] is an unknown integer + kStub(s, argc, argv); break; - case 14: // Modify - // 7 or 8 parameters + case 11: // Go, called by ScrollableWindow::scrollTo + // 2 extra parameters here // TODO + kStub(s, argc, argv); break; - case 15: // Hide - // 2 parameters + case 12: // Insert, called by ScrollableWindow::insertString + // 3 extra parameters here // TODO + kStub(s, argc, argv); break; - case 16: // Show - // 2 parameters - // TODO + // case 13 (Delete) is handled below + // case 14 (Modify) is handled above + case 15: // Hide, called by ScrollableWindow::hide + g_sci->_gfxFrameout->toggleScrollText(false); break; - case 17: // Destroy - // 2 parameters - // TODO + case 16: // Show, called by ScrollableWindow::show + g_sci->_gfxFrameout->toggleScrollText(true); break; - case 18: // Text - // 2 parameters - // TODO + case 17: // Destroy, called by ScrollableWindow::dispose + g_sci->_gfxFrameout->clearScrollTexts(); break; - case 19: // Reconstruct - // 3 parameters - // TODO + case 13: // Delete, unused + case 18: // Text, unused + case 19: // Reconstruct, unused + error("kScrollWindow: Unused subop %d invoked", op); break; default: - error("kScrollWindow: unknown subop %d", argv[0].toUint16()); + error("kScrollWindow: unknown subop %d", op); break; } diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 709a708d8b..450581000b 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -59,6 +59,9 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd _coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster; _scriptsRunningWidth = 320; _scriptsRunningHeight = 200; + _curScrollText = -1; + _showScrollText = false; + _maxScrollTexts = 0; } GfxFrameout::~GfxFrameout() { @@ -69,6 +72,46 @@ void GfxFrameout::clear() { deletePlaneItems(NULL_REG); _planes.clear(); deletePlanePictures(NULL_REG); + clearScrollTexts(); +} + +void GfxFrameout::clearScrollTexts() { + _scrollTexts.clear(); + _curScrollText = -1; +} + +void GfxFrameout::addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace) { + //reg_t bitmapHandle = g_sci->_gfxText32->createScrollTextBitmap(text, kWindow); + // HACK: We set the container dimensions manually + reg_t bitmapHandle = g_sci->_gfxText32->createScrollTextBitmap(text, kWindow, 480, 70); + ScrollTextEntry textEntry; + textEntry.bitmapHandle = bitmapHandle; + textEntry.kWindow = kWindow; + textEntry.x = x; + textEntry.y = y; + if (!replace || _scrollTexts.size() == 0) { + if (_scrollTexts.size() > _maxScrollTexts) { + _scrollTexts.remove_at(0); + _curScrollText--; + } + _scrollTexts.push_back(textEntry); + _curScrollText++; + } else { + _scrollTexts.pop_back(); + _scrollTexts.push_back(textEntry); + } +} + +void GfxFrameout::showCurrentScrollText() { + if (!_showScrollText || _curScrollText < 0) + return; + + uint16 size = (uint16)_scrollTexts.size(); + if (size > 0) { + assert(_curScrollText < size); + ScrollTextEntry textEntry = _scrollTexts[_curScrollText]; + g_sci->_gfxText32->drawScrollTextBitmap(textEntry.kWindow, textEntry.bitmapHandle, textEntry.x, textEntry.y); + } } void GfxFrameout::kernelAddPlane(reg_t object) { @@ -673,6 +716,8 @@ void GfxFrameout::kernelFrameout() { } } + showCurrentScrollText(); + _screen->copyToScreen(); g_sci->getEngineState()->_throttleTrigger = true; diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index ec4de62c0a..2d2ca6546c 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -76,6 +76,15 @@ struct PlanePictureEntry { typedef Common::List PlanePictureList; +struct ScrollTextEntry { + reg_t bitmapHandle; + reg_t kWindow; + uint16 x; + uint16 y; +}; + +typedef Common::Array ScrollTextList; + class GfxCache; class GfxCoordAdjuster32; class GfxPaint32; @@ -104,6 +113,18 @@ public: void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY = 0); void deletePlanePictures(reg_t object); void clear(); + + // Scroll text functions + void addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace); + void showCurrentScrollText(); + void initScrollText(uint16 maxItems) { _maxScrollTexts = maxItems; } + void clearScrollTexts(); + void firstScrollText() { if (_scrollTexts.size() > 0) _curScrollText = 0; } + void lastScrollText() { if (_scrollTexts.size() > 0) _curScrollText = _scrollTexts.size() - 1; } + void prevScrollText() { if (_curScrollText > 0) _curScrollText--; } + void nextScrollText() { if (_curScrollText + 1 < (uint16)_scrollTexts.size()) _curScrollText++; } + void toggleScrollText(bool show) { _showScrollText = show; } + void printPlaneList(Console *con); void printPlaneItemList(Console *con, reg_t planeObject); @@ -127,6 +148,10 @@ private: FrameoutList _screenItems; PlaneList _planes; PlanePictureList _planePictures; + ScrollTextList _scrollTexts; + int16 _curScrollText; + bool _showScrollText; + uint16 _maxScrollTexts; void sortPlanes(); diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index cd24ca5a99..8ac9582535 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -49,9 +49,12 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen) GfxText32::~GfxText32() { } +reg_t GfxText32::createScrollTextBitmap(Common::String text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) { + return createTextBitmapInternal(text, textObject, maxWidth, maxHeight, prevHunk); + +} reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) { reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text)); - // The object in the text selector of the item can be either a raw string // or a Str object. In the latter case, we need to access the object's data // selector to get the raw string. @@ -59,6 +62,11 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH stringObject = readSelector(_segMan, stringObject, SELECTOR(data)); Common::String text = _segMan->getString(stringObject); + + return createTextBitmapInternal(text, textObject, maxWidth, maxHeight, prevHunk); +} + +reg_t GfxText32::createTextBitmapInternal(Common::String &text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) { // HACK: The character offsets of the up and down arrow buttons are off by one // in GK1, for some unknown reason. Fix them here. if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) { @@ -91,7 +99,11 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH reg_t memoryId = NULL_REG; if (prevHunk.isNull()) { memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize); - writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); + + // Scroll text objects have no bitmap selector! + ObjVarRef varp; + if (lookupSelector(_segMan, textObject, SELECTOR(bitmap), &varp, NULL) == kSelectorVariable) + writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId); } else { memoryId = prevHunk; } @@ -175,6 +187,24 @@ void GfxText32::disposeTextBitmap(reg_t hunkId) { void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject) { reg_t hunkId = readSelector(_segMan, textObject, SELECTOR(bitmap)); + drawTextBitmapInternal(x, y, planeRect, textObject, hunkId); +} + +void GfxText32::drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, uint16 y) { + /*reg_t plane = readSelector(_segMan, textObject, SELECTOR(plane)); + Common::Rect planeRect; + planeRect.top = readSelectorValue(_segMan, plane, SELECTOR(top)); + planeRect.left = readSelectorValue(_segMan, plane, SELECTOR(left)); + planeRect.bottom = readSelectorValue(_segMan, plane, SELECTOR(bottom)); + planeRect.right = readSelectorValue(_segMan, plane, SELECTOR(right)); + + drawTextBitmapInternal(x, y, planeRect, textObject, hunkId);*/ + + // HACK: we pretty much ignore the plane rect and x, y... + drawTextBitmapInternal(0, 0, Common::Rect(20, 390, 600, 460), textObject, hunkId); +} + +void GfxText32::drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId) { uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back)); // Sanity check: Check if the hunk is set. If not, either the game scripts // didn't set it, or an old saved game has been loaded, where it wasn't set. @@ -188,8 +218,9 @@ void GfxText32::drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t t byte *memoryPtr = _segMan->getHunkPointer(hunkId); if (!memoryPtr) { - // Happens when restoring in some SCI32 games - warning("Attempt to draw an invalid text bitmap"); + // Happens when restoring in some SCI32 games (e.g. SQ6). + // Commented out to reduce console spam + //warning("Attempt to draw an invalid text bitmap"); return; } diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h index 3505de85eb..ce78003fdf 100644 --- a/engines/sci/graphics/text32.h +++ b/engines/sci/graphics/text32.h @@ -33,13 +33,17 @@ public: GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen); ~GfxText32(); reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG); - void disposeTextBitmap(reg_t hunkId); + reg_t createScrollTextBitmap(Common::String text, reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG); void drawTextBitmap(int16 x, int16 y, Common::Rect planeRect, reg_t textObject); + void drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, uint16 y); + void disposeTextBitmap(reg_t hunkId); int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font); void kernelTextSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); private: + reg_t createTextBitmapInternal(Common::String &text, reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t hunkId); + void drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId); int16 Size(Common::Rect &rect, const char *text, GuiResourceId fontId, int16 maxWidth); void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight, bool restoreFont); void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); -- cgit v1.2.3 From 8deb8b3d42927d1d6e73350f96353eda1b10a1fc Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 7 Jun 2012 12:33:13 +0100 Subject: TOON: Minor cleanup and formatting fixes to Pathfinding class. --- engines/toon/path.cpp | 51 +++++++++++++++++++++++---------------------------- engines/toon/path.h | 7 ++++--- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 540290d823..101778d4b4 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -161,6 +161,18 @@ PathFinding::~PathFinding(void) { delete[] _gridTemp; } +void PathFinding::init(Picture *mask) { + debugC(1, kDebugPath, "init(mask)"); + + _width = mask->getWidth(); + _height = mask->getHeight(); + _currentMask = mask; + _heap->unload(); + _heap->init(500); + delete[] _gridTemp; + _gridTemp = new int32[_width * _height]; +} + bool PathFinding::isLikelyWalkable(int32 x, int32 y) { for (int32 i = 0; i < _numBlockingRects; i++) { if (_blockingRects[i][4] == 0) { @@ -180,12 +192,10 @@ bool PathFinding::isLikelyWalkable(int32 x, int32 y) { bool PathFinding::isWalkable(int32 x, int32 y) { debugC(2, kDebugPath, "isWalkable(%d, %d)", x, y); - bool maskWalk = (_currentMask->getData(x, y) & 0x1f) > 0; - - return maskWalk; + return (_currentMask->getData(x, y) & 0x1f) > 0; } -int32 PathFinding::findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 *fyy, int origX, int origY) { +bool PathFinding::findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 *fyy, int origX, int origY) { debugC(1, kDebugPath, "findClosestWalkingPoint(%d, %d, fxx, fyy, %d, %d)", xx, yy, origX, origY); int32 currentFound = -1; @@ -214,11 +224,11 @@ int32 PathFinding::findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 if (currentFound != -1) { *fxx = currentFound % _width; *fyy = currentFound / _width; - return 1; + return true; } else { *fxx = 0; *fyy = 0; - return 0; + return false; } } @@ -238,15 +248,13 @@ bool PathFinding::walkLine(int32 x, int32 y, int32 x2, int32 y2) { int32 cdx = (dx << 16) / t; int32 cdy = (dy << 16) / t; - int32 i = t; _gridPathCount = 0; - while (i) { + for (int32 i = t; i > 0; i--) { _tempPathX[i] = bx >> 16; _tempPathY[i] = by >> 16; _gridPathCount++; bx += cdx; by += cdy; - i--; } _tempPathX[0] = x2; @@ -271,17 +279,16 @@ bool PathFinding::lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2) { int32 cdx = (dx << 16) / t; int32 cdy = (dy << 16) / t; - int32 i = t; - while (i) { + for (int32 i = t; i > 0; i--) { if (!isWalkable(bx >> 16, by >> 16)) return false; bx += cdx; by += cdy; - i--; } return true; } -int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { + +bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { debugC(1, kDebugPath, "findPath(%d, %d, %d, %d)", x, y, destx, desty); if (x == destx && y == desty) { @@ -373,7 +380,7 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { numpath++; int32 bestscore = sq[destx + desty * _width]; - while (1) { + while (true) { int32 bestX = -1; int32 bestY = -1; @@ -403,7 +410,7 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { free(retPathX); free(retPathY); - return 0; + return false; } retPathX[numpath] = bestX; @@ -432,18 +439,6 @@ int32 PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { return false; } -void PathFinding::init(Picture *mask) { - debugC(1, kDebugPath, "init(mask)"); - - _width = mask->getWidth(); - _height = mask->getHeight(); - _currentMask = mask; - _heap->unload(); - _heap->init(500); - delete[] _gridTemp; - _gridTemp = new int32[_width*_height]; -} - void PathFinding::resetBlockingRects() { _numBlockingRects = 0; } @@ -460,7 +455,7 @@ void PathFinding::addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2) { } void PathFinding::addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h) { - debugC(1, kDebugPath, "addBlockingRect(%d, %d, %d, %d)", x1, y1, w, h); + debugC(1, kDebugPath, "addBlockingEllipse(%d, %d, %d, %d)", x1, y1, w, h); _blockingRects[_numBlockingRects][0] = x1; _blockingRects[_numBlockingRects][1] = y1; diff --git a/engines/toon/path.h b/engines/toon/path.h index df2b2e94be..7709dfe2a0 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -57,13 +57,14 @@ public: PathFinding(ToonEngine *vm); ~PathFinding(); - int32 findPath(int32 x, int32 y, int32 destX, int32 destY); - int32 findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 *fyy, int origX = -1, int origY = -1); + void init(Picture *mask); + + bool findPath(int32 x, int32 y, int32 destX, int32 destY); + bool findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 *fyy, int origX = -1, int origY = -1); bool isWalkable(int32 x, int32 y); bool isLikelyWalkable(int32 x, int32 y); bool lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2); bool walkLine(int32 x, int32 y, int32 x2, int32 y2); - void init(Picture *mask); void resetBlockingRects(); void addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2); -- cgit v1.2.3 From 6cda28adc9e1adb5b05bdb58baf449f2e24b9945 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 7 Jun 2012 13:20:53 +0100 Subject: TOON: Remove unecessary usages of g_system. --- engines/toon/toon.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 657e18635f..9e7aa65265 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -168,7 +168,7 @@ void ToonEngine::waitForScriptStep() { // Wait after a specified number of script steps when executing a script // to lower CPU usage if (++_scriptStep >= 40) { - g_system->delayMillis(1); + _system->delayMillis(1); _scriptStep = 0; } } @@ -2979,8 +2979,7 @@ bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) { return false; // dialog aborted Common::String savegameFile = getSavegameName(savegameId); - Common::SaveFileManager *saveMan = g_system->getSavefileManager(); - Common::OutSaveFile *saveFile = saveMan->openForSaving(savegameFile); + Common::OutSaveFile *saveFile = _saveFileMan->openForSaving(savegameFile); if (!saveFile) return false; @@ -3068,8 +3067,7 @@ bool ToonEngine::loadGame(int32 slot) { return false; // dialog aborted Common::String savegameFile = getSavegameName(savegameId); - Common::SaveFileManager *saveMan = g_system->getSavefileManager(); - Common::InSaveFile *loadFile = saveMan->openForLoading(savegameFile); + Common::InSaveFile *loadFile = _saveFileMan->openForLoading(savegameFile); if (!loadFile) return false; -- cgit v1.2.3 From 70f09e4ee36525025421db28a5a50b8b5dc0a963 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 7 Jun 2012 13:24:54 +0100 Subject: TOON: Reduce unecessary linkages in Pathfinding class. --- engines/toon/path.cpp | 2 +- engines/toon/path.h | 17 ++++++++--------- engines/toon/toon.cpp | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 101778d4b4..527be13c24 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -146,7 +146,7 @@ void PathFindingHeap::pop(int16 *x, int16 *y, int32 *weight) { } } -PathFinding::PathFinding(ToonEngine *vm) : _vm(vm) { +PathFinding::PathFinding() { _width = 0; _height = 0; _heap = new PathFindingHeap(); diff --git a/engines/toon/path.h b/engines/toon/path.h index 7709dfe2a0..30a7a53e9d 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -28,11 +28,6 @@ namespace Toon { // binary heap system for fast A* -struct HeapDataGrid { - int16 _x, _y; - int16 _weight; -}; - class PathFindingHeap { public: PathFindingHeap(); @@ -46,6 +41,11 @@ public: int32 getCount() { return _count; } private: + struct HeapDataGrid { + int16 _x, _y; + int16 _weight; + }; + HeapDataGrid *_data; int32 _size; @@ -54,7 +54,7 @@ private: class PathFinding { public: - PathFinding(ToonEngine *vm); + PathFinding(); ~PathFinding(); void init(Picture *mask); @@ -73,7 +73,8 @@ public: int32 getPathNodeCount() const; int32 getPathNodeX(int32 nodeId) const; int32 getPathNodeY(int32 nodeId) const; -protected: + +private: Picture *_currentMask; PathFindingHeap *_heap; @@ -88,8 +89,6 @@ protected: int32 _numBlockingRects; int32 _allocatedGridPathCount; int32 _gridPathCount; - - ToonEngine *_vm; }; } // End of namespace Toon diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 9e7aa65265..0b39432b53 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -100,7 +100,7 @@ void ToonEngine::init() { syncSoundSettings(); - _pathFinding = new PathFinding(this); + _pathFinding = new PathFinding(); resources()->openPackage("LOCAL.PAK"); resources()->openPackage("ONETIME.PAK"); -- cgit v1.2.3 From 380d3f000a12c4b923d7330cc88551f73abd7265 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 7 Jun 2012 14:41:04 +0100 Subject: TOON: Further cleanup to Pathfinding Class. Removal of some unused variables, logical reordering of functions and minor changes to reduce minor duplication. No functional changes. --- engines/toon/path.cpp | 55 ++++++++++++++++++++------------------------------- engines/toon/path.h | 16 ++++++++------- 2 files changed, 30 insertions(+), 41 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 527be13c24..b3f9b306be 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -174,7 +174,7 @@ void PathFinding::init(Picture *mask) { } bool PathFinding::isLikelyWalkable(int32 x, int32 y) { - for (int32 i = 0; i < _numBlockingRects; i++) { + for (uint8 i = 0; i < _numBlockingRects; i++) { if (_blockingRects[i][4] == 0) { if (x >= _blockingRects[i][0] && x <= _blockingRects[i][2] && y >= _blockingRects[i][1] && y < _blockingRects[i][3]) return false; @@ -364,11 +364,11 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { curX = destx; curY = desty; - int32 *retPathX = (int32 *)malloc(4096 * sizeof(int32)); - int32 *retPathY = (int32 *)malloc(4096 * sizeof(int32)); + int32 *retPathX = new int32[4096]; + int32 *retPathY = new int32[4096]; if (!retPathX || !retPathY) { - free(retPathX); - free(retPathY); + delete retPathX; + delete retPathY; error("[PathFinding::findPath] Cannot allocate pathfinding buffers"); } @@ -380,6 +380,7 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { numpath++; int32 bestscore = sq[destx + desty * _width]; + bool retVal = false; while (true) { int32 bestX = -1; int32 bestY = -1; @@ -406,12 +407,8 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { } } - if (bestX < 0 || bestY < 0) { - free(retPathX); - free(retPathY); - - return false; - } + if (bestX < 0 || bestY < 0) + break; retPathX[numpath] = bestX; retPathY[numpath] = bestY; @@ -423,28 +420,26 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { memcpy(_tempPathX, retPathX, sizeof(int32) * numpath); memcpy(_tempPathY, retPathY, sizeof(int32) * numpath); - free(retPathX); - free(retPathY); - - return true; + retVal = true; + break; } curX = bestX; curY = bestY; } - free(retPathX); - free(retPathY); + delete retPathX; + delete retPathY; - return false; -} - -void PathFinding::resetBlockingRects() { - _numBlockingRects = 0; + return retVal; } void PathFinding::addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2) { debugC(1, kDebugPath, "addBlockingRect(%d, %d, %d, %d)", x1, y1, x2, y2); + if (_numBlockingRects >= kMaxBlockingRects) { + warning("Maximum number of %d Blocking Rects reached!", kMaxBlockingRects); + return; + } _blockingRects[_numBlockingRects][0] = x1; _blockingRects[_numBlockingRects][1] = y1; @@ -456,6 +451,10 @@ void PathFinding::addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2) { void PathFinding::addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h) { debugC(1, kDebugPath, "addBlockingEllipse(%d, %d, %d, %d)", x1, y1, w, h); + if (_numBlockingRects >= kMaxBlockingRects) { + warning("Maximum number of %d Blocking Rects reached!", kMaxBlockingRects); + return; + } _blockingRects[_numBlockingRects][0] = x1; _blockingRects[_numBlockingRects][1] = y1; @@ -465,16 +464,4 @@ void PathFinding::addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h) { _numBlockingRects++; } -int32 PathFinding::getPathNodeCount() const { - return _gridPathCount; -} - -int32 PathFinding::getPathNodeX(int32 nodeId) const { - return _tempPathX[ _gridPathCount - nodeId - 1]; -} - -int32 PathFinding::getPathNodeY(int32 nodeId) const { - return _tempPathY[ _gridPathCount - nodeId - 1]; -} - } // End of namespace Toon diff --git a/engines/toon/path.h b/engines/toon/path.h index 30a7a53e9d..26abb411cc 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -66,15 +66,17 @@ public: bool lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2); bool walkLine(int32 x, int32 y, int32 x2, int32 y2); - void resetBlockingRects(); + void resetBlockingRects() { _numBlockingRects = 0; } void addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2); void addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h); - int32 getPathNodeCount() const; - int32 getPathNodeX(int32 nodeId) const; - int32 getPathNodeY(int32 nodeId) const; + int32 getPathNodeCount() const { return _gridPathCount; } + int32 getPathNodeX(int32 nodeId) const { return _tempPathX[ _gridPathCount - nodeId - 1]; } + int32 getPathNodeY(int32 nodeId) const { return _tempPathY[ _gridPathCount - nodeId - 1]; } private: + static const uint8 kMaxBlockingRects = 16; + Picture *_currentMask; PathFindingHeap *_heap; @@ -85,10 +87,10 @@ private: int32 _tempPathX[4096]; int32 _tempPathY[4096]; - int32 _blockingRects[16][5]; - int32 _numBlockingRects; - int32 _allocatedGridPathCount; int32 _gridPathCount; + + int32 _blockingRects[kMaxBlockingRects][5]; + uint8 _numBlockingRects; }; } // End of namespace Toon -- cgit v1.2.3 From b17b38cc364d13992b3be360a460d5b075e5848e Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 7 Jun 2012 17:50:20 +0200 Subject: COMMON: Move coroutine documentation to the header file. --- common/coroutines.cpp | 139 ------------------------------------------- common/coroutines.h | 161 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 143 insertions(+), 157 deletions(-) diff --git a/common/coroutines.cpp b/common/coroutines.cpp index 6159bdc0f3..102db8d26d 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -72,9 +72,6 @@ static void displayCoroStats() { } #endif -/** - * Creates a coroutine context - */ CoroBaseContext::CoroBaseContext(const char *func) : _line(0), _sleep(0), _subctx(0) { #ifdef COROUTINE_DEBUG @@ -84,9 +81,6 @@ CoroBaseContext::CoroBaseContext(const char *func) #endif } -/** - * Destructor for coroutine context - */ CoroBaseContext::~CoroBaseContext() { #ifdef COROUTINE_DEBUG s_coroCount--; @@ -100,9 +94,6 @@ CoroBaseContext::~CoroBaseContext() { //--------------------- Scheduler Class ------------------------ -/** - * Constructor - */ CoroutineScheduler::CoroutineScheduler() { processList = NULL; pFreeProcesses = NULL; @@ -124,9 +115,6 @@ CoroutineScheduler::CoroutineScheduler() { reset(); } -/** - * Destructor - */ CoroutineScheduler::~CoroutineScheduler() { // Kill all running processes (i.e. free memory allocated for their state). PROCESS *pProc = active->pNext; @@ -148,9 +136,6 @@ CoroutineScheduler::~CoroutineScheduler() { delete (*i); } -/** - * Kills all processes and places them on the free list. - */ void CoroutineScheduler::reset() { #ifdef DEBUG @@ -195,19 +180,12 @@ void CoroutineScheduler::reset() { #ifdef DEBUG -/** - * Shows the maximum number of process used at once. - */ void CoroutineScheduler::printStats() { debug("%i process of %i used", maxProcs, CORO_NUM_PROCESS); } #endif #ifdef DEBUG -/** - * Checks both the active and free process list to insure all the links are valid, - * and that no processes have been lost - */ void CoroutineScheduler::CheckStack() { Common::List pList; @@ -242,9 +220,6 @@ void CoroutineScheduler::CheckStack() { } #endif -/** - * Give all active processes a chance to run - */ void CoroutineScheduler::schedule() { // start dispatching active process list PROCESS *pNext; @@ -274,9 +249,6 @@ void CoroutineScheduler::schedule() { } } -/** - * Reschedules all the processes to run again this query - */ void CoroutineScheduler::rescheduleAll() { assert(pCurrent); @@ -292,10 +264,6 @@ void CoroutineScheduler::rescheduleAll() { pCurrent->pPrevious = active; } -/** - * If the specified process has already run on this tick, make it run - * again on the current tick. - */ void CoroutineScheduler::reschedule(PPROCESS pReSchedProc) { // If not currently processing the schedule list, then no action is needed if (!pCurrent) @@ -333,11 +301,6 @@ void CoroutineScheduler::reschedule(PPROCESS pReSchedProc) { pReSchedProc->pNext = NULL; } -/** - * Moves the specified process to the end of the dispatch queue - * allowing it to run again within the current game cycle. - * @param pGiveProc Which process - */ void CoroutineScheduler::giveWay(PPROCESS pReSchedProc) { // If not currently processing the schedule list, then no action is needed if (!pCurrent) @@ -371,13 +334,6 @@ void CoroutineScheduler::giveWay(PPROCESS pReSchedProc) { pReSchedProc->pNext = NULL; } -/** - * Continously makes a given process wait for another process to finish or event to signal. - * - * @param pid Process/Event identifier - * @param duration Duration in milliseconds - * @param expired If specified, set to true if delay period expired - */ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired) { if (!pCurrent) error("Called CoroutineScheduler::waitForSingleObject from the main process"); @@ -434,15 +390,6 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio CORO_END_CODE; } -/** - * Continously makes a given process wait for given prcesses to finished or events to be set - * - * @param nCount Number of Id's being passed - * @param evtList List of pids to wait for - * @param bWaitAll Specifies whether all or any of the processes/events - * @param duration Duration in milliseconds - * @param expired Set to true if delay period expired - */ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, uint32 duration, bool *expired) { if (!pCurrent) @@ -510,12 +457,6 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 * CORO_END_CODE; } -/** - * Make the active process sleep for the given duration in milliseconds - * @param duration Duration in milliseconds - * @remarks This duration won't be precise, since it relies on the frequency the - * scheduler is called. - */ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) { if (!pCurrent) error("Called CoroutineScheduler::sleep from the main process"); @@ -539,14 +480,6 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) { CORO_END_CODE; } -/** - * Creates a new process. - * - * @param pid process identifier - * @param coroAddr Coroutine start address - * @param pParam Process specific info - * @param sizeParam Size of process specific info - */ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam) { PROCESS *pProc; @@ -611,35 +544,15 @@ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const return pProc; } -/** - * Creates a new process with an auto-incrementing Process Id. - * - * @param coroAddr Coroutine start address - * @param pParam Process specific info - * @param sizeParam Size of process specific info - */ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam) { PROCESS *pProc = createProcess(++pidCounter, coroAddr, pParam, sizeParam); return pProc->pid; } -/** - * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter. - * - * @param coroAddr Coroutine start address - * @param pParam Process specific info - * @param sizeParam Size of process specific info - */ uint32 CoroutineScheduler::createProcess(CORO_ADDR coroAddr, const void *pParam) { return createProcess(coroAddr, &pParam, sizeof(void *)); } - -/** - * Kills the specified process. - * - * @param pKillProc Which process to kill - */ void CoroutineScheduler::killProcess(PROCESS *pKillProc) { // make sure a valid process pointer assert(pKillProc >= processList && pKillProc <= processList + CORO_NUM_PROCESS - 1); @@ -675,20 +588,10 @@ void CoroutineScheduler::killProcess(PROCESS *pKillProc) { pFreeProcesses = pKillProc; } - - -/** - * Returns a pointer to the currently running process. - */ PROCESS *CoroutineScheduler::getCurrentProcess() { return pCurrent; } -/** - * Returns the process identifier of the specified process. - * - * @param pProc Which process - */ int CoroutineScheduler::getCurrentPID() const { PROCESS *pProc = pCurrent; @@ -699,14 +602,6 @@ int CoroutineScheduler::getCurrentPID() const { return pProc->pid; } -/** - * Kills any process matching the specified PID. The current - * process cannot be killed. - * - * @param pidKill Process identifier of process to kill - * @param pidMask Mask to apply to process identifiers before comparison - * @return The number of processes killed is returned. - */ int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) { int numKilled = 0; PROCESS *pProc, *pPrev; // process list pointers @@ -756,15 +651,6 @@ int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) { return numKilled; } -/** - * Set pointer to a function to be called by killProcess(). - * - * May be called by a resource allocator, the function supplied is - * called by killProcess() to allow the resource allocator to free - * resources allocated to the dying process. - * - * @param pFunc Function to be called by killProcess() - */ void CoroutineScheduler::setResourceCallback(VFPTRPP pFunc) { pRCfunction = pFunc; } @@ -789,12 +675,6 @@ EVENT *CoroutineScheduler::getEvent(uint32 pid) { } -/** - * Creates a new event object - * @param bManualReset Events needs to be manually reset. Otherwise, events - * will be automatically reset after a process waits on the event finishes - * @param bInitialState Specifies whether the event is signalled or not initially - */ uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) { EVENT *evt = new EVENT(); evt->pid = ++pidCounter; @@ -805,10 +685,6 @@ uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) { return evt->pid; } -/** - * Destroys the given event - * @param pidEvent Event Process Id - */ void CoroutineScheduler::closeEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); if (evt) { @@ -817,33 +693,18 @@ void CoroutineScheduler::closeEvent(uint32 pidEvent) { } } -/** - * Sets the event - * @param pidEvent Event Process Id - */ void CoroutineScheduler::setEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); if (evt) evt->signalled = true; } -/** - * Resets the event - * @param pidEvent Event Process Id - */ void CoroutineScheduler::resetEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); if (evt) evt->signalled = false; } -/** - * Temporarily sets a given event to true, and then runs all waiting processes, allowing any - * processes waiting on the event to be fired. It then immediately resets the event again. - * @param pidEvent Event Process Id - * - * @remarks Should not be run inside of another process - */ void CoroutineScheduler::pulseEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); if (!evt) diff --git a/common/coroutines.h b/common/coroutines.h index abc114e0cf..f5519902dd 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -56,7 +56,14 @@ struct CoroBaseContext { #ifdef COROUTINE_DEBUG const char *_funcName; #endif + /** + * Creates a coroutine context + */ CoroBaseContext(const char *func); + + /** + * Destructor for coroutine context + */ virtual ~CoroBaseContext(); }; @@ -344,6 +351,10 @@ private: int numProcs; int maxProcs; + /** + * Checks both the active and free process list to insure all the links are valid, + * and that no processes have been lost + */ void CheckStack(); #endif @@ -356,71 +367,185 @@ private: PROCESS *getProcess(uint32 pid); EVENT *getEvent(uint32 pid); public: + /** + * Constructor + */ CoroutineScheduler(); + + /** + * Destructor + */ ~CoroutineScheduler(); + /** + * Kills all processes and places them on the free list. + */ void reset(); #ifdef DEBUG + /** + * Shows the maximum number of process used at once. + */ void printStats(); #endif - /** Give all active processes a chance to run */ + /** + * Give all active processes a chance to run + */ void schedule(); - /** Reschedules all the processes to run again this tick */ + /** + * Reschedules all the processes to run again this tick + */ void rescheduleAll(); - /** If the specified process has already run on this tick, make it run again on the current tick. */ + /** + * If the specified process has already run on this tick, make it run + * again on the current tick. + */ void reschedule(PPROCESS pReSchedProc = NULL); - /** Moves the specified process to the end of the dispatch queue, so it can again in the current tick */ + /** + * Moves the specified process to the end of the dispatch queue + * allowing it to run again within the current game cycle. + * @param pGiveProc Which process + */ void giveWay(PPROCESS pReSchedProc = NULL); - /** Continously makes a given process wait for another process to finish or event to signal. */ + /** + * Continously makes a given process wait for another process to finish or event to signal. + * + * @param pid Process/Event identifier + * @param duration Duration in milliseconds + * @param expired If specified, set to true if delay period expired + */ void waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired = NULL); - /** Continously makes a given process wait for given prcesses to finished or events to be set */ + /** + * Continously makes a given process wait for given prcesses to finished or events to be set + * + * @param nCount Number of Id's being passed + * @param evtList List of pids to wait for + * @param bWaitAll Specifies whether all or any of the processes/events + * @param duration Duration in milliseconds + * @param expired Set to true if delay period expired + */ void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, uint32 duration, bool *expired = NULL); - /** Make the active process sleep for the given duration in milliseconds */ + /** + * Make the active process sleep for the given duration in milliseconds + * + * @param duration Duration in milliseconds + * @remarks This duration won't be precise, since it relies on the frequency the + * scheduler is called. + */ void sleep(CORO_PARAM, uint32 duration); - /** Creates a new process. */ + /** + * Creates a new process. + * + * @param pid process identifier + * @param coroAddr Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info + */ PROCESS *createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam); + + /** + * Creates a new process with an auto-incrementing Process Id. + * + * @param coroAddr Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info + */ uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam); + + /** + * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter. + * + * @param coroAddr Coroutine start address + * @param pParam Process specific info + */ uint32 createProcess(CORO_ADDR coroAddr, const void *pParam); - /** Kills the specified process. */ + /** + * Kills the specified process. + * + * @param pKillProc Which process to kill + */ void killProcess(PROCESS *pKillProc); - /** Returns a pointer to the currently running process. */ + /** + * Returns a pointer to the currently running process. + */ PROCESS *getCurrentProcess(); - /** Returns the process identifier of the specified process. */ + /** + * Returns the process identifier of the currently running process. + */ int getCurrentPID() const; - /** Kills any process matching the specified PID. The current process cannot be killed. */ + /** + * Kills any process matching the specified PID. The current + * process cannot be killed. + * + * @param pidKill Process identifier of process to kill + * @param pidMask Mask to apply to process identifiers before comparison + * @return The number of processes killed is returned. + */ int killMatchingProcess(uint32 pidKill, int pidMask = -1); - /** Set pointer to a function to be called by killProcess() */ + /** + * Set pointer to a function to be called by killProcess(). + * + * May be called by a resource allocator, the function supplied is + * called by killProcess() to allow the resource allocator to free + * resources allocated to the dying process. + * + * @param pFunc Function to be called by killProcess() + */ void setResourceCallback(VFPTRPP pFunc); /* Event methods */ - /** Creates a new event (semaphore) object */ + /** + * Creates a new event (semaphore) object + * + * @param bManualReset Events needs to be manually reset. Otherwise, + * events will be automatically reset after a + * process waits on the event finishes + * @param bInitialState Specifies whether the event is signalled or not + * initially + */ uint32 createEvent(bool bManualReset, bool bInitialState); - /** Destroys the given event */ + /** + * Destroys the given event + * @param pidEvent Event Process Id + */ void closeEvent(uint32 pidEvent); - /** Sets the event */ + /** + * Sets the event + * @param pidEvent Event Process Id + */ void setEvent(uint32 pidEvent); - /** Resets the event */ + /** + * Resets the event + * @param pidEvent Event Process Id + */ void resetEvent(uint32 pidEvent); - /** Temporarily sets a given event to true, allowing other waiting processes to fire */ + /** + * Temporarily sets a given event to true, and then runs all waiting + * processes,allowing any processes waiting on the event to be fired. It + * then immediately resets the event again. + * + * @param pidEvent Event Process Id + * + * @remarks Should not be run inside of another process + */ void pulseEvent(uint32 pidEvent); }; -- cgit v1.2.3 From 27aa0974499c6012da894872913f4f44cf6b6a5c Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 7 Jun 2012 17:51:58 +0200 Subject: COMMON: Slightly adapt coroutine code to better match our guidelines. I used astyle here, which automatically removes the use of tabs in comments. --- common/coroutines.cpp | 34 ++++----- common/coroutines.h | 203 +++++++++++++++++++++++++------------------------- 2 files changed, 118 insertions(+), 119 deletions(-) diff --git a/common/coroutines.cpp b/common/coroutines.cpp index 102db8d26d..241d31e0d7 100644 --- a/common/coroutines.cpp +++ b/common/coroutines.cpp @@ -34,7 +34,6 @@ CoroContext nullContext = NULL; DECLARE_SINGLETON(CoroutineScheduler); - #ifdef COROUTINE_DEBUG namespace { /** Count of active coroutines */ @@ -63,13 +62,13 @@ static void displayCoroStats() { if (!s_coroFuncs) return; for (CoroHashMap::const_iterator it = s_coroFuncs->begin(); - it != s_coroFuncs->end(); ++it) { + it != s_coroFuncs->end(); ++it) { if (it->_value != 0) debug(" %3d x %s", it->_value, it->_key.c_str()); } } -} +} // End of anonymous namespace #endif CoroBaseContext::CoroBaseContext(const char *func) @@ -86,7 +85,7 @@ CoroBaseContext::~CoroBaseContext() { s_coroCount--; changeCoroStats(_funcName, -1); debug("Deleting coro in %s at %p (subctx %p)", - _funcName, (void *)this, (void *)_subctx); + _funcName, (void *)this, (void *)_subctx); displayCoroStats(); #endif delete _subctx; @@ -133,11 +132,10 @@ CoroutineScheduler::~CoroutineScheduler() { // Clear the event list Common::List::iterator i; for (i = _events.begin(); i != _events.end(); ++i) - delete (*i); + delete *i; } void CoroutineScheduler::reset() { - #ifdef DEBUG // clear number of process in use numProcs = 0; @@ -179,14 +177,14 @@ void CoroutineScheduler::reset() { } -#ifdef DEBUG +#ifdef DEBUG void CoroutineScheduler::printStats() { debug("%i process of %i used", maxProcs, CORO_NUM_PROCESS); } #endif #ifdef DEBUG -void CoroutineScheduler::CheckStack() { +void CoroutineScheduler::checkStack() { Common::List pList; // Check both the active and free process lists @@ -354,7 +352,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio // Presume it will expire *expired = true; - // Outer loop for doing checks until expiry + // Outer loop for doing checks until expiry while (g_system->getMillis() <= _ctx->endTime) { // Check to see if a process or event with the given Id exists _ctx->pProcess = getProcess(pid); @@ -368,7 +366,7 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio break; } - // If a process was found, don't go into the if statement, and keep waiting. + // If a process was found, don't go into the if statement, and keep waiting. // Likewise if it's an event that's not yet signalled if ((_ctx->pEvent != NULL) && _ctx->pEvent->signalled) { // Unless the event is flagged for manual reset, reset it now @@ -390,8 +388,8 @@ void CoroutineScheduler::waitForSingleObject(CORO_PARAM, int pid, uint32 duratio CORO_END_CODE; } -void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, - uint32 duration, bool *expired) { +void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, + uint32 duration, bool *expired) { if (!pCurrent) error("Called CoroutineScheduler::waitForMultipleObjects from the main process"); @@ -415,7 +413,7 @@ void CoroutineScheduler::waitForMultipleObjects(CORO_PARAM, int nCount, uint32 * // Presume that delay will expire *expired = true; - // Outer loop for doing checks until expiry + // Outer loop for doing checks until expiry while (g_system->getMillis() <= _ctx->endTime) { _ctx->signalled = bWaitAll; @@ -471,7 +469,7 @@ void CoroutineScheduler::sleep(CORO_PARAM, uint32 duration) { _ctx->endTime = g_system->getMillis() + duration; - // Outer loop for doing checks until expiry + // Outer loop for doing checks until expiry while (g_system->getMillis() < _ctx->endTime) { // Sleep until the next cycle CORO_SLEEP(1); @@ -510,7 +508,7 @@ PROCESS *CoroutineScheduler::createProcess(uint32 pid, CORO_ADDR coroAddr, const pCurrent->pNext = pProc; pProc->pPrevious = pCurrent; - } else { // no active processes, place process at head of list + } else { // no active processes, place process at head of list pProc->pNext = active->pNext; pProc->pPrevious = active; @@ -604,7 +602,7 @@ int CoroutineScheduler::getCurrentPID() const { int CoroutineScheduler::killMatchingProcess(uint32 pidKill, int pidMask) { int numKilled = 0; - PROCESS *pProc, *pPrev; // process list pointers + PROCESS *pProc, *pPrev; // process list pointers for (pProc = active->pNext, pPrev = active; pProc != NULL; pPrev = pProc, pProc = pProc->pNext) { if ((pProc->pid & (uint32)pidMask) == pidKill) { @@ -709,10 +707,10 @@ void CoroutineScheduler::pulseEvent(uint32 pidEvent) { EVENT *evt = getEvent(pidEvent); if (!evt) return; - + // Set the event as true evt->signalled = true; - + // start dispatching active process list for any processes that are currently waiting PROCESS *pOriginal = pCurrent; PROCESS *pNext; diff --git a/common/coroutines.h b/common/coroutines.h index f5519902dd..3b8b1a77f9 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -23,7 +23,7 @@ #define COMMON_COROUTINES_H #include "common/scummsys.h" -#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION +#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION #include "common/list.h" #include "common/singleton.h" @@ -133,42 +133,43 @@ public: /** * End the declaration of a coroutine context. - * @param x name of the coroutine context + * @param x name of the coroutine context * @see CORO_BEGIN_CONTEXT */ #define CORO_END_CONTEXT(x) } *x = (CoroContextTag *)coroParam /** * Begin the code section of a coroutine. - * @param x name of the coroutine context + * @param x name of the coroutine context * @see CORO_BEGIN_CODE */ #define CORO_BEGIN_CODE(x) \ - if (&coroParam == &Common::nullContext) assert(!Common::nullContext);\ - if (!x) {coroParam = x = new CoroContextTag();}\ - Common::CoroContextHolder tmpHolder(coroParam);\ - switch (coroParam->_line) { case 0:; + if (&coroParam == &Common::nullContext) assert(!Common::nullContext); \ + if (!x) { coroParam = x = new CoroContextTag(); } \ + Common::CoroContextHolder tmpHolder(coroParam); \ + switch (coroParam->_line) { case 0:; /** * End the code section of a coroutine. * @see CORO_END_CODE */ #define CORO_END_CODE \ - if (&coroParam == &Common::nullContext) { \ - delete Common::nullContext; \ - Common::nullContext = NULL; \ - } \ - } + if (&coroParam == &Common::nullContext) { \ + delete Common::nullContext; \ + Common::nullContext = NULL; \ + } \ + } /** * Sleep for the specified number of scheduler cycles. */ -#define CORO_SLEEP(delay) do {\ - coroParam->_line = __LINE__;\ - coroParam->_sleep = delay;\ - assert(&coroParam != &Common::nullContext);\ - return; case __LINE__:;\ - } while (0) +#define CORO_SLEEP(delay) \ + do { \ + coroParam->_line = __LINE__; \ + coroParam->_sleep = delay; \ + assert(&coroParam != &Common::nullContext); \ + return; case __LINE__:; \ + } while (0) #define CORO_GIVE_WAY do { CoroScheduler.giveWay(); CORO_SLEEP(1); } while (0) #define CORO_RESCHEDULE do { CoroScheduler.reschedule(); CORO_SLEEP(1); } while (0) @@ -182,7 +183,7 @@ public: * then delete the entire coroutine's state, including all subcontexts). */ #define CORO_KILL_SELF() \ - do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0) + do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0) /** @@ -201,8 +202,8 @@ public: * If the subcontext is null, the coroutine ended normally, and we can * simply break out of the loop and continue execution. * - * @param subCoro name of the coroutine-enabled function to invoke - * @param ARGS list of arguments to pass to subCoro + * @param subCoro name of the coroutine-enabled function to invoke + * @param ARGS list of arguments to pass to subCoro * * @note ARGS must be surrounded by parentheses, and the first argument * in this list must always be CORO_SUBCTX. For example, the @@ -211,18 +212,18 @@ public: * becomes the following: * CORO_INVOKE_ARGS(myFunc, (CORO_SUBCTX, a, b)); */ -#define CORO_INVOKE_ARGS(subCoro, ARGS) \ - do {\ - coroParam->_line = __LINE__;\ - coroParam->_subctx = 0;\ - do {\ - subCoro ARGS;\ - if (!coroParam->_subctx) break;\ - coroParam->_sleep = coroParam->_subctx->_sleep;\ - assert(&coroParam != &Common::nullContext);\ - return; case __LINE__:;\ - } while (1);\ - } while (0) +#define CORO_INVOKE_ARGS(subCoro, ARGS) \ + do { \ + coroParam->_line = __LINE__; \ + coroParam->_subctx = 0; \ + do { \ + subCoro ARGS; \ + if (!coroParam->_subctx) break; \ + coroParam->_sleep = coroParam->_subctx->_sleep; \ + assert(&coroParam != &Common::nullContext); \ + return; case __LINE__:; \ + } while (1); \ + } while (0) /** * Invoke another coroutine. Similar to CORO_INVOKE_ARGS, @@ -230,62 +231,62 @@ public: * if invoked coroutine yields (thus causing the current * coroutine to yield, too). */ -#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \ - do {\ - coroParam->_line = __LINE__;\ - coroParam->_subctx = 0;\ - do {\ - subCoro ARGS;\ - if (!coroParam->_subctx) break;\ - coroParam->_sleep = coroParam->_subctx->_sleep;\ - assert(&coroParam != &Common::nullContext);\ - return RESULT; case __LINE__:;\ - } while (1);\ - } while (0) +#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \ + do { \ + coroParam->_line = __LINE__; \ + coroParam->_subctx = 0; \ + do { \ + subCoro ARGS; \ + if (!coroParam->_subctx) break; \ + coroParam->_sleep = coroParam->_subctx->_sleep; \ + assert(&coroParam != &Common::nullContext); \ + return RESULT; case __LINE__:; \ + } while (1); \ + } while (0) /** * Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine * with no parameters. */ #define CORO_INVOKE_0(subCoroutine) \ - CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX)) + CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX)) /** * Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine * with one parameter. */ #define CORO_INVOKE_1(subCoroutine, a0) \ - CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0)) + CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0)) /** * Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine * with two parameters. */ #define CORO_INVOKE_2(subCoroutine, a0,a1) \ - CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1)) + CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1)) /** * Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine * with three parameters. */ #define CORO_INVOKE_3(subCoroutine, a0,a1,a2) \ - CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2)) + CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2)) /** * Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine * with four parameters. */ #define CORO_INVOKE_4(subCoroutine, a0,a1,a2,a3) \ - CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2,a3)) + CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2, a3)) // the size of process specific info -#define CORO_PARAM_SIZE 32 +#define CORO_PARAM_SIZE 32 // the maximum number of processes -#define CORO_NUM_PROCESS 100 -#define CORO_MAX_PROCESSES 100 +#define CORO_NUM_PROCESS 100 +#define CORO_MAX_PROCESSES 100 #define CORO_MAX_PID_WAITING 5 #define CORO_INFINITE 0xffffffff @@ -296,16 +297,16 @@ typedef void (*CORO_ADDR)(CoroContext &, const void *); /** process structure */ struct PROCESS { - PROCESS *pNext; ///< pointer to next process in active or free list - PROCESS *pPrevious; ///< pointer to previous process in active or free list + PROCESS *pNext; ///< pointer to next process in active or free list + PROCESS *pPrevious; ///< pointer to previous process in active or free list - CoroContext state; ///< the state of the coroutine - CORO_ADDR coroAddr; ///< the entry point of the coroutine + CoroContext state; ///< the state of the coroutine + CORO_ADDR coroAddr; ///< the entry point of the coroutine - int sleepTime; ///< number of scheduler cycles to sleep - uint32 pid; ///< process ID - uint32 pidWaiting[CORO_MAX_PID_WAITING]; ///< Process ID(s) process is currently waiting on - char param[CORO_PARAM_SIZE]; ///< process specific info + int sleepTime; ///< number of scheduler cycles to sleep + uint32 pid; ///< process ID + uint32 pidWaiting[CORO_MAX_PID_WAITING]; ///< Process ID(s) process is currently waiting on + char param[CORO_PARAM_SIZE]; ///< process specific info }; typedef PROCESS *PPROCESS; @@ -321,7 +322,7 @@ struct EVENT { /** * Creates and manages "processes" (really coroutines). */ -class CoroutineScheduler: public Singleton { +class CoroutineScheduler : public Singleton { public: /** Pointer to a function of the form "void function(PPROCESS)" */ typedef void (*VFPTRPP)(PROCESS *); @@ -355,7 +356,7 @@ private: * Checks both the active and free process list to insure all the links are valid, * and that no processes have been lost */ - void CheckStack(); + void checkStack(); #endif /** @@ -382,12 +383,12 @@ public: */ void reset(); - #ifdef DEBUG +#ifdef DEBUG /** * Shows the maximum number of process used at once. */ void printStats(); - #endif +#endif /** * Give all active processes a chance to run @@ -408,71 +409,71 @@ public: /** * Moves the specified process to the end of the dispatch queue * allowing it to run again within the current game cycle. - * @param pGiveProc Which process + * @param pGiveProc Which process */ void giveWay(PPROCESS pReSchedProc = NULL); /** * Continously makes a given process wait for another process to finish or event to signal. * - * @param pid Process/Event identifier - * @param duration Duration in milliseconds - * @param expired If specified, set to true if delay period expired + * @param pid Process/Event identifier + * @param duration Duration in milliseconds + * @param expired If specified, set to true if delay period expired */ void waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired = NULL); /** * Continously makes a given process wait for given prcesses to finished or events to be set * - * @param nCount Number of Id's being passed - * @param evtList List of pids to wait for - * @param bWaitAll Specifies whether all or any of the processes/events - * @param duration Duration in milliseconds - * @param expired Set to true if delay period expired + * @param nCount Number of Id's being passed + * @param evtList List of pids to wait for + * @param bWaitAll Specifies whether all or any of the processes/events + * @param duration Duration in milliseconds + * @param expired Set to true if delay period expired */ - void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, - uint32 duration, bool *expired = NULL); + void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll, + uint32 duration, bool *expired = NULL); /** * Make the active process sleep for the given duration in milliseconds * - * @param duration Duration in milliseconds - * @remarks This duration won't be precise, since it relies on the frequency the + * @param duration Duration in milliseconds + * @remarks This duration won't be precise, since it relies on the frequency the * scheduler is called. */ void sleep(CORO_PARAM, uint32 duration); - + /** * Creates a new process. * - * @param pid process identifier - * @param coroAddr Coroutine start address - * @param pParam Process specific info - * @param sizeParam Size of process specific info + * @param pid process identifier + * @param coroAddr Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info */ PROCESS *createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam); /** * Creates a new process with an auto-incrementing Process Id. * - * @param coroAddr Coroutine start address - * @param pParam Process specific info - * @param sizeParam Size of process specific info + * @param coroAddr Coroutine start address + * @param pParam Process specific info + * @param sizeParam Size of process specific info */ uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam); /** * Creates a new process with an auto-incrementing Process Id, and a single pointer parameter. * - * @param coroAddr Coroutine start address - * @param pParam Process specific info + * @param coroAddr Coroutine start address + * @param pParam Process specific info */ uint32 createProcess(CORO_ADDR coroAddr, const void *pParam); /** * Kills the specified process. * - * @param pKillProc Which process to kill + * @param pKillProc Which process to kill */ void killProcess(PROCESS *pKillProc); @@ -490,9 +491,9 @@ public: * Kills any process matching the specified PID. The current * process cannot be killed. * - * @param pidKill Process identifier of process to kill - * @param pidMask Mask to apply to process identifiers before comparison - * @return The number of processes killed is returned. + * @param pidKill Process identifier of process to kill + * @param pidMask Mask to apply to process identifiers before comparison + * @return The number of processes killed is returned. */ int killMatchingProcess(uint32 pidKill, int pidMask = -1); @@ -503,7 +504,7 @@ public: * called by killProcess() to allow the resource allocator to free * resources allocated to the dying process. * - * @param pFunc Function to be called by killProcess() + * @param pFunc Function to be called by killProcess() */ void setResourceCallback(VFPTRPP pFunc); @@ -511,29 +512,29 @@ public: /** * Creates a new event (semaphore) object * - * @param bManualReset Events needs to be manually reset. Otherwise, + * @param bManualReset Events needs to be manually reset. Otherwise, * events will be automatically reset after a * process waits on the event finishes - * @param bInitialState Specifies whether the event is signalled or not + * @param bInitialState Specifies whether the event is signalled or not * initially */ uint32 createEvent(bool bManualReset, bool bInitialState); /** * Destroys the given event - * @param pidEvent Event Process Id + * @param pidEvent Event Process Id */ void closeEvent(uint32 pidEvent); /** * Sets the event - * @param pidEvent Event Process Id + * @param pidEvent Event Process Id */ void setEvent(uint32 pidEvent); /** * Resets the event - * @param pidEvent Event Process Id + * @param pidEvent Event Process Id */ void resetEvent(uint32 pidEvent); @@ -542,9 +543,9 @@ public: * processes,allowing any processes waiting on the event to be fired. It * then immediately resets the event again. * - * @param pidEvent Event Process Id + * @param pidEvent Event Process Id * - * @remarks Should not be run inside of another process + * @remarks Should not be run inside of another process */ void pulseEvent(uint32 pidEvent); }; @@ -553,4 +554,4 @@ public: } // end of namespace Common -#endif // COMMON_COROUTINES_H +#endif // COMMON_COROUTINES_H -- cgit v1.2.3 From 8e7f874db35395d100ca73d9433b25f2f7eae19d Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 7 Jun 2012 18:11:38 +0200 Subject: COMMON: Make CoroutineScheduler's constructor and destructor private. CoroutineSchedule is a singleton, thus it should not be possible to create a custom instance of it. --- common/coroutines.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/common/coroutines.h b/common/coroutines.h index 3b8b1a77f9..64eabbf8f4 100644 --- a/common/coroutines.h +++ b/common/coroutines.h @@ -328,6 +328,18 @@ public: typedef void (*VFPTRPP)(PROCESS *); private: + friend class Singleton; + + /** + * Constructor + */ + CoroutineScheduler(); + + /** + * Destructor + */ + ~CoroutineScheduler(); + /** list of all processes */ PROCESS *processList; @@ -368,16 +380,6 @@ private: PROCESS *getProcess(uint32 pid); EVENT *getEvent(uint32 pid); public: - /** - * Constructor - */ - CoroutineScheduler(); - - /** - * Destructor - */ - ~CoroutineScheduler(); - /** * Kills all processes and places them on the free list. */ -- cgit v1.2.3 From e1d45a7b89368ddb5c2d6a1d5b225611d1cfb9a4 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 7 Jun 2012 18:19:10 +0200 Subject: TINSEL: Remove unused member _scheduler in TinselEngine. This is a leftover from before the move of the coroutine code. --- engines/tinsel/tinsel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h index 59344c44f4..bac7ef6efb 100644 --- a/engines/tinsel/tinsel.h +++ b/engines/tinsel/tinsel.h @@ -53,7 +53,6 @@ class Config; class MidiDriver; class MidiMusicPlayer; class PCMMusicPlayer; -class Scheduler; class SoundManager; typedef Common::List RectList; @@ -154,7 +153,6 @@ class TinselEngine : public Engine { Common::Point _mousePos; uint8 _dosPlayerDir; Console *_console; - Scheduler *_scheduler; static const char *const _sampleIndices[][3]; static const char *const _sampleFiles[][3]; -- cgit v1.2.3 From 421b93ce0574b76eeae0ffe0598f1f6858ddf1f1 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 8 Jun 2012 03:11:44 +0200 Subject: GOB: Rewrite "pathfinding" and implement moving enemies Since shooting does not yet work, we're just getting mauled by them... --- engines/gob/minigames/geisha/penetration.cpp | 362 ++++++++++++++++++++++----- engines/gob/minigames/geisha/penetration.h | 77 ++++-- engines/gob/minigames/geisha/submarine.cpp | 3 + 3 files changed, 358 insertions(+), 84 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 9791757984..656e90a45b 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -59,8 +59,12 @@ enum Sprite { }; enum Animation { - kAnimationMouthKiss = 33, - kAnimationMouthBite = 34 + kAnimationEnemyRound = 0, + kAnimationEnemyRoundExplode = 1, + kAnimationEnemySquare = 2, + kAnimationEnemySquareExplode = 3, + kAnimationMouthKiss = 33, + kAnimationMouthBite = 34 }; static const int kMapTileWidth = 24; @@ -353,12 +357,55 @@ static const char *kStrings[kLanguageCount][kStringCount] = { } }; -Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { + +Penetration::MapObject::MapObject(uint16 tX, uint16 tY, uint16 mX, uint16 mY, uint16 w, uint16 h) : + tileX(tX), tileY(tY), mapX(mX), mapY(mY), width(w), height(h) { + + isBlocking = true; +} + +Penetration::MapObject::MapObject(uint16 tX, uint16 tY, uint16 w, uint16 h) : + tileX(tX), tileY(tY), width(w), height(h) { + + isBlocking = true; + + setMapFromTilePosition(); } +void Penetration::MapObject::setTileFromMapPosition() { + tileX = (mapX + (width / 2)) / kMapTileWidth; + tileY = (mapY + (height / 2)) / kMapTileHeight; +} + +void Penetration::MapObject::setMapFromTilePosition() { + mapX = tileX * kMapTileWidth; + mapY = tileY * kMapTileHeight; +} + +bool Penetration::MapObject::isIn(uint16 mX, uint16 mY) const { + if ((mX < mapX) || (mY < mapY)) + return false; + if ((mX > (mapX + width - 1)) || (mY > (mapY + height - 1))) + return false; + + return true; +} + +bool Penetration::MapObject::isIn(uint16 mX, uint16 mY, uint16 w, uint16 h) const { + return isIn(mX , mY ) || + isIn(mX + w - 1, mY ) || + isIn(mX , mY + h - 1) || + isIn(mX + w - 1, mY + h - 1); +} + +bool Penetration::MapObject::isIn(const MapObject &obj) const { + return isIn(obj.mapX, obj.mapY, obj.width, obj.height); +} + + +Penetration::ManagedMouth::ManagedMouth(uint16 tX, uint16 tY, MouthType t) : + MapObject(tX, tY, 0, 0), mouth(0), type(t) { -Penetration::ManagedMouth::ManagedMouth(uint16 pX, uint16 pY, MouthType t) : - Position(pX, pY), mouth(0), type(t) { } Penetration::ManagedMouth::~ManagedMouth() { @@ -366,9 +413,9 @@ Penetration::ManagedMouth::~ManagedMouth() { } -Penetration::ManagedSub::ManagedSub(uint16 pX, uint16 pY) : Position(pX, pY), sub(0) { - mapX = x * kMapTileWidth; - mapY = y * kMapTileHeight; +Penetration::ManagedSub::ManagedSub(uint16 tX, uint16 tY) : + MapObject(tX, tY, kMapTileWidth, kMapTileHeight), sub(0) { + } Penetration::ManagedSub::~ManagedSub() { @@ -376,6 +423,20 @@ Penetration::ManagedSub::~ManagedSub() { } +Penetration::ManagedEnemy::ManagedEnemy() : MapObject(0, 0, 0, 0), enemy(0), dead(false) { +} + +Penetration::ManagedEnemy::~ManagedEnemy() { + delete enemy; +} + +void Penetration::ManagedEnemy::clear() { + delete enemy; + + enemy = 0; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) { @@ -415,6 +476,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_video->retrace(); while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) { + enemiesCreate(); updateAnims(); // Draw, fade in if necessary and wait for the end of the frame @@ -428,6 +490,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Handle the sub movement handleSub(); + // Handle the enemies movement + enemiesMove(); + checkExited(); } @@ -449,11 +514,12 @@ void Penetration::cheatWin() { void Penetration::init() { // Load sounds - _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); - _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); - _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); - _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); - _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); + _vm->_sound->sampleLoad(&_soundShield , SOUND_SND, "boucl.snd"); + _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); + _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); + _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); + _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); + _vm->_sound->sampleLoad(&_soundExplode, SOUND_SND, "virmor.snd"); _quit = false; for (int i = 0; i < kKeyCount; i++) @@ -486,6 +552,7 @@ void Penetration::deinit() { _soundKiss.free(); _soundShoot.free(); _soundExit.free(); + _soundExplode.free(); clearMap(); @@ -500,10 +567,16 @@ void Penetration::clearMap() { _mapAnims.clear(); _anims.clear(); + _blockingObjects.clear(); + + _walls.clear(); _exits.clear(); _shields.clear(); _mouths.clear(); + for (int i = 0; i < kEnemyCount; i++) + _enemies[i].clear(); + delete _sub; _sub = 0; @@ -526,13 +599,9 @@ void Penetration::createMap() { for (int x = 0; x < kMapWidth; x++) { const byte mapTile = mapTiles[y * kMapWidth + x]; - bool *walkMap = _walkMap + (y * kMapWidth + x); - const int posX = kPlayAreaBorderWidth + x * kMapTileWidth; const int posY = kPlayAreaBorderHeight + y * kMapTileHeight; - *walkMap = true; - switch (mapTile) { case 0: // Floor _sprites->draw(*_map, kSpriteFloor, posX, posY); @@ -542,18 +611,18 @@ void Penetration::createMap() { exitWorks = _hasAccessPass; if (exitWorks) { - _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); + _exits.push_back(MapObject(x, y, 0, 0)); } else { _sprites->draw(*_map, kSpriteWall, posX, posY); - *walkMap = false; + _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight)); } break; case 50: // Wall _sprites->draw(*_map, kSpriteWall, posX, posY); - *walkMap = false; + _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight)); break; case 51: // Regular exit @@ -563,11 +632,11 @@ void Penetration::createMap() { exitWorks = _testMode || (_floor < 2) || _hasAccessPass; if (exitWorks) { - _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); + _exits.push_back(MapObject(x, y, 0, 0)); } else { _sprites->draw(*_map, kSpriteWall, posX, posY); - *walkMap = false; + _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight)); } break; @@ -603,7 +672,7 @@ void Penetration::createMap() { _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield - _shields.push_back(Position(x, y)); + _shields.push_back(MapObject(x, y, 0, 0)); break; case 57: // Start position @@ -623,10 +692,30 @@ void Penetration::createMap() { if (!_sub) error("Geisha: No starting position in floor %d (testmode: %d)", _floor, _testMode); - for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) + // Walls + for (Common::List::iterator w = _walls.begin(); w != _walls.end(); ++w) + _blockingObjects.push_back(&*w); + + // Mouths + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); ++m) _mapAnims.push_back(m->mouth); + // Sub + _blockingObjects.push_back(_sub); _anims.push_back(_sub->sub); + + // Moving enemies + for (int i = 0; i < kEnemyCount; i++) { + _enemies[i].enemy = new ANIObject(*_objects); + + _enemies[i].enemy->setPause(true); + _enemies[i].enemy->setVisible(false); + + _enemies[i].isBlocking = false; + + _blockingObjects.push_back(&_enemies[i]); + _mapAnims.push_back(_enemies[i].enemy); + } } void Penetration::drawFloorText() { @@ -741,6 +830,104 @@ void Penetration::initScreen() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } +void Penetration::enemiesCreate() { + for (int i = 0; i < kEnemyCount; i++) { + ManagedEnemy &enemy = _enemies[i]; + + if (enemy.enemy->isVisible()) + continue; + + enemy.enemy->setAnimation((i & 1) ? kAnimationEnemySquare : kAnimationEnemyRound); + enemy.enemy->setMode(ANIObject::kModeContinuous); + enemy.enemy->setPause(false); + enemy.enemy->setVisible(true); + + int16 width, height; + enemy.enemy->getFrameSize(width, height); + + enemy.width = width; + enemy.height = height; + + do { + enemy.mapX = _vm->_util->getRandom(kMapWidth) * kMapTileWidth + 2; + enemy.mapY = _vm->_util->getRandom(kMapHeight) * kMapTileHeight + 4; + enemy.setTileFromMapPosition(); + } while (isBlocked(enemy, enemy.mapX, enemy.mapY)); + + const int posX = kPlayAreaBorderWidth + enemy.mapX; + const int posY = kPlayAreaBorderHeight + enemy.mapY; + + enemy.enemy->setPosition(posX, posY); + + enemy.isBlocking = true; + enemy.dead = false; + } +} + +void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) { + if ((x == 0) && (y == 0)) + return; + + bool touchedSub; + findPath(enemy, x, y, _sub, &touchedSub); + + enemy.setTileFromMapPosition(); + + const int posX = kPlayAreaBorderWidth + enemy.mapX; + const int posY = kPlayAreaBorderHeight + enemy.mapY; + + enemy.enemy->setPosition(posX, posY); + + if (touchedSub) + enemyAttack(enemy); +} + +void Penetration::enemiesMove() { + for (int i = 0; i < kEnemyCount; i++) { + ManagedEnemy &enemy = _enemies[i]; + + if (!enemy.enemy->isVisible() || enemy.dead) + continue; + + int x = 0, y = 0; + + if (enemy.mapX > _sub->mapX) + x = -8; + else if (enemy.mapX < _sub->mapX) + x = 8; + + if (enemy.mapY > _sub->mapY) + y = -8; + else if (enemy.mapY < _sub->mapY) + y = 8; + + enemyMove(enemy, x, y); + } +} + +void Penetration::enemyAttack(ManagedEnemy &enemy) { + // If we have shields, the enemy explodes at them, taking a huge chunk of energy with it. + // Otherwise, the enemy nibbles a small amount of health away. + + if (_shieldMeter->getValue() > 0) { + enemyExplode(enemy); + + healthLose(80); + } else + healthLose(5); +} + +void Penetration::enemyExplode(ManagedEnemy &enemy) { + enemy.dead = true; + + bool isSquare = enemy.enemy->getAnimation() == kAnimationEnemySquare; + + enemy.enemy->setAnimation(isSquare ? kAnimationEnemySquareExplode : kAnimationEnemyRoundExplode); + enemy.enemy->setMode(ANIObject::kModeOnce); + + _vm->_sound->blasterPlay(&_soundExplode, 1, 0); +} + void Penetration::checkInput() { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); @@ -785,13 +972,6 @@ void Penetration::checkInput() { } } -bool Penetration::isWalkable(int16 x, int16 y) const { - if ((x < 0) || (x >= kMapWidth) || (y < 0) || (y >= kMapHeight)) - return false; - - return _walkMap[y * kMapWidth + x]; -} - void Penetration::handleSub() { int x, y; Submarine::Direction direction = getDirection(x, y); @@ -802,34 +982,90 @@ void Penetration::handleSub() { subShoot(); } -void Penetration::subMove(int x, int y, Submarine::Direction direction) { - if (!_sub->sub->canMove()) - return; +bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, + const MapObject *checkBlockedBy, bool *blockedBy) const { - // Limit the movement to walkable tiles + if ((x < 0) || (y < 0)) + return true; + if (((x + self.width - 1) >= (kMapWidth * kMapTileWidth)) || + ((y + self.height - 1) >= (kMapHeight * kMapTileHeight))) + return true; - int16 minX = 0; - if (!isWalkable(_sub->x - 1, _sub->y)) - minX = _sub->x * kMapTileWidth; + MapObject checkSelf(0, 0, self.width, self.height); - int16 maxX = kMapWidth * kMapTileWidth; - if (!isWalkable(_sub->x + 1, _sub->y)) - maxX = _sub->x * kMapTileWidth; + checkSelf.mapX = x; + checkSelf.mapY = y; - int16 minY = 0; - if (!isWalkable(_sub->x, _sub->y - 1)) - minY = _sub->y * kMapTileHeight; + bool blocked = false; + for (Common::List::const_iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) { + const MapObject &obj = **o; - int16 maxY = kMapHeight * kMapTileHeight; - if (!isWalkable(_sub->x, _sub->y + 1)) - maxY = _sub->y * kMapTileHeight; + if (&obj == &self) + continue; - _sub->mapX = CLIP(_sub->mapX + x, minX, maxX); - _sub->mapY = CLIP(_sub->mapY + y, minY, maxY); + if (!obj.isBlocking) + continue; + + if (obj.isIn(checkSelf) || checkSelf.isIn(obj)) { + blocked = true; + + if (checkBlockedBy && blockedBy && (&obj == checkBlockedBy)) + *blockedBy = true; + } + } + + return blocked; +} + +void Penetration::findPath(MapObject &obj, int x, int y, + const MapObject *checkBlockedBy, bool *blockedBy) const { + + if (blockedBy) + *blockedBy = false; + + while ((x != 0) || (y != 0)) { + uint16 oldX = obj.mapX; + uint16 oldY = obj.mapY; + + uint16 newX = obj.mapX; + if (x > 0) { + newX++; + x--; + } else if (x < 0) { + newX--; + x++; + } + + if (!isBlocked(obj, newX, obj.mapY, checkBlockedBy, blockedBy)) + obj.mapX = newX; + + uint16 newY = obj.mapY; + if (y > 0) { + newY++; + y--; + } else if (y < 0) { + newY--; + y++; + } + + if (!isBlocked(obj, obj.mapX, newY, checkBlockedBy, blockedBy)) + obj.mapY = newY; + + if ((obj.mapX == oldX) && (obj.mapY == oldY)) + break; + } +} + +void Penetration::subMove(int x, int y, Submarine::Direction direction) { + if (!_sub->sub->canMove()) + return; - // The tile the sub is on is where its mid-point is - _sub->x = (_sub->mapX + (kMapTileWidth / 2)) / kMapTileWidth; - _sub->y = (_sub->mapY + (kMapTileHeight / 2)) / kMapTileHeight; + if ((x == 0) && (y == 0)) + return; + + findPath(*_sub, x, y); + + _sub->setTileFromMapPosition(); _sub->sub->turn(direction); @@ -872,8 +1108,8 @@ Submarine::Direction Penetration::getDirection(int &x, int &y) const { } void Penetration::checkShields() { - for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { - if ((pos->x == _sub->x) && (pos->y == _sub->y)) { + for (Common::List::iterator s = _shields.begin(); s != _shields.end(); ++s) { + if ((s->tileX == _sub->tileX) && (s->tileY == _sub->tileY)) { // Charge shields _shieldMeter->setMaxValue(); @@ -881,11 +1117,8 @@ void Penetration::checkShields() { _vm->_sound->blasterPlay(&_soundShield, 1, 0); // Erase the shield from the map - const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth; - const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight; - _sprites->draw(*_map, 30, mapX, mapY); - - _shields.erase(pos); + _sprites->draw(*_map, 30, s->mapX + kPlayAreaBorderWidth, s->mapY + kPlayAreaBorderHeight); + _shields.erase(s); break; } } @@ -896,8 +1129,8 @@ void Penetration::checkMouths() { if (!m->mouth->isDeactivated()) continue; - if ((( m->x == _sub->x) && (m->y == _sub->y)) || - (((m->x + 1) == _sub->x) && (m->y == _sub->y))) { + if ((( m->tileX == _sub->tileX) && (m->tileY == _sub->tileY)) || + (((m->tileX + 1) == _sub->tileX) && (m->tileY == _sub->tileY))) { m->mouth->activate(); @@ -917,10 +1150,9 @@ void Penetration::checkExits() { if (!_sub->sub->canMove()) return; - for (Common::List::iterator e = _exits.begin(); e != _exits.end(); ++e) { - if ((e->x == _sub->x) && (e->y == _sub->y)) { - _sub->mapX = e->x * kMapTileWidth; - _sub->mapY = e->y * kMapTileHeight; + for (Common::List::iterator e = _exits.begin(); e != _exits.end(); ++e) { + if ((e->tileX == _sub->tileX) && (e->tileY == _sub->tileY)) { + _sub->setMapFromTilePosition(); _sub->sub->leave(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 0336ef8dcb..9abae258b2 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -65,11 +65,29 @@ private: static const byte kPalettes[kFloorCount][3 * kPaletteSize]; static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; - struct Position { - uint16 x; - uint16 y; + static const int kEnemyCount = 9; - Position(uint16 pX, uint16 pY); + struct MapObject { + uint16 tileX; + uint16 tileY; + + uint16 mapX; + uint16 mapY; + + uint16 width; + uint16 height; + + bool isBlocking; + + MapObject(uint16 tX, uint16 tY, uint16 mX, uint16 mY, uint16 w, uint16 h); + MapObject(uint16 tX, uint16 tY, uint16 w, uint16 h); + + void setTileFromMapPosition(); + void setMapFromTilePosition(); + + bool isIn(uint16 mX, uint16 mY) const; + bool isIn(uint16 mX, uint16 mY, uint16 w, uint16 h) const; + bool isIn(const MapObject &obj) const; }; enum MouthType { @@ -77,24 +95,31 @@ private: kMouthTypeKiss }; - struct ManagedMouth : public Position { + struct ManagedMouth : public MapObject { Mouth *mouth; + MouthType type; - ManagedMouth(uint16 pX, uint16 pY, MouthType t); + ManagedMouth(uint16 tX, uint16 tY, MouthType t); ~ManagedMouth(); }; - struct ManagedSub : public Position { + struct ManagedSub : public MapObject { Submarine *sub; - uint16 mapX; - uint16 mapY; - - ManagedSub(uint16 pX, uint16 pY); + ManagedSub(uint16 tX, uint16 tY); ~ManagedSub(); + }; - void setPosition(uint16 pX, uint16 pY); + struct ManagedEnemy : public MapObject { + ANIObject *enemy; + + bool dead; + + ManagedEnemy(); + ~ManagedEnemy(); + + void clear(); }; enum Keys { @@ -130,19 +155,24 @@ private: uint8 _floor; Surface *_map; - bool _walkMap[kMapWidth * kMapHeight]; ManagedSub *_sub; - Common::List _exits; - Common::List _shields; + Common::List _walls; + Common::List _exits; + Common::List _shields; Common::List _mouths; + ManagedEnemy _enemies[kEnemyCount]; + + Common::List _blockingObjects; + SoundDesc _soundShield; SoundDesc _soundBite; SoundDesc _soundKiss; SoundDesc _soundShoot; SoundDesc _soundExit; + SoundDesc _soundExplode; bool _isPlaying; @@ -161,18 +191,21 @@ private: void drawFloorText(); void drawEndText(); + bool isBlocked(const MapObject &self, int16 x, int16 y, + const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; + void findPath(MapObject &obj, int x, int y, + const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; + void updateAnims(); void checkInput(); + Submarine::Direction getDirection(int &x, int &y) const; + void handleSub(); void subMove(int x, int y, Submarine::Direction direction); void subShoot(); - Submarine::Direction getDirection(int &x, int &y) const; - - bool isWalkable(int16 x, int16 y) const; - void checkExits(); void checkShields(); void checkMouths(); @@ -182,6 +215,12 @@ private: void checkExited(); + void enemiesCreate(); + void enemiesMove(); + void enemyMove(ManagedEnemy &enemy, int x, int y); + void enemyAttack(ManagedEnemy &enemy); + void enemyExplode(ManagedEnemy &enemy); + bool isDead() const; bool hasWon() const; diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index 9c12a56a85..cbe5f21eff 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -90,6 +90,9 @@ void Submarine::shoot() { } void Submarine::die() { + if (!canMove()) + return; + _state = kStateDie; setAnimation(directionToExplode(_direction)); -- cgit v1.2.3 From c414baa35d4cc4b11929d9c4995a1027d16f59e6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 8 Jun 2012 05:16:01 +0200 Subject: GOB: Implement shooting in Penetration Geisha's Penetration minigame should be complete now. This also means that Geisha is now basically complete. The only thing missing is the MDYPlayer, but since the music is only played once during the title screen, and it has a PCM-based fallback (which is currently played), this is low priority. --- engines/gob/minigames/geisha/penetration.cpp | 257 ++++++++++++++++++++++++--- engines/gob/minigames/geisha/penetration.h | 34 +++- engines/gob/minigames/geisha/submarine.cpp | 4 + engines/gob/minigames/geisha/submarine.h | 2 + 4 files changed, 270 insertions(+), 27 deletions(-) diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 656e90a45b..3be9f1f651 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -55,7 +55,15 @@ enum Sprite { kSpriteFloor = 30, kSpriteWall = 31, kSpriteMouthBite = 32, - kSpriteMouthKiss = 33 + kSpriteMouthKiss = 33, + kSpriteBulletN = 65, + kSpriteBulletS = 66, + kSpriteBulletW = 67, + kSpriteBulletE = 68, + kSpriteBulletSW = 85, + kSpriteBulletSE = 86, + kSpriteBulletNW = 87, + kSpriteBulletNE = 88 }; enum Animation { @@ -437,6 +445,20 @@ void Penetration::ManagedEnemy::clear() { } +Penetration::ManagedBullet::ManagedBullet() : MapObject(0, 0, 0, 0), bullet(0) { +} + +Penetration::ManagedBullet::~ManagedBullet() { + delete bullet; +} + +void Penetration::ManagedBullet::clear() { + delete bullet; + + bullet = 0; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) { @@ -477,6 +499,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) { enemiesCreate(); + bulletsMove(); updateAnims(); // Draw, fade in if necessary and wait for the end of the frame @@ -494,6 +517,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { enemiesMove(); checkExited(); + + if (_shotCoolDown > 0) + _shotCoolDown--; } deinit(); @@ -543,6 +569,8 @@ void Penetration::init() { _floor = 0; + _shotCoolDown = 0; + createMap(); } @@ -576,6 +604,8 @@ void Penetration::clearMap() { for (int i = 0; i < kEnemyCount; i++) _enemies[i].clear(); + for (int i = 0; i < kMaxBulletCount; i++) + _bullets[i].clear(); delete _sub; @@ -716,6 +746,18 @@ void Penetration::createMap() { _blockingObjects.push_back(&_enemies[i]); _mapAnims.push_back(_enemies[i].enemy); } + + // Bullets + for (int i = 0; i < kMaxBulletCount; i++) { + _bullets[i].bullet = new ANIObject(*_sprites); + + _bullets[i].bullet->setPause(true); + _bullets[i].bullet->setVisible(false); + + _bullets[i].isBlocking = false; + + _mapAnims.push_back(_bullets[i].bullet); + } } void Penetration::drawFloorText() { @@ -868,8 +910,8 @@ void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) { if ((x == 0) && (y == 0)) return; - bool touchedSub; - findPath(enemy, x, y, _sub, &touchedSub); + MapObject *blockedBy; + findPath(enemy, x, y, &blockedBy); enemy.setTileFromMapPosition(); @@ -878,7 +920,7 @@ void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) { enemy.enemy->setPosition(posX, posY); - if (touchedSub) + if (blockedBy == _sub) enemyAttack(enemy); } @@ -918,7 +960,8 @@ void Penetration::enemyAttack(ManagedEnemy &enemy) { } void Penetration::enemyExplode(ManagedEnemy &enemy) { - enemy.dead = true; + enemy.dead = true; + enemy.isBlocking = false; bool isSquare = enemy.enemy->getAnimation() == kAnimationEnemySquare; @@ -982,8 +1025,7 @@ void Penetration::handleSub() { subShoot(); } -bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, - const MapObject *checkBlockedBy, bool *blockedBy) const { +bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, MapObject **blockedBy) { if ((x < 0) || (y < 0)) return true; @@ -996,9 +1038,8 @@ bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, checkSelf.mapX = x; checkSelf.mapY = y; - bool blocked = false; - for (Common::List::const_iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) { - const MapObject &obj = **o; + for (Common::List::iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) { + MapObject &obj = **o; if (&obj == &self) continue; @@ -1007,21 +1048,19 @@ bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, continue; if (obj.isIn(checkSelf) || checkSelf.isIn(obj)) { - blocked = true; + if (blockedBy && !*blockedBy) + *blockedBy = &obj; - if (checkBlockedBy && blockedBy && (&obj == checkBlockedBy)) - *blockedBy = true; + return true; } } - return blocked; + return false; } -void Penetration::findPath(MapObject &obj, int x, int y, - const MapObject *checkBlockedBy, bool *blockedBy) const { - +void Penetration::findPath(MapObject &obj, int x, int y, MapObject **blockedBy) { if (blockedBy) - *blockedBy = false; + *blockedBy = 0; while ((x != 0) || (y != 0)) { uint16 oldX = obj.mapX; @@ -1036,7 +1075,7 @@ void Penetration::findPath(MapObject &obj, int x, int y, x++; } - if (!isBlocked(obj, newX, obj.mapY, checkBlockedBy, blockedBy)) + if (!isBlocked(obj, newX, obj.mapY, blockedBy)) obj.mapX = newX; uint16 newY = obj.mapY; @@ -1048,7 +1087,7 @@ void Penetration::findPath(MapObject &obj, int x, int y, y++; } - if (!isBlocked(obj, obj.mapX, newY, checkBlockedBy, blockedBy)) + if (!isBlocked(obj, obj.mapX, newY, blockedBy)) obj.mapY = newY; if ((obj.mapX == oldX) && (obj.mapY == oldY)) @@ -1078,9 +1117,185 @@ void Penetration::subShoot() { if (!_sub->sub->canMove() || _sub->sub->isShooting()) return; - _sub->sub->shoot(); + if (_shotCoolDown > 0) + return; + + // Creating a bullet + int slot = findEmptyBulletSlot(); + if (slot < 0) + return; + + ManagedBullet &bullet = _bullets[slot]; + bullet.bullet->setAnimation(directionToBullet(_sub->sub->getDirection())); + + setBulletPosition(*_sub, bullet); + + const int posX = kPlayAreaBorderWidth + bullet.mapX; + const int posY = kPlayAreaBorderHeight + bullet.mapY; + + bullet.bullet->setPosition(posX, posY); + bullet.bullet->setVisible(true); + + // Shooting + _sub->sub->shoot(); _vm->_sound->blasterPlay(&_soundShoot, 1, 0); + + _shotCoolDown = 3; +} + +void Penetration::setBulletPosition(const ManagedSub &sub, ManagedBullet &bullet) const { + bullet.mapX = sub.mapX; + bullet.mapY= sub.mapY; + + int16 sWidth, sHeight; + sub.sub->getFrameSize(sWidth, sHeight); + + int16 bWidth, bHeight; + bullet.bullet->getFrameSize(bWidth, bHeight); + + switch (sub.sub->getDirection()) { + case Submarine::kDirectionN: + bullet.mapX += sWidth / 2; + bullet.mapY -= bHeight; + + bullet.deltaX = 0; + bullet.deltaY = -8; + break; + + case Submarine::kDirectionNE: + bullet.mapX += sWidth; + bullet.mapY -= bHeight * 2; + + bullet.deltaX = 8; + bullet.deltaY = -8; + break; + + case Submarine::kDirectionE: + bullet.mapX += sWidth; + bullet.mapY += sHeight / 2 - bHeight; + + bullet.deltaX = 8; + bullet.deltaY = 0; + break; + + case Submarine::kDirectionSE: + bullet.mapX += sWidth; + bullet.mapY += sHeight; + + bullet.deltaX = 8; + bullet.deltaY = 8; + break; + + case Submarine::kDirectionS: + bullet.mapX += sWidth / 2; + bullet.mapY += sHeight; + + bullet.deltaX = 0; + bullet.deltaY = 8; + break; + + case Submarine::kDirectionSW: + bullet.mapX -= bWidth; + bullet.mapY += sHeight; + + bullet.deltaX = -8; + bullet.deltaY = 8; + break; + + case Submarine::kDirectionW: + bullet.mapX -= bWidth; + bullet.mapY += sHeight / 2 - bHeight; + + bullet.deltaX = -8; + bullet.deltaY = 0; + break; + + case Submarine::kDirectionNW: + bullet.mapX -= bWidth; + bullet.mapY -= bHeight; + + bullet.deltaX = -8; + bullet.deltaY = -8; + break; + + default: + break; + } +} + +uint16 Penetration::directionToBullet(Submarine::Direction direction) const { + switch (direction) { + case Submarine::kDirectionN: + return kSpriteBulletN; + + case Submarine::kDirectionNE: + return kSpriteBulletNE; + + case Submarine::kDirectionE: + return kSpriteBulletE; + + case Submarine::kDirectionSE: + return kSpriteBulletSE; + + case Submarine::kDirectionS: + return kSpriteBulletS; + + case Submarine::kDirectionSW: + return kSpriteBulletSW; + + case Submarine::kDirectionW: + return kSpriteBulletW; + + case Submarine::kDirectionNW: + return kSpriteBulletNW; + + default: + break; + } + + return 0; +} + +int Penetration::findEmptyBulletSlot() const { + for (int i = 0; i < kMaxBulletCount; i++) + if (!_bullets[i].bullet->isVisible()) + return i; + + return -1; +} + +void Penetration::bulletsMove() { + for (int i = 0; i < kMaxBulletCount; i++) + if (_bullets[i].bullet->isVisible()) + bulletMove(_bullets[i]); +} + +void Penetration::bulletMove(ManagedBullet &bullet) { + MapObject *blockedBy; + findPath(bullet, bullet.deltaX, bullet.deltaY, &blockedBy); + + if (blockedBy) { + checkShotEnemy(*blockedBy); + bullet.bullet->setVisible(false); + return; + } + + const int posX = kPlayAreaBorderWidth + bullet.mapX; + const int posY = kPlayAreaBorderHeight + bullet.mapY; + + bullet.bullet->setPosition(posX, posY); +} + +void Penetration::checkShotEnemy(MapObject &shotObject) { + for (int i = 0; i < kEnemyCount; i++) { + ManagedEnemy &enemy = _enemies[i]; + + if ((&enemy == &shotObject) && !enemy.dead && enemy.enemy->isVisible()) { + enemyExplode(enemy); + return; + } + } } Submarine::Direction Penetration::getDirection(int &x, int &y) const { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 9abae258b2..50004eba8e 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -65,7 +65,8 @@ private: static const byte kPalettes[kFloorCount][3 * kPaletteSize]; static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; - static const int kEnemyCount = 9; + static const int kEnemyCount = 9; + static const int kMaxBulletCount = 10; struct MapObject { uint16 tileX; @@ -122,6 +123,18 @@ private: void clear(); }; + struct ManagedBullet : public MapObject { + ANIObject *bullet; + + int16 deltaX; + int16 deltaY; + + ManagedBullet(); + ~ManagedBullet(); + + void clear(); + }; + enum Keys { kKeyUp = 0, kKeyDown, @@ -163,10 +176,13 @@ private: Common::List _shields; Common::List _mouths; - ManagedEnemy _enemies[kEnemyCount]; + ManagedEnemy _enemies[kEnemyCount]; + ManagedBullet _bullets[kMaxBulletCount]; Common::List _blockingObjects; + uint8 _shotCoolDown; + SoundDesc _soundShield; SoundDesc _soundBite; SoundDesc _soundKiss; @@ -191,10 +207,8 @@ private: void drawFloorText(); void drawEndText(); - bool isBlocked(const MapObject &self, int16 x, int16 y, - const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; - void findPath(MapObject &obj, int x, int y, - const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; + bool isBlocked(const MapObject &self, int16 x, int16 y, MapObject **blockedBy = 0); + void findPath(MapObject &obj, int x, int y, MapObject **blockedBy = 0); void updateAnims(); @@ -206,6 +220,14 @@ private: void subMove(int x, int y, Submarine::Direction direction); void subShoot(); + int findEmptyBulletSlot() const; + uint16 directionToBullet(Submarine::Direction direction) const; + void setBulletPosition(const ManagedSub &sub, ManagedBullet &bullet) const; + + void bulletsMove(); + void bulletMove(ManagedBullet &bullet); + void checkShotEnemy(MapObject &shotObject); + void checkExits(); void checkShields(); void checkMouths(); diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index cbe5f21eff..d16761cb7c 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -58,6 +58,10 @@ Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) { Submarine::~Submarine() { } +Submarine::Direction Submarine::getDirection() const { + return _direction; +} + void Submarine::turn(Direction to) { // Nothing to do if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to))) diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index 8a6d679bdd..a6eae57095 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -47,6 +47,8 @@ public: Submarine(const ANIFile &ani); ~Submarine(); + Direction getDirection() const; + /** Turn to the specified direction. */ void turn(Direction to); -- cgit v1.2.3 From 18dd5e5128dcff623830ed43916828bc5cde1969 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 8 Jun 2012 08:30:32 +0200 Subject: SCI: Fix mouse up events Regression from 906f0248317e1a4167190a666fe308a09334bfac. Fixes bug #3533069. --- engines/sci/event.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp index 378e88b7df..14443db1e2 100644 --- a/engines/sci/event.cpp +++ b/engines/sci/event.cpp @@ -102,8 +102,8 @@ const MouseEventConversion mouseEventMappings[] = { { Common::EVENT_RBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 2 }, { Common::EVENT_MBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 3 }, { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 1 }, - { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 2 }, - { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 3 } + { Common::EVENT_RBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 2 }, + { Common::EVENT_MBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 3 } }; EventManager::EventManager(bool fontIsExtended) : _fontIsExtended(fontIsExtended) { -- cgit v1.2.3 From a643981a385b20ef71a4d1987965f5d1b73fdadc Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 8 Jun 2012 11:57:43 +0300 Subject: SCI: Handle resource ID -1 when setting the palVary resource Fixes several wrong colors in SQ6 --- engines/sci/graphics/palette.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index 47d1647c6c..ea154c5037 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -698,7 +698,7 @@ void GfxPalette::palVaryInit() { } bool GfxPalette::palVaryLoadTargetPalette(GuiResourceId resourceId) { - _palVaryResourceId = resourceId; + _palVaryResourceId = (resourceId != 65535) ? resourceId : -1; Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), false); if (palResource) { // Load and initialize destination palette -- cgit v1.2.3 From c735b2acda10dcf2225a38cb50a69c840b6662bc Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 8 Jun 2012 14:32:13 -0400 Subject: SCUMM: Give football u32 opcodes proper names --- engines/scumm/he/logic/football.cpp | 57 +++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp index 5a0d423508..87efd7cfb2 100644 --- a/engines/scumm/he/logic/football.cpp +++ b/engines/scumm/he/logic/football.cpp @@ -38,14 +38,14 @@ public: int32 dispatch(int op, int numArgs, int32 *args); private: - int op_1004(int32 *args); - int op_1006(int32 *args); - int op_1007(int32 *args); - int op_1010(int32 *args); - int op_1022(int32 *args); - int op_1023(int32 *args); - int op_1024(int32 *args); - int op_1028(); + int lineEquation3D(int32 *args); + int translateWorldToScreen(int32 *args); + int fieldGoalScreenTranslation(int32 *args); + int translateScreenToWorld(int32 *args); + int nextPoint(int32 *args); + int computePlayerBallIntercepts(int32 *args); + int computeTwoCircleIntercepts(int32 *args); + int largestFreeBlock(); }; int LogicHEfootball::versionID() { @@ -57,36 +57,36 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) { switch (op) { case 1004: - res = op_1004(args); + res = lineEquation3D(args); break; case 1006: - res = op_1006(args); + res = translateWorldToScreen(args); break; case 1007: - res = op_1007(args); + res = fieldGoalScreenTranslation(args); break; case 1010: - res = op_1010(args); + res = translateScreenToWorld(args); break; case 1022: - res = op_1022(args); + res = nextPoint(args); break; case 1023: - res = op_1023(args); + res = computePlayerBallIntercepts(args); break; case 1024: - res = op_1024(args); + res = computeTwoCircleIntercepts(args); break; case 1028: // Backyard Football 2002 only - res = op_1028(); + res = largestFreeBlock(); break; case 8221968: @@ -129,8 +129,8 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) { return res; } -int LogicHEfootball::op_1004(int32 *args) { - // Identical to LogicHEsoccer::op_1004 +int LogicHEfootball::lineEquation3D(int32 *args) { + // Identical to soccer's 1004 opcode double res, a2, a4, a5; a5 = ((double)args[4] - (double)args[1]) / ((double)args[5] - (double)args[2]); @@ -147,8 +147,8 @@ int LogicHEfootball::op_1004(int32 *args) { return 1; } -int LogicHEfootball::op_1006(int32 *args) { - // This seems to be more or less the inverse of op_1010 +int LogicHEfootball::translateWorldToScreen(int32 *args) { + // This is more or less the inverse of translateScreenToWorld const double a1 = args[1]; double res; @@ -173,7 +173,7 @@ int LogicHEfootball::op_1006(int32 *args) { return 1; } -int LogicHEfootball::op_1007(int32 *args) { +int LogicHEfootball::fieldGoalScreenTranslation(int32 *args) { double res, temp; temp = (double)args[1] * 0.32; @@ -194,8 +194,8 @@ int LogicHEfootball::op_1007(int32 *args) { return 1; } -int LogicHEfootball::op_1010(int32 *args) { - // This seems to be more or less the inverse of op_1006 +int LogicHEfootball::translateScreenToWorld(int32 *args) { + // This is more or less the inverse of translateWorldToScreen double a1 = (640.0 - (double)args[1] - 26.0) / 1.1588235e-1; // 2.9411764e-4 = 1/3400 @@ -211,7 +211,7 @@ int LogicHEfootball::op_1010(int32 *args) { return 1; } -int LogicHEfootball::op_1022(int32 *args) { +int LogicHEfootball::nextPoint(int32 *args) { double res; double var10 = args[4] - args[1]; double var8 = args[5] - args[2]; @@ -232,7 +232,7 @@ int LogicHEfootball::op_1022(int32 *args) { return 1; } -int LogicHEfootball::op_1023(int32 *args) { +int LogicHEfootball::computePlayerBallIntercepts(int32 *args) { double var10, var18, var20, var28, var30, var30_; double argf[7]; @@ -278,7 +278,8 @@ int LogicHEfootball::op_1023(int32 *args) { return 1; } -int LogicHEfootball::op_1024(int32 *args) { +int LogicHEfootball::computeTwoCircleIntercepts(int32 *args) { + // Looks like this was just dummied out writeScummVar(108, 0); writeScummVar(109, 0); writeScummVar(110, 0); @@ -287,8 +288,10 @@ int LogicHEfootball::op_1024(int32 *args) { return 1; } -int LogicHEfootball::op_1028() { +int LogicHEfootball::largestFreeBlock() { // Backyard Football 2002 only + // The Windows version always sets the variable to this + // The Mac version actually checks for the largest free block writeScummVar(108, 100000000); return 1; } -- cgit v1.2.3 From f22661e4b931609609fb785b503c1e534bfe14d7 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 8 Jun 2012 19:45:31 -0400 Subject: SCUMM: Stub off other football2002 u32 opcodes --- engines/scumm/detection_tables.h | 2 +- engines/scumm/he/logic/football.cpp | 100 +++++++++++++++++++++++++++++++----- engines/scumm/he/logic_he.cpp | 3 ++ engines/scumm/he/logic_he.h | 1 + engines/scumm/scumm.h | 1 + 5 files changed, 94 insertions(+), 13 deletions(-) diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 452a6f0960..c84681e266 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -384,7 +384,7 @@ static const GameSettings gameVariantsTable[] = { // Added the use of bink videos {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, - {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, + {"football2002", 0, 0, GID_FOOTBALL2002, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, // U32 code required, for testing only diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp index 87efd7cfb2..73f9161d95 100644 --- a/engines/scumm/he/logic/football.cpp +++ b/engines/scumm/he/logic/football.cpp @@ -35,17 +35,16 @@ public: LogicHEfootball(ScummEngine_v90he *vm) : LogicHE(vm) {} int versionID(); - int32 dispatch(int op, int numArgs, int32 *args); + virtual int32 dispatch(int op, int numArgs, int32 *args); -private: +protected: int lineEquation3D(int32 *args); - int translateWorldToScreen(int32 *args); + virtual int translateWorldToScreen(int32 *args); int fieldGoalScreenTranslation(int32 *args); - int translateScreenToWorld(int32 *args); + virtual int translateScreenToWorld(int32 *args); int nextPoint(int32 *args); int computePlayerBallIntercepts(int32 *args); int computeTwoCircleIntercepts(int32 *args); - int largestFreeBlock(); }; int LogicHEfootball::versionID() { @@ -84,11 +83,6 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) { res = computeTwoCircleIntercepts(args); break; - case 1028: - // Backyard Football 2002 only - res = largestFreeBlock(); - break; - case 8221968: // Someone had a fun and used his birthday as opcode number res = getFromArray(args[0], args[1], args[2]); @@ -288,8 +282,86 @@ int LogicHEfootball::computeTwoCircleIntercepts(int32 *args) { return 1; } -int LogicHEfootball::largestFreeBlock() { - // Backyard Football 2002 only +class LogicHEfootball2002 : public LogicHEfootball { +public: + LogicHEfootball2002(ScummEngine_v90he *vm) : LogicHEfootball(vm) {} + + int32 dispatch(int op, int numArgs, int32 *args); + +private: + int translateWorldToScreen(int32 *args); + int translateScreenToWorld(int32 *args); + int getDayOfWeek(); + int initScreenTranslations(); + int getPlaybookFiles(int32 *args); + int largestFreeBlock(); +}; + +int32 LogicHEfootball2002::dispatch(int op, int numArgs, int32 *args) { + int32 res = 0; + + switch (op) { + case 1025: + res = getDayOfWeek(); + break; + + case 1026: + res = initScreenTranslations(); + break; + + case 1027: + res = getPlaybookFiles(args); + break; + + case 1028: + res = largestFreeBlock(); + break; + + case 1029: + // Clean-up off heap + // Dummied in the Windows U32 + res = 1; + break; + + case 1516: + // Start auto LAN game + break; + + default: + res = LogicHEfootball::dispatch(op, numArgs, args); + break; + } + + return res; +} + +int LogicHEfootball2002::translateWorldToScreen(int32 *args) { + // TODO: Implement modified 2002 version + return LogicHEfootball::translateWorldToScreen(args); +} + +int LogicHEfootball2002::translateScreenToWorld(int32 *args) { + // TODO: Implement modified 2002 version + return LogicHEfootball::translateScreenToWorld(args); +} + +int LogicHEfootball2002::getDayOfWeek() { + // TODO: Get day of week, store in var 108 + return 1; +} + +int LogicHEfootball2002::initScreenTranslations() { + // TODO: Set values used by translateWorldToScreen/translateScreenToWorld + return 1; +} + +int LogicHEfootball2002::getPlaybookFiles(int32 *args) { + // TODO: Get list of playbook files + error("STUB: LogicHEfootball2002::getPlaybookFiles()"); + return 1; +} + +int LogicHEfootball2002::largestFreeBlock() { // The Windows version always sets the variable to this // The Mac version actually checks for the largest free block writeScummVar(108, 100000000); @@ -300,4 +372,8 @@ LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm) { return new LogicHEfootball(vm); } +LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm) { + return new LogicHEfootball2002(vm); +} + } // End of namespace Scumm diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp index a76c393e13..0f9454ba28 100644 --- a/engines/scumm/he/logic_he.cpp +++ b/engines/scumm/he/logic_he.cpp @@ -87,6 +87,9 @@ LogicHE *LogicHE::makeLogicHE(ScummEngine_v90he *vm) { case GID_FOOTBALL: return makeLogicHEfootball(vm); + case GID_FOOTBALL2002: + return makeLogicHEfootball2002(vm); + case GID_SOCCER: case GID_SOCCERMLS: case GID_SOCCER2004: diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h index 893dc81b87..93c0569a4f 100644 --- a/engines/scumm/he/logic_he.h +++ b/engines/scumm/he/logic_he.h @@ -61,6 +61,7 @@ protected: LogicHE *makeLogicHErace(ScummEngine_v90he *vm); LogicHE *makeLogicHEfunshop(ScummEngine_v90he *vm); LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm); +LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm); LogicHE *makeLogicHEsoccer(ScummEngine_v90he *vm); LogicHE *makeLogicHEbaseball2001(ScummEngine_v90he *vm); LogicHE *makeLogicHEbasketball(ScummEngine_v90he *vm); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 8c0070b5f5..c8cf096a19 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -241,6 +241,7 @@ enum ScummGameId { GID_PUTTRACE, GID_FUNSHOP, // Used for all three funshops GID_FOOTBALL, + GID_FOOTBALL2002, GID_SOCCER, GID_SOCCERMLS, GID_SOCCER2004, -- cgit v1.2.3 From e8ab1f5088fad1de4e8fa5d56bb1c518ee1008a8 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 8 Jun 2012 22:22:38 -0400 Subject: SCUMM: Implement listing playbook files in football2002 --- engines/scumm/he/intern_he.h | 8 +++++--- engines/scumm/he/logic/football.cpp | 28 ++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index cdc5faa084..fc5e4bcdf0 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -187,6 +187,8 @@ public: Wiz *_wiz; + virtual int setupStringArray(int size); + protected: virtual void setupOpcodes(); @@ -201,7 +203,6 @@ protected: virtual void clearDrawQueues(); int getStringCharWidth(byte chr); - virtual int setupStringArray(int size); void appendSubstring(int dst, int src, int len2, int len); void adjustRect(Common::Rect &rect); @@ -258,6 +259,9 @@ public: virtual void resetScumm(); + virtual byte *getStringAddress(ResId idx); + virtual int setupStringArray(int size); + protected: virtual void setupOpcodes(); @@ -265,7 +269,6 @@ protected: virtual void resetScummVars(); virtual void readArrayFromIndexFile(); - virtual byte *getStringAddress(ResId idx); virtual void readMAXS(int blockSize); virtual void redrawBGAreas(); @@ -280,7 +283,6 @@ protected: void copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end, int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end); void copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num); - virtual int setupStringArray(int size); int readFileToArray(int slot, int32 size); void writeFileFromArray(int slot, int32 resID); diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp index 73f9161d95..f67e07c475 100644 --- a/engines/scumm/he/logic/football.cpp +++ b/engines/scumm/he/logic/football.cpp @@ -20,6 +20,8 @@ * */ +#include "common/savefile.h" + #include "scumm/he/intern_he.h" #include "scumm/he/logic_he.h" @@ -356,8 +358,30 @@ int LogicHEfootball2002::initScreenTranslations() { } int LogicHEfootball2002::getPlaybookFiles(int32 *args) { - // TODO: Get list of playbook files - error("STUB: LogicHEfootball2002::getPlaybookFiles()"); + // Get the pattern and then skip over the directory prefix ("*\" or "*:") + Common::String pattern = (const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2; + + // Prepare a buffer to hold the file names + char buffer[1000]; + buffer[0] = 0; + + // Get the list of file names that match the pattern and iterate over it + Common::StringArray fileList = _vm->getSaveFileManager()->listSavefiles(pattern); + + for (uint32 i = 0; i < fileList.size() && strlen(buffer) < 970; i++) { + // Isolate the base part of the filename and concatenate it to our buffer + Common::String fileName = Common::String(fileList[i].c_str(), fileList[i].size() - (pattern.size() - 1)); + strcat(buffer, fileName.c_str()); + strcat(buffer, ">"); // names separated by '>' + } + + // Now store the result in an array + int array = _vm->setupStringArray(strlen(buffer)); + strcpy((char *)_vm->getStringAddress(array), buffer); + + // And store the array index in variable 108 + writeScummVar(108, array); + return 1; } -- cgit v1.2.3 From 6559a74dac3a267198e41b187401fa03859782ee Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 9 Jun 2012 04:55:11 +0200 Subject: NEWS: Add Geisha to the supported games --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index ed98cdc83f..916262f5d6 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ For a more comprehensive changelog of the latest experimental code, see: - Added support for Blue Force. - Added support for Darby the Dragon. - Added support for Dreamweb. + - Added support for Geisha. - Added support for Gregory and the Hot Air Balloon. - Added support for Magic Tales: Baba Yaga and the Magic Geese. - Added support for Magic Tales: Imo and the King. -- cgit v1.2.3 From 8675f510012d0ebbd02e7f90adf6c7195a7f9e4b Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 8 Jun 2012 23:06:58 -0400 Subject: NEWS: Fix a typo --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 916262f5d6..7ce4f255dd 100644 --- a/NEWS +++ b/NEWS @@ -29,7 +29,7 @@ For a more comprehensive changelog of the latest experimental code, see: Engine tab when adding or editing a configuration for a game. In most cases, you will have to run each game once or readd them all in ScummVM's launcher in order to get the custom options tab. - - Improved predicitve dialog look. + - Improved predictive dialog look. - Various GUI improvements. SDL ports: -- cgit v1.2.3 From 3968f3194893d88d1a8d73eef535b801e5415765 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Sat, 9 Jun 2012 15:36:47 +1000 Subject: SCUMM: Add HE101 version, for debugInput opcode difference in some HE100 games. --- engines/scumm/detection_tables.h | 9 ++++++--- engines/scumm/he/script_v100he.cpp | 5 +++-- engines/scumm/he/sound_he.cpp | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index c84681e266..be1b90e356 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -382,14 +382,16 @@ static const GameSettings gameVariantsTable[] = { {"pjgames", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, // Added the use of bink videos - {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, - {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, - {"football2002", 0, 0, GID_FOOTBALL2002, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, // U32 code required, for testing only {"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"moonbase", "Demo", 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR | GF_DEMO, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, + + // HE100 games, which use older o72_debugInput code + {"Baseball2003", 0, 0, GID_BASEBALL2003, 6, 101, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, + {"basketball", 0, 0, GID_BASKETBALL, 6, 101, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, + {"football2002", 0, 0, GID_FOOTBALL2002, 6, 101, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, #endif // The following are meant to be generic HE game variants and as such do @@ -407,6 +409,7 @@ static const GameSettings gameVariantsTable[] = { {"", "HE 98.5", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_HE_985, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"", "HE 99", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, {"", "HE 100", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, + {"", "HE 101", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY, UNK, GUIO3(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI, GUIO_NOASPECT)}, #endif {NULL, NULL, 0, 0, 0, MDT_NONE, 0, 0, UNK, 0} }; diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index d2e01a6564..3e2053790e 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -2339,8 +2339,9 @@ void ScummEngine_v100he::o100_writeFile() { } void ScummEngine_v100he::o100_debugInput() { - // Backyard Basketball uses older code for this opcode - if (_game.id == GID_BASKETBALL) { + // Backyard Baseball 2003 / Basketball / Football 2002 + // use older o72_debugInput code + if (_game.heversion == 101) { ScummEngine_v72he::o72_debugInput(); return; } diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index 1007d2a7b0..f94b74ac45 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -65,7 +65,7 @@ void SoundHE::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlag if (_vm->VAR_LAST_SOUND != 0xFF) _vm->VAR(_vm->VAR_LAST_SOUND) = sound; - if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion == 100 && (heFlags & 8))) { + if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion >= 100 && (heFlags & 8))) { playHESound(sound, heOffset, heChannel, heFlags); return; } else { -- cgit v1.2.3 From 66af2cf1d729e5944641ab203f3d36761fdff132 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 9 Jun 2012 12:12:44 +0300 Subject: SCI: Handle translucent text planes Fixes the incorrect flood fill in the Rada Drums screen in GK1 --- engines/sci/graphics/frameout.cpp | 23 ++++++++++++++--------- engines/sci/graphics/text32.cpp | 9 ++++++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 450581000b..a5bd8ba48e 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -53,6 +53,11 @@ namespace Sci { // TODO/FIXME: This is all guesswork +enum SciSpeciaPlanelPictureCodes { + kPlaneTranslucent = 0xfffe, // -2 + kPlanePlainColored = 0xffff // -1 +}; + GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette *palette, GfxPaint32 *paint32) : _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) { @@ -137,7 +142,7 @@ void GfxFrameout::kernelAddPlane(reg_t object) { newPlane.lastPriority = 0xFFFF; // hidden newPlane.planeOffsetX = 0; newPlane.planeOffsetY = 0; - newPlane.pictureId = 0xFFFF; + newPlane.pictureId = kPlanePlainColored; newPlane.planePictureMirrored = false; newPlane.planeBack = 0; _planes.push_back(newPlane); @@ -155,7 +160,8 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) { if (lastPictureId != it->pictureId) { // picture got changed, load new picture deletePlanePictures(object); - if ((it->pictureId != 0xFFFF) && (it->pictureId != 0xFFFE)) { + // Draw the plane's picture if it's not a translucent/plane colored frame + if ((it->pictureId != kPlanePlainColored) && (it->pictureId != kPlaneTranslucent)) { // SQ6 gives us a bad picture number for the control menu if (_resMan->testResource(ResourceId(kResourceTypePic, it->pictureId))) addPlanePicture(object, it->pictureId, 0); @@ -248,6 +254,9 @@ void GfxFrameout::kernelDeletePlane(reg_t object) { } void GfxFrameout::addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY) { + if (pictureId == kPlanePlainColored || pictureId == kPlaneTranslucent) // sanity check + return; + PlanePictureEntry newPicture; newPicture.object = object; newPicture.pictureId = pictureId; @@ -574,21 +583,17 @@ void GfxFrameout::kernelFrameout() { // There is a race condition lurking in SQ6, which causes the game to hang in the intro, when teleporting to Polysorbate LX. // Since I first wrote the patch, the race has stopped occurring for me though. // I'll leave this for investigation later, when someone can reproduce. - //if (it->pictureId == 0xffff) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes) - if (it->planeBack) + //if (it->pictureId == kPlanePlainColored) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes) + if (it->pictureId == kPlanePlainColored && it->planeBack) _paint32->fillRect(it->planeRect, it->planeBack); - GuiResourceId planeMainPictureId = it->pictureId; - _coordAdjuster->pictureSetDisplayArea(it->planeRect); - _palette->drewPicture(planeMainPictureId); + _palette->drewPicture(it->pictureId); FrameoutList itemList; createPlaneItemList(planeObject, itemList); -// warning("Plane %s", _segMan->getObjectName(planeObject)); - for (FrameoutList::iterator listIterator = itemList.begin(); listIterator != itemList.end(); listIterator++) { FrameoutEntry *itemEntry = *listIterator; diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index 8ac9582535..7907809c91 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -205,7 +205,7 @@ void GfxText32::drawScrollTextBitmap(reg_t textObject, reg_t hunkId, uint16 x, u } void GfxText32::drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, reg_t textObject, reg_t hunkId) { - uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back)); + int16 backColor = (int16)readSelectorValue(_segMan, textObject, SELECTOR(back)); // Sanity check: Check if the hunk is set. If not, either the game scripts // didn't set it, or an old saved game has been loaded, where it wasn't set. if (hunkId.isNull()) @@ -227,7 +227,7 @@ void GfxText32::drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, byte *surface = memoryPtr + BITMAP_HEADER_SIZE; int curByte = 0; - uint16 skipColor = readSelectorValue(_segMan, textObject, SELECTOR(skip)); + int16 skipColor = (int16)readSelectorValue(_segMan, textObject, SELECTOR(skip)); uint16 textX = planeRect.left + x; uint16 textY = planeRect.top + y; // Get totalWidth, totalHeight @@ -240,10 +240,13 @@ void GfxText32::drawTextBitmapInternal(int16 x, int16 y, Common::Rect planeRect, textY = textY * _screen->getDisplayHeight() / _screen->getHeight(); } + bool translucent = (skipColor == -1 && backColor == -1); + for (int curY = 0; curY < height; curY++) { for (int curX = 0; curX < width; curX++) { byte pixel = surface[curByte++]; - if (pixel != skipColor && pixel != backColor) + if ((!translucent && pixel != skipColor && pixel != backColor) || + (translucent && pixel != 0xFF)) _screen->putFontPixel(textY, curX + textX, curY, pixel); } } -- cgit v1.2.3 From a693603e1ee1a58f2d4c72f726a9f92a3ddf1627 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sat, 9 Jun 2012 11:58:26 +0100 Subject: TOON: Replace Pathfinding _tempPath static buffers with Common::Array. --- engines/toon/path.cpp | 31 ++++++++++++++++++------------- engines/toon/path.h | 16 ++++++++++------ 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index b3f9b306be..b4fe412144 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -248,17 +248,19 @@ bool PathFinding::walkLine(int32 x, int32 y, int32 x2, int32 y2) { int32 cdx = (dx << 16) / t; int32 cdy = (dy << 16) / t; - _gridPathCount = 0; + _tempPath.clear(); + i32Point p; for (int32 i = t; i > 0; i--) { - _tempPathX[i] = bx >> 16; - _tempPathY[i] = by >> 16; - _gridPathCount++; + p.x = bx >> 16; + p.y = by >> 16; + _tempPath.insert_at(0, p); bx += cdx; by += cdy; } - _tempPathX[0] = x2; - _tempPathY[0] = y2; + p.x = x2; + p.y = y2; + _tempPath.insert_at(0, p); return true; } @@ -292,13 +294,13 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { debugC(1, kDebugPath, "findPath(%d, %d, %d, %d)", x, y, destx, desty); if (x == destx && y == desty) { - _gridPathCount = 0; + _tempPath.clear(); return true; } // ignore path finding if the character is outside the screen if (x < 0 || x > 1280 || y < 0 || y > 400 || destx < 0 || destx > 1280 || desty < 0 || desty > 400) { - _gridPathCount = 0; + _tempPath.clear(); return true; } @@ -357,7 +359,7 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { // let's see if we found a result ! if (!_gridTemp[destx + desty * _width]) { // didn't find anything - _gridPathCount = 0; + _tempPath.clear(); return false; } @@ -415,10 +417,13 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { numpath++; if ((bestX == x && bestY == y)) { - _gridPathCount = numpath; - - memcpy(_tempPathX, retPathX, sizeof(int32) * numpath); - memcpy(_tempPathY, retPathY, sizeof(int32) * numpath); + _tempPath.clear(); + i32Point p; + for (int32 i = 0; i < numpath; i++) { + p.x = retPathX[i]; + p.y = retPathY[i]; + _tempPath.push_back(p); + } retVal = true; break; diff --git a/engines/toon/path.h b/engines/toon/path.h index 26abb411cc..6a22096054 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -23,6 +23,8 @@ #ifndef TOON_PATH_H #define TOON_PATH_H +#include "common/array.h" + #include "toon/toon.h" namespace Toon { @@ -70,9 +72,9 @@ public: void addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2); void addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h); - int32 getPathNodeCount() const { return _gridPathCount; } - int32 getPathNodeX(int32 nodeId) const { return _tempPathX[ _gridPathCount - nodeId - 1]; } - int32 getPathNodeY(int32 nodeId) const { return _tempPathY[ _gridPathCount - nodeId - 1]; } + int32 getPathNodeCount() const { return _tempPath.size(); } + int32 getPathNodeX(int32 nodeId) const { return _tempPath[ _tempPath.size() - nodeId - 1].x; } + int32 getPathNodeY(int32 nodeId) const { return _tempPath[ _tempPath.size() - nodeId - 1].y; } private: static const uint8 kMaxBlockingRects = 16; @@ -85,9 +87,11 @@ private: int32 _width; int32 _height; - int32 _tempPathX[4096]; - int32 _tempPathY[4096]; - int32 _gridPathCount; + struct i32Point { + int32 x, y; + }; + + Common::Array _tempPath; int32 _blockingRects[kMaxBlockingRects][5]; uint8 _numBlockingRects; -- cgit v1.2.3 From fae9f4d5baf258ecb4f9e25fe1364e42442385e2 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sat, 9 Jun 2012 12:33:30 +0100 Subject: TOON: Replace Pathfinding retPath static buffers with Common::Array. --- engines/toon/path.cpp | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index b4fe412144..2b41995a98 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -366,20 +366,13 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { curX = destx; curY = desty; - int32 *retPathX = new int32[4096]; - int32 *retPathY = new int32[4096]; - if (!retPathX || !retPathY) { - delete retPathX; - delete retPathY; + Common::Array retPath; - error("[PathFinding::findPath] Cannot allocate pathfinding buffers"); - } - - int32 numpath = 0; + i32Point p; + p.x = curX; + p.y = curY; + retPath.push_back(p); - retPathX[numpath] = curX; - retPathY[numpath] = curY; - numpath++; int32 bestscore = sq[destx + desty * _width]; bool retVal = false; @@ -412,18 +405,15 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { if (bestX < 0 || bestY < 0) break; - retPathX[numpath] = bestX; - retPathY[numpath] = bestY; - numpath++; + i32Point pp; + pp.x = bestX; + pp.y = bestY; + retPath.push_back(pp); if ((bestX == x && bestY == y)) { _tempPath.clear(); - i32Point p; - for (int32 i = 0; i < numpath; i++) { - p.x = retPathX[i]; - p.y = retPathY[i]; - _tempPath.push_back(p); - } + for (uint32 i = 0; i < retPath.size(); i++) + _tempPath.push_back(retPath[i]); retVal = true; break; @@ -433,9 +423,6 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { curY = bestY; } - delete retPathX; - delete retPathY; - return retVal; } -- cgit v1.2.3 From dc11d223cdb156dd71300a8535cb5ab0940180c1 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 9 Jun 2012 15:36:36 +0300 Subject: SCI: Initial implementation of AddLine, UpdateLine, DeleteLine --- engines/sci/engine/kernel.h | 3 ++ engines/sci/engine/kernel_tables.h | 6 ++-- engines/sci/engine/kgraphics32.cpp | 32 +++++++++++++++++++ engines/sci/graphics/frameout.cpp | 63 ++++++++++++++++++++++++++++++++++++++ engines/sci/graphics/frameout.h | 15 +++++++++ 5 files changed, 116 insertions(+), 3 deletions(-) diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 664c97f7b5..d9fdbefbc2 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -482,6 +482,9 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv); reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv); reg_t kFont(EngineState *s, int argc, reg_t *argv); reg_t kBitmap(EngineState *s, int argc, reg_t *argv); +reg_t kAddLine(EngineState *s, int argc, reg_t *argv); +reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv); +reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv); // SCI3 Kernel functions reg_t kPlayDuck(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 254a479e65..9b765283ec 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -568,6 +568,9 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(SetFontRes), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(Font), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, { MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(AddLine), SIG_EVERYWHERE, "oiiiiiiiii", NULL, NULL }, + { MAP_CALL(UpdateLine), SIG_EVERYWHERE, "roiiiiiiiii", NULL, NULL }, + { MAP_CALL(DeleteLine), SIG_EVERYWHERE, "ro", NULL, NULL }, // SCI2.1 Empty Functions @@ -613,9 +616,6 @@ static SciKernelMapEntry s_kernelMap[] = { // SCI2.1 unmapped functions - TODO! // MovePlaneItems - used by SQ6 to scroll through the inventory via the up/down buttons - // AddLine - used by Torin's Passage to highlight the chapter buttons - // DeleteLine - used by Torin's Passage to delete the highlight from the chapter buttons - // UpdateLine - used by LSL6 // SetPalStyleRange - 2 integer parameters, start and end. All styles from start-end // (inclusive) are set to 0 // MorphOn - used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270) diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 71c4949d65..53cf8ada75 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -605,6 +605,38 @@ reg_t kEditText(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } +reg_t kAddLine(EngineState *s, int argc, reg_t *argv) { + reg_t plane = argv[0]; + Common::Point startPoint(argv[1].toUint16(), argv[2].toUint16()); + Common::Point endPoint(argv[3].toUint16(), argv[4].toUint16()); + // argv[5] is unknown (a number, usually 200) + byte color = (byte)argv[6].toUint16(); + byte priority = (byte)argv[7].toUint16(); + byte control = (byte)argv[8].toUint16(); + // argv[9] is unknown (usually a small number, 1 or 2). Thickness, perhaps? + return g_sci->_gfxFrameout->addPlaneLine(plane, startPoint, endPoint, color, priority, control); +} + +reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv) { + reg_t hunkId = argv[0]; + reg_t plane = argv[1]; + Common::Point startPoint(argv[2].toUint16(), argv[3].toUint16()); + Common::Point endPoint(argv[4].toUint16(), argv[5].toUint16()); + // argv[6] is unknown (a number, usually 200) + byte color = (byte)argv[7].toUint16(); + byte priority = (byte)argv[8].toUint16(); + byte control = (byte)argv[9].toUint16(); + // argv[10] is unknown (usually a small number, 1 or 2). Thickness, perhaps? + g_sci->_gfxFrameout->updatePlaneLine(plane, hunkId, startPoint, endPoint, color, priority, control); + return s->r_acc; +} +reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv) { + reg_t hunkId = argv[0]; + reg_t plane = argv[1]; + g_sci->_gfxFrameout->deletePlaneLine(plane, hunkId); + return s->r_acc; +} + #endif } // End of namespace Sci diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index a5bd8ba48e..db49497b6b 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -281,6 +281,56 @@ void GfxFrameout::deletePlanePictures(reg_t object) { } } +// Provides the same functionality as kGraph(DrawLine) +reg_t GfxFrameout::addPlaneLine(reg_t object, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) { + for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) { + if (it->object == object) { + PlaneLineEntry line; + line.hunkId = _segMan->allocateHunkEntry("PlaneLine()", 1); // we basically use this for a unique ID + line.startPoint = startPoint; + line.endPoint = endPoint; + line.color = color; + line.priority = priority; + line.control = control; + it->lines.push_back(line); + return line.hunkId; + } + } + + return NULL_REG; +} + +void GfxFrameout::updatePlaneLine(reg_t object, reg_t hunkId, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) { + for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) { + if (it->object == object) { + for (PlaneLineList::iterator it2 = it->lines.begin(); it2 != it->lines.end(); ++it2) { + if (it2->hunkId == hunkId) { + it2->startPoint = startPoint; + it2->endPoint = endPoint; + it2->color = color; + it2->priority = priority; + it2->control = control; + return; + } + } + } + } +} + +void GfxFrameout::deletePlaneLine(reg_t object, reg_t hunkId) { + for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); ++it) { + if (it->object == object) { + for (PlaneLineList::iterator it2 = it->lines.begin(); it2 != it->lines.end(); ++it2) { + if (it2->hunkId == hunkId) { + _segMan->freeHunkEntry(hunkId); + it2 = it->lines.erase(it2); + return; + } + } + } + } +} + void GfxFrameout::kernelAddScreenItem(reg_t object) { // Ignore invalid items if (!_segMan->isObject(object)) @@ -567,6 +617,19 @@ void GfxFrameout::kernelFrameout() { for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) { reg_t planeObject = it->object; + + // Draw any plane lines, if they exist + // These are drawn on invisible planes as well. (e.g. "invisiblePlane" in LSL6 hires) + // FIXME: Lines aren't always drawn (e.g. when the narrator speaks in LSL6 hires). + // Perhaps something is painted over them? + for (PlaneLineList::iterator it2 = it->lines.begin(); it2 != it->lines.end(); ++it2) { + Common::Point startPoint = it2->startPoint; + Common::Point endPoint = it2->endPoint; + _coordAdjuster->kernelLocalToGlobal(startPoint.x, startPoint.y, it->object); + _coordAdjuster->kernelLocalToGlobal(endPoint.x, endPoint.y, it->object); + _screen->drawLine(startPoint, endPoint, it2->color, it2->priority, it2->control); + } + uint16 planeLastPriority = it->lastPriority; // Update priority here, sq6 sets it w/o UpdatePlane diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 2d2ca6546c..0d80a68f1d 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -27,6 +27,17 @@ namespace Sci { class GfxPicture; +struct PlaneLineEntry { + reg_t hunkId; + Common::Point startPoint; + Common::Point endPoint; + byte color; + byte priority; + byte control; +}; + +typedef Common::List PlaneLineList; + struct PlaneEntry { reg_t object; uint16 priority; @@ -40,6 +51,7 @@ struct PlaneEntry { Common::Rect upscaledPlaneClipRect; bool planePictureMirrored; byte planeBack; + PlaneLineList lines; }; typedef Common::List PlaneList; @@ -112,6 +124,9 @@ public: void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY = 0); void deletePlanePictures(reg_t object); + reg_t addPlaneLine(reg_t object, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control); + void updatePlaneLine(reg_t object, reg_t hunkId, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control); + void deletePlaneLine(reg_t object, reg_t hunkId); void clear(); // Scroll text functions -- cgit v1.2.3 From 2d0cedab1ff3984d1d269c0fb735f9179ca8e7d9 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sat, 9 Jun 2012 13:43:42 +0100 Subject: TOON: Minor cleanups in Pathfinding class. No functional change. --- engines/toon/path.cpp | 41 ++++++++++++++++++++--------------------- engines/toon/path.h | 2 +- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 2b41995a98..dfdf095af9 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -150,7 +150,7 @@ PathFinding::PathFinding() { _width = 0; _height = 0; _heap = new PathFindingHeap(); - _gridTemp = NULL; + _sq = NULL; _numBlockingRects = 0; } @@ -158,7 +158,7 @@ PathFinding::~PathFinding(void) { if (_heap) _heap->unload(); delete _heap; - delete[] _gridTemp; + delete[] _sq; } void PathFinding::init(Picture *mask) { @@ -169,8 +169,8 @@ void PathFinding::init(Picture *mask) { _currentMask = mask; _heap->unload(); _heap->init(500); - delete[] _gridTemp; - _gridTemp = new int32[_width * _height]; + delete[] _sq; + _sq = new int32[_width * _height]; } bool PathFinding::isLikelyWalkable(int32 x, int32 y) { @@ -311,23 +311,22 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { } // no direct line, we use the standard A* algorithm - memset(_gridTemp , 0, _width * _height * sizeof(int32)); + memset(_sq , 0, _width * _height * sizeof(int32)); _heap->clear(); int32 curX = x; int32 curY = y; int32 curWeight = 0; - int32 *sq = _gridTemp; - sq[curX + curY *_width] = 1; + _sq[curX + curY *_width] = 1; _heap->push(curX, curY, abs(destx - x) + abs(desty - y)); - int wei = 0; + int32 wei = 0; while (_heap->getCount()) { wei = 0; int16 tempCurX, tempCurY; _heap->pop(&tempCurX, &tempCurY, &curWeight); curX = tempCurX, curY = tempCurY; // FIXME - Bodge to match heap->pop types - int curNode = curX + curY * _width; + int32 curNode = curX + curY * _width; int32 endX = MIN(curX + 1, _width - 1); int32 endY = MIN(curY + 1, _height - 1); @@ -336,17 +335,17 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { bool next = false; for (int32 px = startX; px <= endX && !next; px++) { - for (int py = startY; py <= endY && !next; py++) { + for (int32 py = startY; py <= endY && !next; py++) { if (px != curX || py != curY) { wei = ((abs(px - curX) + abs(py - curY))); int32 curPNode = px + py * _width; if (isWalkable(px, py)) { // walkable ? - int sum = sq[curNode] + wei * (1 + (isLikelyWalkable(px, py) ? 5 : 0)); - if (sq[curPNode] > sum || !sq[curPNode]) { - int newWeight = abs(destx - px) + abs(desty - py); - sq[curPNode] = sum; - _heap->push(px, py, sq[curPNode] + newWeight); + int32 sum = _sq[curNode] + wei * (1 + (isLikelyWalkable(px, py) ? 5 : 0)); + if (_sq[curPNode] > sum || !_sq[curPNode]) { + int32 newWeight = abs(destx - px) + abs(desty - py); + _sq[curPNode] = sum; + _heap->push(px, py, _sq[curPNode] + newWeight); if (!newWeight) next = true; // we found it ! } @@ -357,7 +356,7 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { } // let's see if we found a result ! - if (!_gridTemp[destx + desty * _width]) { + if (!_sq[destx + desty * _width]) { // didn't find anything _tempPath.clear(); return false; @@ -373,7 +372,7 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { p.y = curY; retPath.push_back(p); - int32 bestscore = sq[destx + desty * _width]; + int32 bestscore = _sq[destx + desty * _width]; bool retVal = false; while (true) { @@ -390,10 +389,10 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { if (px != curX || py != curY) { wei = abs(px - curX) + abs(py - curY); - int PNode = px + py * _width; - if (sq[PNode] && (isWalkable(px, py))) { - if (sq[PNode] < bestscore) { - bestscore = sq[PNode]; + int32 PNode = px + py * _width; + if (_sq[PNode] && (isWalkable(px, py))) { + if (_sq[PNode] < bestscore) { + bestscore = _sq[PNode]; bestX = px; bestY = py; } diff --git a/engines/toon/path.h b/engines/toon/path.h index 6a22096054..8e2c61d482 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -83,7 +83,7 @@ private: PathFindingHeap *_heap; - int32 *_gridTemp; + int32 *_sq; int32 _width; int32 _height; -- cgit v1.2.3 From ca3ea849d808b7f184cb05c42c317ed19edb73fc Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 9 Jun 2012 16:29:14 +0300 Subject: SCI: Update information on kGetSierraProfileInt Thanks to LePhilousophe for his feedback and observations on this --- engines/sci/engine/kmisc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 9a113bc5f9..f243cf2ffe 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -391,6 +391,8 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { return argv[1]; } +// Likely modelled after the Windows 3.1 function GetPrivateProfileInt: +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724345%28v=vs.85%29.aspx reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv) { Common::String category = s->_segMan->getString(argv[0]); // always "config" category.toLowercase(); @@ -402,8 +404,7 @@ reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv) { if (setting != "videospeed") error("GetSierraProfileInt: setting isn't 'videospeed', it's '%s'", setting.c_str()); - // The game scripts pass 425 as the third parameter for some unknown reason, - // as after the call they compare the result to 425 anyway... + // The third parameter is 425 (the default if the configuration key is missing) // We return the same fake value for videospeed as with kGetConfig return make_reg(0, 500); -- cgit v1.2.3 From 0e5ae35e345d6e7f38177e158dcc871cf7a034d3 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sat, 9 Jun 2012 20:00:45 -0400 Subject: SCUMM: Create proper engine for heversion 101 Regression from 3968f3194893d88d1a8d73eef535b801e5415765 --- engines/scumm/detection.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 95de1a8706..ebf1a2675c 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -1135,6 +1135,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co case 200: *engine = new ScummEngine_vCUPhe(syst, res); break; + case 101: case 100: *engine = new ScummEngine_v100he(syst, res); break; -- cgit v1.2.3 From 15046a7529e3c755de1f00b4a2666786eb2bd4f8 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 10 Jun 2012 04:14:17 +0200 Subject: GUI: Get rid of SaveLoadChooser::setSaveMode. We already pass the title and process button name to the constructor of SaveLoadChooser and then do not offer any way of changing it, thus changing the edit mode of the chooser is kind of pointless and was never actually used. Instead we pass the mode on SaveLoadChooser construction now. --- engines/agi/saveload.cpp | 6 ++---- engines/cge/events.cpp | 6 ++---- engines/cruise/menu.cpp | 5 ++--- engines/dialogs.cpp | 6 ++---- engines/dreamweb/saveload.cpp | 6 ++---- engines/hugo/file.cpp | 6 ++---- engines/mohawk/myst.cpp | 3 +-- engines/mohawk/riven.cpp | 3 +-- engines/parallaction/saveload.cpp | 3 +-- engines/sci/engine/kfile.cpp | 6 ++---- engines/toon/toon.cpp | 6 ++---- engines/tsage/scenes.cpp | 6 ++---- gui/launcher.cpp | 2 +- gui/saveload.cpp | 8 ++------ gui/saveload.h | 3 +-- 15 files changed, 25 insertions(+), 50 deletions(-) diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp index d58e55a6b9..cb7792af8e 100644 --- a/engines/agi/saveload.cpp +++ b/engines/agi/saveload.cpp @@ -802,8 +802,7 @@ int AgiEngine::scummVMSaveLoadDialog(bool isSave) { int slot; if (isSave) { - dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); - dialog->setSaveMode(true); + dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); desc = dialog->getResultString(); @@ -824,8 +823,7 @@ int AgiEngine::scummVMSaveLoadDialog(bool isSave) { if (desc.size() > 28) desc = Common::String(desc.c_str(), 28); } else { - dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore")); - dialog->setSaveMode(false); + dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); } diff --git a/engines/cge/events.cpp b/engines/cge/events.cpp index 3c561c5659..e903584100 100644 --- a/engines/cge/events.cpp +++ b/engines/cge/events.cpp @@ -73,8 +73,7 @@ bool Keyboard::getKey(Common::Event &event) { const EnginePlugin *plugin = NULL; EngineMan.findGame(_vm->_gameDescription->gameid, &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save"); - dialog->setSaveMode(true); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true); int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); Common::String savegameDescription = dialog->getResultString(); delete dialog; @@ -88,8 +87,7 @@ bool Keyboard::getKey(Common::Event &event) { const EnginePlugin *plugin = NULL; EngineMan.findGame(_vm->_gameDescription->gameid, &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore"); - dialog->setSaveMode(false); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false); int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); delete dialog; diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp index e763e2b8a1..988355e777 100644 --- a/engines/cruise/menu.cpp +++ b/engines/cruise/menu.cpp @@ -211,11 +211,10 @@ static void handleSaveLoad(bool saveFlag) { EngineMan.findGame(_vm->getGameId(), &plugin); GUI::SaveLoadChooser *dialog; if (saveFlag) - dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); + dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); else - dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load")); + dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false); - dialog->setSaveMode(saveFlag); int slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); if (slot >= 0) { diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index 1b54c7e26a..3fa01ddcbf 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -111,10 +111,8 @@ MainMenuDialog::MainMenuDialog(Engine *engine) _aboutDialog = new GUI::AboutDialog(); _optionsDialog = new ConfigDialog(_engine->hasFeature(Engine::kSupportsSubtitleOptions)); - _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load")); - _loadDialog->setSaveMode(false); - _saveDialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); - _saveDialog->setSaveMode(true); + _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false); + _saveDialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); } MainMenuDialog::~MainMenuDialog() { diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index c8fb537fec..e659c03e13 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -161,8 +161,7 @@ void DreamWebEngine::doLoad(int savegameId) { const EnginePlugin *plugin = NULL; Common::String gameId = ConfMan.get("gameid"); EngineMan.findGame(gameId, &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore")); - dialog->setSaveMode(false); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); delete dialog; } @@ -248,8 +247,7 @@ void DreamWebEngine::saveGame() { const EnginePlugin *plugin = NULL; Common::String gameId = ConfMan.get("gameid"); EngineMan.findGame(gameId, &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); - dialog->setSaveMode(true); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); int savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); Common::String game_description = dialog->getResultString(); if (game_description.empty()) diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index 2217cef92a..3c94b2ee3d 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -336,8 +336,7 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) { EngineMan.findGame(_vm->getGameId(), &plugin); if (slot == -1) { - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save"); - dialog->setSaveMode(true); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); savegameDescription = dialog->getResultString(); delete dialog; @@ -441,8 +440,7 @@ bool FileManager::restoreGame(const int16 slot) { EngineMan.findGame(_vm->getGameId(), &plugin); if (slot == -1) { - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore"); - dialog->setSaveMode(false); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); delete dialog; } else { diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index c22b30ad4d..0efd412bd0 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -252,8 +252,7 @@ Common::Error MohawkEngine_Myst::run() { _gfx = new MystGraphics(this); _console = new MystConsole(this); _gameState = new MystGameState(this, _saveFileMan); - _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load")); - _loadDialog->setSaveMode(false); + _loadDialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false); _optionsDialog = new MystOptionsDialog(this); _cursor = new MystCursorManager(this); _rnd = new Common::RandomSource("myst"); diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 07b1b59929..b7866a3cb7 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -713,8 +713,7 @@ void MohawkEngine_Riven::delayAndUpdate(uint32 ms) { } void MohawkEngine_Riven::runLoadDialog() { - GUI::SaveLoadChooser slc(_("Load game:"), _("Load")); - slc.setSaveMode(false); + GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false); Common::String gameId = ConfMan.get("gameid"); diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 3ab25f203f..3bd736b915 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -180,8 +180,7 @@ void SaveLoad_ns::doSaveGame(uint16 slot, const char* name) { } int SaveLoad::selectSaveFile(Common::String &selectedName, bool saveMode, const Common::String &caption, const Common::String &button) { - GUI::SaveLoadChooser slc(caption, button); - slc.setSaveMode(saveMode); + GUI::SaveLoadChooser slc(caption, button, saveMode); selectedName.clear(); diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 8d1b078697..6c40be87e2 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -564,8 +564,7 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { g_sci->_soundCmd->pauseAll(true); // pause music const EnginePlugin *plugin = NULL; EngineMan.findGame(g_sci->getGameIdStr(), &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); - dialog->setSaveMode(true); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); game_description = dialog->getResultString(); if (game_description.empty()) { @@ -671,8 +670,7 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { g_sci->_soundCmd->pauseAll(true); // pause music const EnginePlugin *plugin = NULL; EngineMan.findGame(g_sci->getGameIdStr(), &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore")); - dialog->setSaveMode(false); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); delete dialog; if (savegameId < 0) { diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 657e18635f..9da06ce5be 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -2961,8 +2961,7 @@ bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) { EngineMan.findGame(_gameDescription->gameid, &plugin); if (slot == -1) { - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save"); - dialog->setSaveMode(true); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); savegameDescription = dialog->getResultString(); delete dialog; @@ -3057,8 +3056,7 @@ bool ToonEngine::loadGame(int32 slot) { EngineMan.findGame(_gameDescription->gameid, &plugin); if (slot == -1) { - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore"); - dialog->setSaveMode(false); + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false); savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); delete dialog; } else { diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 0756d71d4c..8fe7b8c458 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -573,11 +573,9 @@ void Game::handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName EngineMan.findGame(g_vm->getGameId(), &plugin); GUI::SaveLoadChooser *dialog; if (saveFlag) - dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save")); + dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), saveFlag); else - dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load")); - - dialog->setSaveMode(saveFlag); + dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), saveFlag); saveSlot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); saveName = dialog->getResultString(); diff --git a/gui/launcher.cpp b/gui/launcher.cpp index c8ed3126c4..26fafa5279 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -677,7 +677,7 @@ LauncherDialog::LauncherDialog() _browser = new BrowserDialog(_("Select directory with game data"), true); // Create Load dialog - _loadDialog = new SaveLoadChooser(_("Load game:"), _("Load")); + _loadDialog = new SaveLoadChooser(_("Load game:"), _("Load"), false); } void LauncherDialog::selectTarget(const String &target) { diff --git a/gui/saveload.cpp b/gui/saveload.cpp index 3dc9961906..c7da94357f 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -40,7 +40,7 @@ enum { }; -SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel) +SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode) : Dialog("SaveLoadChooser"), _delSupport(0), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { _delSupport = _metaInfoSupport = _thumbnailSupport = _saveDateSupport = _playTimeSupport = false; @@ -51,7 +51,7 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel) // Add choice list _list = new GUI::ListWidget(this, "SaveLoadChooser.List"); _list->setNumberingMode(GUI::kListNumberingZero); - setSaveMode(false); + _list->setEditable(saveMode); _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); @@ -117,10 +117,6 @@ const Common::String &SaveLoadChooser::getResultString() const { return (selItem >= 0) ? _list->getSelectedString() : _resultString; } -void SaveLoadChooser::setSaveMode(bool saveMode) { - _list->setEditable(saveMode); -} - void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { int selItem = _list->getSelected(); diff --git a/gui/saveload.h b/gui/saveload.h index adaf311fd2..e6fea0fb52 100644 --- a/gui/saveload.h +++ b/gui/saveload.h @@ -62,7 +62,7 @@ protected: void updateSaveList(); void updateSelection(bool redraw); public: - SaveLoadChooser(const String &title, const String &buttonLabel); + SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode); ~SaveLoadChooser(); virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); @@ -71,7 +71,6 @@ public: void open(); const Common::String &getResultString() const; - void setSaveMode(bool saveMode); virtual void reflowLayout(); -- cgit v1.2.3 From 5c8b7af4958edb4d53d2ac5ea575124a318b5cca Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 10 Jun 2012 04:16:52 +0200 Subject: MOHAWK: Do not call close on SaveLoadChooser. This is actually always called when a dialog closes, thus manual closing is not required. It furthermore is actually *bad* to call this from outside the dialog's code, since it will remove the top dialog from the dialog stack and thus mess up the GUI in case multiple dialogs are opened. --- engines/mohawk/riven.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index b7866a3cb7..d66e46f4a8 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -723,8 +723,6 @@ void MohawkEngine_Riven::runLoadDialog() { int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); if (slot >= 0) loadGameState(slot); - - slc.close(); } Common::Error MohawkEngine_Riven::loadGameState(int slot) { -- cgit v1.2.3 From 9b05f4e1039ade7f2d0b774c18a6767113f2c848 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 10 Jun 2012 04:17:46 +0200 Subject: PARALLACTION: Do not call close on a SaveLoadChooser. --- engines/parallaction/saveload.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 3bd736b915..85923363c7 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -192,7 +192,6 @@ int SaveLoad::selectSaveFile(Common::String &selectedName, bool saveMode, const int idx = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); if (idx >= 0) { selectedName = slc.getResultString(); - slc.close(); } return idx; -- cgit v1.2.3 From 7c5cf1b400808865a5f601f70d624ad6704a0c8c Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 10 Jun 2012 04:49:42 +0200 Subject: GUI: Add helper to SaveLoadChooser, which uses the currently active target. This reduces the code duplication in all client code, which formerly duplicated the querying of the plugin, game id etc. and now simply calls the newly added method runModalWithCurrentTarget() on a SaveLoadChooser object. --- engines/agi/saveload.cpp | 6 ++---- engines/cge/events.cpp | 10 ++-------- engines/cruise/menu.cpp | 4 +--- engines/dialogs.cpp | 14 ++------------ engines/dreamweb/saveload.cpp | 10 ++-------- engines/hugo/file.cpp | 8 ++------ engines/mohawk/riven.cpp | 7 +------ engines/parallaction/saveload.cpp | 7 +------ engines/sci/engine/kfile.cpp | 8 ++------ engines/toon/toon.cpp | 8 ++------ engines/tsage/scenes.cpp | 4 +--- gui/saveload.cpp | 9 +++++++++ gui/saveload.h | 7 +++++++ 13 files changed, 34 insertions(+), 68 deletions(-) diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp index cb7792af8e..25fa7829ef 100644 --- a/engines/agi/saveload.cpp +++ b/engines/agi/saveload.cpp @@ -795,8 +795,6 @@ int AgiEngine::selectSlot() { } int AgiEngine::scummVMSaveLoadDialog(bool isSave) { - const EnginePlugin *plugin = NULL; - EngineMan.findGame(ConfMan.get("gameid"), &plugin); GUI::SaveLoadChooser *dialog; Common::String desc; int slot; @@ -804,7 +802,7 @@ int AgiEngine::scummVMSaveLoadDialog(bool isSave) { if (isSave) { dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); - slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + slot = dialog->runModalWithCurrentTarget(); desc = dialog->getResultString(); if (desc.empty()) { @@ -824,7 +822,7 @@ int AgiEngine::scummVMSaveLoadDialog(bool isSave) { desc = Common::String(desc.c_str(), 28); } else { dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); - slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + slot = dialog->runModalWithCurrentTarget(); } delete dialog; diff --git a/engines/cge/events.cpp b/engines/cge/events.cpp index e903584100..095aac2412 100644 --- a/engines/cge/events.cpp +++ b/engines/cge/events.cpp @@ -70,11 +70,8 @@ bool Keyboard::getKey(Common::Event &event) { return false; case Common::KEYCODE_F5: if (_vm->canSaveGameStateCurrently()) { - const EnginePlugin *plugin = NULL; - EngineMan.findGame(_vm->_gameDescription->gameid, &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true); - int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int16 savegameId = dialog->runModalWithCurrentTarget(); Common::String savegameDescription = dialog->getResultString(); delete dialog; @@ -84,11 +81,8 @@ bool Keyboard::getKey(Common::Event &event) { return false; case Common::KEYCODE_F7: if (_vm->canLoadGameStateCurrently()) { - const EnginePlugin *plugin = NULL; - EngineMan.findGame(_vm->_gameDescription->gameid, &plugin); - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false); - int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int16 savegameId = dialog->runModalWithCurrentTarget(); delete dialog; if (savegameId != -1) diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp index 988355e777..512259f7d7 100644 --- a/engines/cruise/menu.cpp +++ b/engines/cruise/menu.cpp @@ -207,15 +207,13 @@ int processMenu(menuStruct *pMenu) { } static void handleSaveLoad(bool saveFlag) { - const EnginePlugin *plugin = 0; - EngineMan.findGame(_vm->getGameId(), &plugin); GUI::SaveLoadChooser *dialog; if (saveFlag) dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); else dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false); - int slot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int slot = dialog->runModalWithCurrentTarget(); if (slot >= 0) { if (!saveFlag) diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index 3fa01ddcbf..9245d9fe62 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -214,12 +214,7 @@ void MainMenuDialog::reflowLayout() { } void MainMenuDialog::save() { - const Common::String gameId = ConfMan.get("gameid"); - - const EnginePlugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - - int slot = _saveDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int slot = _saveDialog->runModalWithCurrentTarget(); if (slot >= 0) { Common::String result(_saveDialog->getResultString()); @@ -250,12 +245,7 @@ void MainMenuDialog::save() { } void MainMenuDialog::load() { - const Common::String gameId = ConfMan.get("gameid"); - - const EnginePlugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - - int slot = _loadDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int slot = _loadDialog->runModalWithCurrentTarget(); _engine->setGameToLoadSlot(slot); diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index e659c03e13..ea9cdc0249 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -158,11 +158,8 @@ void DreamWebEngine::doLoad(int savegameId) { if (savegameId == -1) { // Open dialog to get savegameId - const EnginePlugin *plugin = NULL; - Common::String gameId = ConfMan.get("gameid"); - EngineMan.findGame(gameId, &plugin); GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); delete dialog; } @@ -244,11 +241,8 @@ void DreamWebEngine::saveGame() { } return; } else { - const EnginePlugin *plugin = NULL; - Common::String gameId = ConfMan.get("gameid"); - EngineMan.findGame(gameId, &plugin); GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); - int savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int savegameId = dialog->runModalWithCurrentTarget(); Common::String game_description = dialog->getResultString(); if (game_description.empty()) game_description = "Untitled"; diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index 3c94b2ee3d..f94f3b0443 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -330,14 +330,12 @@ sound_pt FileManager::getSound(const int16 sound, uint16 *size) { bool FileManager::saveGame(const int16 slot, const Common::String &descrip) { debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip.c_str()); - const EnginePlugin *plugin = NULL; int16 savegameId; Common::String savegameDescription; - EngineMan.findGame(_vm->getGameId(), &plugin); if (slot == -1) { GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); savegameDescription = dialog->getResultString(); delete dialog; } else { @@ -435,13 +433,11 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) { bool FileManager::restoreGame(const int16 slot) { debugC(1, kDebugFile, "restoreGame(%d)", slot); - const EnginePlugin *plugin = NULL; int16 savegameId; - EngineMan.findGame(_vm->getGameId(), &plugin); if (slot == -1) { GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); delete dialog; } else { savegameId = slot; diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index d66e46f4a8..e54d6fefa2 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -715,12 +715,7 @@ void MohawkEngine_Riven::delayAndUpdate(uint32 ms) { void MohawkEngine_Riven::runLoadDialog() { GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false); - Common::String gameId = ConfMan.get("gameid"); - - const EnginePlugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - - int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int slot = slc.runModalWithCurrentTarget(); if (slot >= 0) loadGameState(slot); } diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 85923363c7..8de2d89b18 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -184,12 +184,7 @@ int SaveLoad::selectSaveFile(Common::String &selectedName, bool saveMode, const selectedName.clear(); - Common::String gameId = ConfMan.get("gameid"); - - const EnginePlugin *plugin = 0; - EngineMan.findGame(gameId, &plugin); - - int idx = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + int idx = slc.runModalWithCurrentTarget(); if (idx >= 0) { selectedName = slc.getResultString(); } diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 6c40be87e2..4af71f41af 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -562,10 +562,8 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { // we are supposed to show a dialog for the user and let him choose where to save g_sci->_soundCmd->pauseAll(true); // pause music - const EnginePlugin *plugin = NULL; - EngineMan.findGame(g_sci->getGameIdStr(), &plugin); GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); game_description = dialog->getResultString(); if (game_description.empty()) { // create our own description for the saved game, the user didnt enter it @@ -668,10 +666,8 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { if (savegameId == -1) { // we are supposed to show a dialog for the user and let him choose a saved game g_sci->_soundCmd->pauseAll(true); // pause music - const EnginePlugin *plugin = NULL; - EngineMan.findGame(g_sci->getGameIdStr(), &plugin); GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); delete dialog; if (savegameId < 0) { g_sci->_soundCmd->pauseAll(false); // unpause music diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 9da06ce5be..be298e1236 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -2955,14 +2955,12 @@ Common::String ToonEngine::getSavegameName(int nr) { } bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) { - const EnginePlugin *plugin = NULL; int16 savegameId; Common::String savegameDescription; - EngineMan.findGame(_gameDescription->gameid, &plugin); if (slot == -1) { GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); savegameDescription = dialog->getResultString(); delete dialog; } else { @@ -3051,13 +3049,11 @@ bool ToonEngine::saveGame(int32 slot, const Common::String &saveGameDesc) { } bool ToonEngine::loadGame(int32 slot) { - const EnginePlugin *plugin = NULL; int16 savegameId; - EngineMan.findGame(_gameDescription->gameid, &plugin); if (slot == -1) { GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false); - savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + savegameId = dialog->runModalWithCurrentTarget(); delete dialog; } else { savegameId = slot; diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 8fe7b8c458..774a5277dc 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -569,15 +569,13 @@ void Game::quitGame() { } void Game::handleSaveLoad(bool saveFlag, int &saveSlot, Common::String &saveName) { - const EnginePlugin *plugin = 0; - EngineMan.findGame(g_vm->getGameId(), &plugin); GUI::SaveLoadChooser *dialog; if (saveFlag) dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), saveFlag); else dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), saveFlag); - saveSlot = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); + saveSlot = dialog->runModalWithCurrentTarget(); saveName = dialog->getResultString(); delete dialog; diff --git a/gui/saveload.cpp b/gui/saveload.cpp index c7da94357f..366efa7a90 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -76,6 +76,15 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, SaveLoadChooser::~SaveLoadChooser() { } +int SaveLoadChooser::runModalWithCurrentTarget() { + const Common::String gameId = ConfMan.get("gameid"); + + const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); + + return runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); +} + int SaveLoadChooser::runModalWithPluginAndTarget(const EnginePlugin *plugin, const String &target) { if (_gfxWidget) _gfxWidget->setGfx(0); diff --git a/gui/saveload.h b/gui/saveload.h index e6fea0fb52..dc0f0429c7 100644 --- a/gui/saveload.h +++ b/gui/saveload.h @@ -67,6 +67,13 @@ public: virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); void setList(const StringArray& list); + /** + * Runs the save/load chooser with the currently active config manager + * domain as target. + * + * @return The selcted save slot. -1 in case none is selected. + */ + int runModalWithCurrentTarget(); int runModalWithPluginAndTarget(const EnginePlugin *plugin, const String &target); void open(); -- cgit v1.2.3 From 49fafb48a7f089c97ed3baa9aefe65ec56dce682 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 10 Jun 2012 05:04:59 +0200 Subject: GUI: Refactor default savegame description creation. Formerly the GMM, AGI and SCI duplicated the logic for USE_SAVEGAME_TIMESTAMP. Now I added a method to SaveLoadChooser instead, which takes care of this. This might not be the best placement of such a functionality, thus I added a TODO which talks about moving it to a better place. --- engines/agi/saveload.cpp | 10 +--------- engines/dialogs.cpp | 10 +--------- engines/sci/engine/kfile.cpp | 10 +--------- gui/saveload.cpp | 13 +++++++++++++ gui/saveload.h | 15 +++++++++++++++ 5 files changed, 31 insertions(+), 27 deletions(-) diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp index 25fa7829ef..3e63da756d 100644 --- a/engines/agi/saveload.cpp +++ b/engines/agi/saveload.cpp @@ -807,15 +807,7 @@ int AgiEngine::scummVMSaveLoadDialog(bool isSave) { if (desc.empty()) { // create our own description for the saved game, the user didnt enter it -#if defined(USE_SAVEGAME_TIMESTAMP) - TimeDate curTime; - g_system->getTimeAndDate(curTime); - curTime.tm_year += 1900; // fixup year - curTime.tm_mon++; // fixup month - desc = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec); -#else - desc = Common::String::format("Save %d", slot + 1); -#endif + desc = dialog->createDefaultSaveDescription(slot); } if (desc.size() > 28) diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index 9245d9fe62..cf3dfaa44b 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -220,15 +220,7 @@ void MainMenuDialog::save() { Common::String result(_saveDialog->getResultString()); if (result.empty()) { // If the user was lazy and entered no save name, come up with a default name. - #if defined(USE_SAVEGAME_TIMESTAMP) - TimeDate curTime; - g_system->getTimeAndDate(curTime); - curTime.tm_year += 1900; // fixup year - curTime.tm_mon++; // fixup month - result = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec); - #else - result = Common::String::format("Save %d", slot + 1); - #endif + result = _saveDialog->createDefaultSaveDescription(slot); } Common::Error status = _engine->saveGameState(slot, result); diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 4af71f41af..42f8b8832c 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -567,15 +567,7 @@ reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { game_description = dialog->getResultString(); if (game_description.empty()) { // create our own description for the saved game, the user didnt enter it - #if defined(USE_SAVEGAME_TIMESTAMP) - TimeDate curTime; - g_system->getTimeAndDate(curTime); - curTime.tm_year += 1900; // fixup year - curTime.tm_mon++; // fixup month - game_description = Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec); - #else - game_description = Common::String::format("Save %d", savegameId + 1); - #endif + game_description = dialog->createDefaultSaveDescription(savegameId); } delete dialog; g_sci->_soundCmd->pauseAll(false); // unpause music ( we can't have it paused during save) diff --git a/gui/saveload.cpp b/gui/saveload.cpp index 366efa7a90..67d871e133 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -21,6 +21,7 @@ #include "common/config-manager.h" #include "common/translation.h" +#include "common/system.h" #include "gui/widgets/list.h" #include "gui/message.h" @@ -126,6 +127,18 @@ const Common::String &SaveLoadChooser::getResultString() const { return (selItem >= 0) ? _list->getSelectedString() : _resultString; } +Common::String SaveLoadChooser::createDefaultSaveDescription(const int slot) const { +#if defined(USE_SAVEGAME_TIMESTAMP) + TimeDate curTime; + g_system->getTimeAndDate(curTime); + curTime.tm_year += 1900; // fixup year + curTime.tm_mon++; // fixup month + return Common::String::format("%04d.%02d.%02d / %02d:%02d:%02d", curTime.tm_year, curTime.tm_mon, curTime.tm_mday, curTime.tm_hour, curTime.tm_min, curTime.tm_sec); +#else + return Common::String::format("Save %d", slot + 1); +#endif +} + void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { int selItem = _list->getSelected(); diff --git a/gui/saveload.h b/gui/saveload.h index dc0f0429c7..e81b10d214 100644 --- a/gui/saveload.h +++ b/gui/saveload.h @@ -79,6 +79,21 @@ public: const Common::String &getResultString() const; + /** + * Creates a default save description for the specified slot. Depending + * on the ScummVM configuration this might be a simple "Slot #" description + * or the current date and time. + * + * TODO: This might not be the best place to put this, since engines not + * using this class might want to mimic the same behavior. Check whether + * moving this to a better place makes sense and find what this place would + * be. + * + * @param slot The slot number (must be >= 0). + * @return The slot description. + */ + Common::String createDefaultSaveDescription(const int slot) const; + virtual void reflowLayout(); virtual void close(); -- cgit v1.2.3 From 5458127d9706d2c124d907edc5be06e58384d562 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sun, 10 Jun 2012 16:00:26 +0100 Subject: TOON: Migrate Pathfinding API x,y coordinates to int16. This harmonises the usage with Common::Point. --- engines/toon/character.cpp | 4 ++- engines/toon/path.cpp | 66 ++++++++++++++++++++++------------------------ engines/toon/path.h | 26 +++++++++--------- engines/toon/toon.cpp | 2 +- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index 0e5189957b..3ac454983d 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -173,7 +173,9 @@ bool Character::walkTo(int32 newPosX, int32 newPosY) { _vm->getPathFinding()->addBlockingEllipse(_vm->getDrew()->getFinalX(), _vm->getDrew()->getFinalY(), sizeX, sizeY); } - _vm->getPathFinding()->findClosestWalkingPoint(newPosX, newPosY, &_finalX, &_finalY, _x, _y); + int16 tempFinalX, tempFinalY; + _vm->getPathFinding()->findClosestWalkingPoint(newPosX, newPosY, &tempFinalX, &tempFinalY, _x, _y); + _finalX = tempFinalX, _finalY = tempFinalY; // FIXME - Bodge to match types... if (_x == _finalX && _y == _finalY) return true; diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index dfdf095af9..5aae523455 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -60,7 +60,7 @@ void PathFindingHeap::clear() { memset(_data, 0, sizeof(HeapDataGrid) * _size); } -void PathFindingHeap::push(int16 x, int16 y, int32 weight) { +void PathFindingHeap::push(int16 x, int16 y, int16 weight) { debugC(2, kDebugPath, "push(%d, %d, %d)", x, y, weight); if (_count == _size) { @@ -104,7 +104,7 @@ void PathFindingHeap::push(int16 x, int16 y, int32 weight) { } } -void PathFindingHeap::pop(int16 *x, int16 *y, int32 *weight) { +void PathFindingHeap::pop(int16 *x, int16 *y, int16 *weight) { debugC(2, kDebugPath, "pop(x, y, weight)"); if (!_count) { @@ -173,14 +173,14 @@ void PathFinding::init(Picture *mask) { _sq = new int32[_width * _height]; } -bool PathFinding::isLikelyWalkable(int32 x, int32 y) { +bool PathFinding::isLikelyWalkable(int16 x, int16 y) { for (uint8 i = 0; i < _numBlockingRects; i++) { if (_blockingRects[i][4] == 0) { if (x >= _blockingRects[i][0] && x <= _blockingRects[i][2] && y >= _blockingRects[i][1] && y < _blockingRects[i][3]) return false; } else { - int32 dx = abs(_blockingRects[i][0] - x); - int32 dy = abs(_blockingRects[i][1] - y); + int16 dx = abs(_blockingRects[i][0] - x); + int16 dy = abs(_blockingRects[i][1] - y); if ((dx << 8) / _blockingRects[i][2] < (1 << 8) && (dy << 8) / _blockingRects[i][3] < (1 << 8)) { return false; } @@ -189,13 +189,13 @@ bool PathFinding::isLikelyWalkable(int32 x, int32 y) { return true; } -bool PathFinding::isWalkable(int32 x, int32 y) { +bool PathFinding::isWalkable(int16 x, int16 y) { debugC(2, kDebugPath, "isWalkable(%d, %d)", x, y); return (_currentMask->getData(x, y) & 0x1f) > 0; } -bool PathFinding::findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 *fyy, int origX, int origY) { +bool PathFinding::findClosestWalkingPoint(int16 xx, int16 yy, int16 *fxx, int16 *fyy, int16 origX, int16 origY) { debugC(1, kDebugPath, "findClosestWalkingPoint(%d, %d, fxx, fyy, %d, %d)", xx, yy, origX, origY); int32 currentFound = -1; @@ -207,8 +207,8 @@ bool PathFinding::findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 if (origY == -1) origY = yy; - for (int y = 0; y < _height; y++) { - for (int x = 0; x < _width; x++) { + for (int16 y = 0; y < _height; y++) { + for (int16 x = 0; x < _width; x++) { if (isWalkable(x, y) && isLikelyWalkable(x, y)) { int32 ndist = (x - xx) * (x - xx) + (y - yy) * (y - yy); int32 ndist2 = (x - origX) * (x - origX) + (y - origY) * (y - origY); @@ -232,7 +232,7 @@ bool PathFinding::findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 } } -bool PathFinding::walkLine(int32 x, int32 y, int32 x2, int32 y2) { +bool PathFinding::walkLine(int16 x, int16 y, int16 x2, int16 y2) { uint32 bx = x << 16; int32 dx = x2 - x; uint32 by = y << 16; @@ -265,7 +265,7 @@ bool PathFinding::walkLine(int32 x, int32 y, int32 x2, int32 y2) { return true; } -bool PathFinding::lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2) { +bool PathFinding::lineIsWalkable(int16 x, int16 y, int16 x2, int16 y2) { uint32 bx = x << 16; int32 dx = x2 - x; uint32 by = y << 16; @@ -290,7 +290,7 @@ bool PathFinding::lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2) { return true; } -bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { +bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { debugC(1, kDebugPath, "findPath(%d, %d, %d, %d)", x, y, destx, desty); if (x == destx && y == desty) { @@ -313,9 +313,9 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { // no direct line, we use the standard A* algorithm memset(_sq , 0, _width * _height * sizeof(int32)); _heap->clear(); - int32 curX = x; - int32 curY = y; - int32 curWeight = 0; + int16 curX = x; + int16 curY = y; + int16 curWeight = 0; _sq[curX + curY *_width] = 1; _heap->push(curX, curY, abs(destx - x) + abs(desty - y)); @@ -323,19 +323,17 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { while (_heap->getCount()) { wei = 0; - int16 tempCurX, tempCurY; - _heap->pop(&tempCurX, &tempCurY, &curWeight); - curX = tempCurX, curY = tempCurY; // FIXME - Bodge to match heap->pop types + _heap->pop(&curX, &curY, &curWeight); int32 curNode = curX + curY * _width; - int32 endX = MIN(curX + 1, _width - 1); - int32 endY = MIN(curY + 1, _height - 1); - int32 startX = MAX(curX - 1, 0); - int32 startY = MAX(curY - 1, 0); + int16 endX = MIN(curX + 1, _width - 1); + int16 endY = MIN(curY + 1, _height - 1); + int16 startX = MAX(curX - 1, 0); + int16 startY = MAX(curY - 1, 0); bool next = false; - for (int32 px = startX; px <= endX && !next; px++) { - for (int32 py = startY; py <= endY && !next; py++) { + for (int16 px = startX; px <= endX && !next; px++) { + for (int16 py = startY; py <= endY && !next; py++) { if (px != curX || py != curY) { wei = ((abs(px - curX) + abs(py - curY))); @@ -376,16 +374,16 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { bool retVal = false; while (true) { - int32 bestX = -1; - int32 bestY = -1; + int16 bestX = -1; + int16 bestY = -1; - int32 endX = MIN(curX + 1, _width - 1); - int32 endY = MIN(curY + 1, _height - 1); - int32 startX = MAX(curX - 1, 0); - int32 startY = MAX(curY - 1, 0); + int16 endX = MIN(curX + 1, _width - 1); + int16 endY = MIN(curY + 1, _height - 1); + int16 startX = MAX(curX - 1, 0); + int16 startY = MAX(curY - 1, 0); - for (int32 px = startX; px <= endX; px++) { - for (int32 py = startY; py <= endY; py++) { + for (int16 px = startX; px <= endX; px++) { + for (int16 py = startY; py <= endY; py++) { if (px != curX || py != curY) { wei = abs(px - curX) + abs(py - curY); @@ -425,7 +423,7 @@ bool PathFinding::findPath(int32 x, int32 y, int32 destx, int32 desty) { return retVal; } -void PathFinding::addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2) { +void PathFinding::addBlockingRect(int16 x1, int16 y1, int16 x2, int16 y2) { debugC(1, kDebugPath, "addBlockingRect(%d, %d, %d, %d)", x1, y1, x2, y2); if (_numBlockingRects >= kMaxBlockingRects) { warning("Maximum number of %d Blocking Rects reached!", kMaxBlockingRects); @@ -440,7 +438,7 @@ void PathFinding::addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2) { _numBlockingRects++; } -void PathFinding::addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h) { +void PathFinding::addBlockingEllipse(int16 x1, int16 y1, int16 w, int16 h) { debugC(1, kDebugPath, "addBlockingEllipse(%d, %d, %d, %d)", x1, y1, w, h); if (_numBlockingRects >= kMaxBlockingRects) { warning("Maximum number of %d Blocking Rects reached!", kMaxBlockingRects); diff --git a/engines/toon/path.h b/engines/toon/path.h index 8e2c61d482..f73415adc5 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -35,8 +35,8 @@ public: PathFindingHeap(); ~PathFindingHeap(); - void push(int16 x, int16 y, int32 weight); - void pop(int16 *x, int16 *y, int32 *weight); + void push(int16 x, int16 y, int16 weight); + void pop(int16 *x, int16 *y, int16 *weight); void init(int32 size); void clear(); void unload(); @@ -61,16 +61,16 @@ public: void init(Picture *mask); - bool findPath(int32 x, int32 y, int32 destX, int32 destY); - bool findClosestWalkingPoint(int32 xx, int32 yy, int32 *fxx, int32 *fyy, int origX = -1, int origY = -1); - bool isWalkable(int32 x, int32 y); - bool isLikelyWalkable(int32 x, int32 y); - bool lineIsWalkable(int32 x, int32 y, int32 x2, int32 y2); - bool walkLine(int32 x, int32 y, int32 x2, int32 y2); + bool findPath(int16 x, int16 y, int16 destX, int16 destY); + bool findClosestWalkingPoint(int16 xx, int16 yy, int16 *fxx, int16 *fyy, int16 origX = -1, int16 origY = -1); + bool isWalkable(int16 x, int16 y); + bool isLikelyWalkable(int16 x, int16 y); + bool lineIsWalkable(int16 x, int16 y, int16 x2, int16 y2); + bool walkLine(int16 x, int16 y, int16 x2, int16 y2); void resetBlockingRects() { _numBlockingRects = 0; } - void addBlockingRect(int32 x1, int32 y1, int32 x2, int32 y2); - void addBlockingEllipse(int32 x1, int32 y1, int32 w, int32 h); + void addBlockingRect(int16 x1, int16 y1, int16 x2, int16 y2); + void addBlockingEllipse(int16 x1, int16 y1, int16 w, int16 h); int32 getPathNodeCount() const { return _tempPath.size(); } int32 getPathNodeX(int32 nodeId) const { return _tempPath[ _tempPath.size() - nodeId - 1].x; } @@ -84,8 +84,8 @@ private: PathFindingHeap *_heap; int32 *_sq; - int32 _width; - int32 _height; + int16 _width; + int16 _height; struct i32Point { int32 x, y; @@ -93,7 +93,7 @@ private: Common::Array _tempPath; - int32 _blockingRects[kMaxBlockingRects][5]; + int16 _blockingRects[kMaxBlockingRects][5]; uint8 _numBlockingRects; }; diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 0b39432b53..dd3c32b5bf 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -1488,7 +1488,7 @@ void ToonEngine::clickEvent() { } if (!currentHot) { - int32 xx, yy; + int16 xx, yy; if (_gameState->_inCutaway || _gameState->_inInventory || _gameState->_inCloseUp) return; -- cgit v1.2.3 From 13832580002a0a902a23fa893784aa61f7b3faaa Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sun, 10 Jun 2012 20:45:37 +0100 Subject: TOON: Migrate Pathfinding Path Buffers to Common::Point. This removes the need for i32Point, which used int32, instead of the int16 of Common::Point. Since the co-ordinates passed in are in int16, this is safe. Tested with no regressions. Also, removed return value from walkLine function as it always returned true. --- engines/toon/path.cpp | 26 ++++++-------------------- engines/toon/path.h | 9 +++------ 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 5aae523455..63dbf1a442 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -232,7 +232,7 @@ bool PathFinding::findClosestWalkingPoint(int16 xx, int16 yy, int16 *fxx, int16 } } -bool PathFinding::walkLine(int16 x, int16 y, int16 x2, int16 y2) { +void PathFinding::walkLine(int16 x, int16 y, int16 x2, int16 y2) { uint32 bx = x << 16; int32 dx = x2 - x; uint32 by = y << 16; @@ -249,20 +249,13 @@ bool PathFinding::walkLine(int16 x, int16 y, int16 x2, int16 y2) { int32 cdy = (dy << 16) / t; _tempPath.clear(); - i32Point p; for (int32 i = t; i > 0; i--) { - p.x = bx >> 16; - p.y = by >> 16; - _tempPath.insert_at(0, p); + _tempPath.insert_at(0, Common::Point(bx >> 16, by >> 16)); bx += cdx; by += cdy; } - p.x = x2; - p.y = y2; - _tempPath.insert_at(0, p); - - return true; + _tempPath.insert_at(0, Common::Point(x2, y2)); } bool PathFinding::lineIsWalkable(int16 x, int16 y, int16 x2, int16 y2) { @@ -363,12 +356,8 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { curX = destx; curY = desty; - Common::Array retPath; - - i32Point p; - p.x = curX; - p.y = curY; - retPath.push_back(p); + Common::Array retPath; + retPath.push_back(Common::Point(curX, curY)); int32 bestscore = _sq[destx + desty * _width]; @@ -402,10 +391,7 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { if (bestX < 0 || bestY < 0) break; - i32Point pp; - pp.x = bestX; - pp.y = bestY; - retPath.push_back(pp); + retPath.push_back(Common::Point(bestX, bestY)); if ((bestX == x && bestY == y)) { _tempPath.clear(); diff --git a/engines/toon/path.h b/engines/toon/path.h index f73415adc5..2a583e5bff 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -24,6 +24,7 @@ #define TOON_PATH_H #include "common/array.h" +#include "common/rect.h" #include "toon/toon.h" @@ -66,7 +67,7 @@ public: bool isWalkable(int16 x, int16 y); bool isLikelyWalkable(int16 x, int16 y); bool lineIsWalkable(int16 x, int16 y, int16 x2, int16 y2); - bool walkLine(int16 x, int16 y, int16 x2, int16 y2); + void walkLine(int16 x, int16 y, int16 x2, int16 y2); void resetBlockingRects() { _numBlockingRects = 0; } void addBlockingRect(int16 x1, int16 y1, int16 x2, int16 y2); @@ -87,11 +88,7 @@ private: int16 _width; int16 _height; - struct i32Point { - int32 x, y; - }; - - Common::Array _tempPath; + Common::Array _tempPath; int16 _blockingRects[kMaxBlockingRects][5]; uint8 _numBlockingRects; -- cgit v1.2.3 From fcfff28c5f3cabf193d83846cfe9d90f0153d187 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Sun, 10 Jun 2012 21:12:01 +0100 Subject: TOON: Minor type fixes and cleanups in Pathfinding class. --- engines/toon/character.cpp | 2 +- engines/toon/path.cpp | 20 ++++++++++---------- engines/toon/path.h | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index 3ac454983d..260296cc9f 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -186,7 +186,7 @@ bool Character::walkTo(int32 newPosX, int32 newPosY) { int32 smoothDx = 0; int32 smoothDy = 0; - for (int32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++) { + for (uint32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++) { _currentPathX[a] = _vm->getPathFinding()->getPathNodeX(a); _currentPathY[a] = _vm->getPathFinding()->getPathNodeY(a); } diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 63dbf1a442..735801eebc 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -65,7 +65,7 @@ void PathFindingHeap::push(int16 x, int16 y, int16 weight) { if (_count == _size) { // Increase size by 50% - int newSize = _size + (_size >> 1) + 1; + uint32 newSize = _size + (_size / 2) + 1; HeapDataGrid *newData; newData = (HeapDataGrid *)realloc(_data, sizeof(HeapDataGrid) * newSize); @@ -84,13 +84,13 @@ void PathFindingHeap::push(int16 x, int16 y, int16 weight) { _data[_count]._weight = weight; _count++; - int32 lMax = _count-1; - int32 lT = 0; + uint32 lMax = _count - 1; + uint32 lT = 0; while (true) { if (lMax <= 0) break; - lT = (lMax-1) / 2; + lT = (lMax - 1) / 2; if (_data[lT]._weight > _data[lMax]._weight) { HeapDataGrid temp; @@ -120,13 +120,13 @@ void PathFindingHeap::pop(int16 *x, int16 *y, int16 *weight) { if (!_count) return; - int32 lMin = 0; - int32 lT = 0; + uint32 lMin = 0; + uint32 lT = 0; while (true) { - lT = (lMin << 1) + 1; + lT = (lMin * 2) + 1; if (lT < _count) { - if (lT < _count-1) { + if (lT < _count - 1) { if (_data[lT + 1]._weight < _data[lT]._weight) lT++; } @@ -312,8 +312,8 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { _sq[curX + curY *_width] = 1; _heap->push(curX, curY, abs(destx - x) + abs(desty - y)); - int32 wei = 0; + int16 wei; while (_heap->getCount()) { wei = 0; _heap->pop(&curX, &curY, &curWeight); @@ -328,7 +328,7 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { for (int16 px = startX; px <= endX && !next; px++) { for (int16 py = startY; py <= endY && !next; py++) { if (px != curX || py != curY) { - wei = ((abs(px - curX) + abs(py - curY))); + wei = abs(px - curX) + abs(py - curY); int32 curPNode = px + py * _width; if (isWalkable(px, py)) { // walkable ? diff --git a/engines/toon/path.h b/engines/toon/path.h index 2a583e5bff..2476dc3b8a 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -41,7 +41,7 @@ public: void init(int32 size); void clear(); void unload(); - int32 getCount() { return _count; } + uint32 getCount() { return _count; } private: struct HeapDataGrid { @@ -51,8 +51,8 @@ private: HeapDataGrid *_data; - int32 _size; - int32 _count; + uint32 _size; + uint32 _count; }; class PathFinding { @@ -73,9 +73,9 @@ public: void addBlockingRect(int16 x1, int16 y1, int16 x2, int16 y2); void addBlockingEllipse(int16 x1, int16 y1, int16 w, int16 h); - int32 getPathNodeCount() const { return _tempPath.size(); } - int32 getPathNodeX(int32 nodeId) const { return _tempPath[ _tempPath.size() - nodeId - 1].x; } - int32 getPathNodeY(int32 nodeId) const { return _tempPath[ _tempPath.size() - nodeId - 1].y; } + uint32 getPathNodeCount() const { return _tempPath.size(); } + int16 getPathNodeX(uint32 nodeId) const { return _tempPath[(_tempPath.size() - 1) - nodeId].x; } + int16 getPathNodeY(uint32 nodeId) const { return _tempPath[(_tempPath.size() - 1) - nodeId].y; } private: static const uint8 kMaxBlockingRects = 16; -- cgit v1.2.3 From 03ef6689c015742c192d5d92d936e60d638caa1c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 9 Jun 2012 10:38:55 +0200 Subject: GOB: Rewrite the AdLib players This is a complete rewrite of the AdLib players for ADL and MDY/TBR files in the Gob engine. Major changes 1) The AdLib base class is now completely separated from all file format code and can theoretically be used by any OPL2-based format (within reason) 2) The new code is far better documented and more readable 3) The MDY player now actually works. The MDY/TBR format is in reality the MUS/SND format created by AdLib as a simpler alternative to the ROL format 4) Since the MAME emulator is quite buggy and leads to noticable wrong percussion in the Gobliins 2 title music, the new AdLib player will try to create a DOSBox OPL. If it's not compiled in, or if the user configured opl_driver to "mame", it will print out appropriate warnings. --- engines/gob/module.mk | 2 + engines/gob/sound/adlib.cpp | 1038 +++++++++++++++++---------------------- engines/gob/sound/adlib.h | 317 ++++++++---- engines/gob/sound/adlplayer.cpp | 257 ++++++++++ engines/gob/sound/adlplayer.h | 85 ++++ engines/gob/sound/musplayer.cpp | 391 +++++++++++++++ engines/gob/sound/musplayer.h | 109 ++++ engines/gob/sound/sound.cpp | 41 +- engines/gob/sound/sound.h | 17 +- 9 files changed, 1545 insertions(+), 712 deletions(-) create mode 100644 engines/gob/sound/adlplayer.cpp create mode 100644 engines/gob/sound/adlplayer.h create mode 100644 engines/gob/sound/musplayer.cpp create mode 100644 engines/gob/sound/musplayer.h diff --git a/engines/gob/module.mk b/engines/gob/module.mk index b9680fad6b..7c5d7de158 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -103,6 +103,8 @@ MODULE_OBJS := \ sound/sounddesc.o \ sound/pcspeaker.o \ sound/adlib.o \ + sound/musplayer.o \ + sound/adlplayer.o \ sound/infogrames.o \ sound/protracker.o \ sound/soundmixer.o \ diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index f1ab2a2d79..3f46f6cf4b 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -20,771 +20,615 @@ * */ -#include "common/debug.h" -#include "common/file.h" -#include "common/endian.h" +#include "common/util.h" #include "common/textconsole.h" +#include "common/debug.h" +#include "common/config-manager.h" + +#include "audio/fmopl.h" #include "gob/gob.h" #include "gob/sound/adlib.h" namespace Gob { -const unsigned char AdLib::_operators[] = {0, 1, 2, 8, 9, 10, 16, 17, 18}; -const unsigned char AdLib::_volRegNums[] = { - 3, 4, 5, - 11, 12, 13, - 19, 20, 21 +static const int kPitchTom = 24; +static const int kPitchTomToSnare = 7; +static const int kPitchSnareDrum = kPitchTom + kPitchTomToSnare; + + +// Is the operator a modulator (0) or a carrier (1)? +const uint8 AdLib::kOperatorType[kOperatorCount] = { + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 +}; + +// Operator number to register offset on the OPL +const uint8 AdLib::kOperatorOffset[kOperatorCount] = { + 0, 1, 2, 3, 4, 5, + 8, 9, 10, 11, 12, 13, + 16, 17, 18, 19, 20, 21 +}; + +// For each operator, the voice it belongs to +const uint8 AdLib::kOperatorVoice[kOperatorCount] = { + 0, 1, 2, + 0, 1, 2, + 3, 4, 5, + 3, 4, 5, + 6, 7, 8, + 6, 7, 8, +}; + +// Voice to operator set, for the 9 melodyvoices (only 6 useable in percussion mode) +const uint8 AdLib::kVoiceMelodyOperator[kOperatorsPerVoice][kMelodyVoiceCount] = { + {0, 1, 2, 6, 7, 8, 12, 13, 14}, + {3, 4, 5, 9, 10, 11, 15, 16, 17} }; -AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer) { - init(); +// Voice to operator set, for the 5 percussion voices (only useable in percussion mode) +const uint8 AdLib::kVoicePercussionOperator[kOperatorsPerVoice][kPercussionVoiceCount] = { + {12, 16, 14, 17, 13}, + {15, 0, 0, 0, 0} +}; + +// Mask bits to set each percussion instrument on/off +const byte AdLib::kPercussionMasks[kPercussionVoiceCount] = {0x10, 0x08, 0x04, 0x02, 0x01}; + +// Default instrument presets +const uint16 AdLib::kPianoParams [kOperatorsPerVoice][kParamCount] = { + { 1, 1, 3, 15, 5, 0, 1, 3, 15, 0, 0, 0, 1, 0}, + { 0, 1, 1, 15, 7, 0, 2, 4, 0, 0, 0, 1, 0, 0} }; +const uint16 AdLib::kBaseDrumParams[kOperatorsPerVoice][kParamCount] = { + { 0, 0, 0, 10, 4, 0, 8, 12, 11, 0, 0, 0, 1, 0 }, + { 0, 0, 0, 13, 4, 0, 6, 15, 0, 0, 0, 0, 1, 0 } }; +const uint16 AdLib::kSnareDrumParams[kParamCount] = { + 0, 12, 0, 15, 11, 0, 8, 5, 0, 0, 0, 0, 0, 0 }; +const uint16 AdLib::kTomParams [kParamCount] = { + 0, 4, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 }; +const uint16 AdLib::kCymbalParams [kParamCount] = { + 0, 1, 0, 15, 11, 0, 5, 5, 0, 0, 0, 0, 0, 0 }; +const uint16 AdLib::kHihatParams [kParamCount] = { + 0, 1, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 }; + + +AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0), + _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true) { + + _rate = _mixer->getOutputRate(); + + createOPL(); + initOPL(); + + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, + this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); } AdLib::~AdLib() { - Common::StackLock slock(_mutex); - _mixer->stopHandle(_handle); - OPLDestroy(_opl); - if (_data && _freeData) - delete[] _data; + + delete _opl; } -void AdLib::init() { - _index = -1; - _data = 0; - _playPos = 0; - _dataSize = 0; +// Creates the OPL. Try to use the DOSBox emulator, unless that one is not compiled in, +// or the user explicitly wants the MAME emulator. The MAME one is slightly buggy, leading +// to some wrong sounds, especially noticeable in the title music of Gobliins 2, so we +// really don't want to use it, if we can help it. +void AdLib::createOPL() { + Common::String oplDriver = ConfMan.get("opl_driver"); - _rate = _mixer->getOutputRate(); + if (oplDriver.empty() || (oplDriver == "auto") || (OPL::Config::parse(oplDriver) == -1)) { + // User has selected OPL driver auto detection or an invalid OPL driver. + // Set it to our preferred driver (DOSBox), if we can. - _opl = makeAdLibOPL(_rate); + if (OPL::Config::parse("db") <= 0) { + warning("The DOSBox AdLib emulator is not compiled in. Please keep in mind that the MAME one is buggy"); + } else + oplDriver = "db"; - _first = true; - _ended = false; - _playing = false; + } else if (oplDriver == "mame") { + // User has selected the MAME OPL driver. It is buggy, so warn the user about that. - _freeData = false; - - _repCount = -1; - _samplesTillPoll = 0; + warning("You have selected the MAME AdLib emulator. It is buggy; AdLib music might be slightly glitchy now"); + } - for (int i = 0; i < 16; i ++) - _pollNotes[i] = 0; - setFreqs(); + _opl = OPL::Config::create(OPL::Config::parse(oplDriver), OPL::Config::kOpl2); + if (!_opl || !_opl->init(_rate)) { + delete _opl; - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, - this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + error("Could not create an AdLib emulator"); + } } int AdLib::readBuffer(int16 *buffer, const int numSamples) { Common::StackLock slock(_mutex); - int samples; - int render; - if (!_playing || (numSamples < 0)) { - memset(buffer, 0, numSamples * sizeof(int16)); - return numSamples; - } - if (_first) { + // Nothing to do, fill with silence + if (!_playing) { memset(buffer, 0, numSamples * sizeof(int16)); - pollMusic(); return numSamples; } - samples = numSamples; + // Read samples from the OPL, polling in more music when necessary + uint32 samples = numSamples; while (samples && _playing) { - if (_samplesTillPoll) { - render = (samples > _samplesTillPoll) ? (_samplesTillPoll) : (samples); + if (_toPoll) { + const uint32 render = MIN(samples, _toPoll); + + _opl->readBuffer(buffer, render); + + buffer += render; samples -= render; - _samplesTillPoll -= render; - YM3812UpdateOne(_opl, buffer, render); - buffer += render; + _toPoll -= render; + } else { - pollMusic(); + // Song ended, fill the rest with silence if (_ended) { memset(buffer, 0, samples * sizeof(int16)); samples = 0; + break; } + + // Poll more music + _toPoll = pollMusic(_first); + _first = false; } } + // Song ended, loop if requested if (_ended) { - _first = true; - _ended = false; + _toPoll = 0; - rewind(); + // _repCount == 0: No looping (anymore); _repCount < 0: Infinite looping + if (_repCount != 0) { + if (_repCount > 0) + _repCount--; + + _first = true; + _ended = false; - _samplesTillPoll = 0; - if (_repCount == -1) { - reset(); - setVoices(); - } else if (_repCount > 0) { - _repCount--; reset(); - setVoices(); - } - else + rewind(); + } else _playing = false; } - return numSamples; -} - -void AdLib::writeOPL(byte reg, byte val) { - debugC(6, kDebugSound, "AdLib::writeOPL (%02X, %02X)", reg, val); - OPLWriteReg(_opl, reg, val); -} -void AdLib::setFreqs() { - byte lin; - byte col; - long val = 0; - - // Run through the 11 channels - for (lin = 0; lin < 11; lin ++) { - _notes[lin] = 0; - _notCol[lin] = 0; - _notLin[lin] = 0; - _notOn[lin] = false; - } - - // Run through the 25 lines - for (lin = 0; lin < 25; lin ++) { - // Run through the 12 columns - for (col = 0; col < 12; col ++) { - if (!col) - val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) * - 9 / 0x1B503; - _freqs[lin][col] = (short)((val + 4) >> 3); - val = val * 0x6A / 0x64; - } - } + return numSamples; } -void AdLib::reset() { - _first = true; - OPLResetChip(_opl); - _samplesTillPoll = 0; - - setFreqs(); - // Set frequencies and octave to 0; notes off - for (int i = 0; i < 9; i++) { - writeOPL(0xA0 | i, 0); - writeOPL(0xB0 | i, 0); - writeOPL(0xE0 | _operators[i] , 0); - writeOPL(0xE0 |(_operators[i] + 3), 0); - } - - // Authorize the control of the waveformes - writeOPL(0x01, 0x20); -} - -void AdLib::setKey(byte voice, byte note, bool on, bool spec) { - short freq = 0; - short octa = 0; - - // Instruction AX - if (spec) { - // 0x7F donne 0x16B; - // 7F - // << 7 = 3F80 - // + E000 = 11F80 - // & FFFF = 1F80 - // * 19 = 31380 - // / 2000 = 18 => Ligne 18h, colonne 0 => freq 16B - - // 0x3A donne 0x2AF; - // 3A - // << 7 = 1D00 - // + E000 = FD00 negatif - // * 19 = xB500 - // / 2000 = -2 => Ligne 17h, colonne -1 - - // 2E - // << 7 = 1700 - // + E000 = F700 negatif - // * 19 = x1F00 - // / 2000 = - short a; - short lin; - short col; - - a = (note << 7) + 0xE000; // Volontairement tronque - a = (short)((long)a * 25 / 0x2000); - if (a < 0) { - col = - ((24 - a) / 25); - lin = (-a % 25); - if (lin) - lin = 25 - lin; - } - else { - col = a / 25; - lin = a % 25; - } - - _notCol[voice] = col; - _notLin[voice] = lin; - note = _notes[voice]; - } - // Instructions 0X 9X 8X - else { - note -= 12; - _notOn[voice] = on; - } - - _notes[voice] = note; - note += _notCol[voice]; - note = MIN((byte) 0x5F, note); - octa = note / 12; - freq = _freqs[_notLin[voice]][note - octa * 12]; - - writeOPL(0xA0 + voice, freq & 0xFF); - writeOPL(0xB0 + voice, (freq >> 8) | (octa << 2) | (0x20 * (on ? 1 : 0))); - - if (!freq) - warning("AdLib::setKey Voice %d, note %02X unknown", voice, note); +bool AdLib::isStereo() const { + return _opl->isStereo(); } -void AdLib::setVolume(byte voice, byte volume) { - debugC(6, kDebugSound, "AdLib::setVolume(%d, %d)", voice, volume); - //assert(voice >= 0 && voice <= 9); - volume = 0x3F - ((volume * 0x7E) + 0x7F) / 0xFE; - writeOPL(0x40 + _volRegNums[voice], volume); +bool AdLib::endOfData() const { + return !_playing; } -void AdLib::pollMusic() { - if ((_playPos > (_data + _dataSize)) && (_dataSize != 0xFFFFFFFF)) { - _ended = true; - return; - } - - interpret(); +bool AdLib::endOfStream() const { + return false; } -void AdLib::unload() { - _playing = false; - _index = -1; - - if (_data && _freeData) - delete[] _data; - - _freeData = false; +int AdLib::getRate() const { + return _rate; } bool AdLib::isPlaying() const { return _playing; } -bool AdLib::getRepeating() const { - return _repCount != 0; +int32 AdLib::getRepeating() const { + Common::StackLock slock(_mutex); + + return _repCount; } void AdLib::setRepeating(int32 repCount) { + Common::StackLock slock(_mutex); + _repCount = repCount; } -int AdLib::getIndex() const { - return _index; +uint32 AdLib::getSamplesPerSecond() const { + return _rate * (isStereo() ? 2 : 1); } void AdLib::startPlay() { - if (_data) _playing = true; + Common::StackLock slock(_mutex); + + _playing = true; + _ended = false; + _first = true; + + reset(); + rewind(); } void AdLib::stopPlay() { Common::StackLock slock(_mutex); + + end(true); + _playing = false; } -ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer) { -} +void AdLib::writeOPL(byte reg, byte val) { + debugC(6, kDebugSound, "AdLib::writeOPL (%02X, %02X)", reg, val); -ADLPlayer::~ADLPlayer() { + _opl->writeReg(reg, val); } -bool ADLPlayer::load(const char *fileName) { - Common::File song; +void AdLib::reset() { + allOff(); + initOPL(); +} - unload(); - song.open(fileName); - if (!song.isOpen()) - return false; +void AdLib::allOff() { + // NOTE: Explicit casts are necessary, because of 5.16 paragraph 4 of the C++ standard + int numVoices = isPercussionMode() ? (int)kMaxVoiceCount : (int)kMelodyVoiceCount; - _freeData = true; - _dataSize = song.size(); - _data = new byte[_dataSize]; - song.read(_data, _dataSize); - song.close(); + for (int i = 0; i < numVoices; i++) + noteOff(i); +} +void AdLib::end(bool killRepeat) { reset(); - setVoices(); - _playPos = _data + 3 + (_data[1] + 1) * 0x38; - return true; + _ended = true; + + if (killRepeat) + _repCount = 0; } -bool ADLPlayer::load(byte *data, uint32 size, int index) { - unload(); - _repCount = 0; +void AdLib::initOPL() { + _tremoloDepth = false; + _vibratoDepth = false; + _keySplit = false; - _dataSize = size; - _data = data; - _index = index; + _enableWaveSelect = true; - reset(); - setVoices(); - _playPos = _data + 3 + (_data[1] + 1) * 0x38; + for (int i = 0; i < kMaxVoiceCount; i++) { + _voiceNote[i] = 0; + _voiceOn [i] = 0; + } + + _opl->reset(); + + initOperatorVolumes(); + initFreqs(); + + setPercussionMode(false); + + setTremoloDepth(false); + setVibratoDepth(false); + setKeySplit(false); - return true; + for(int i = 0; i < kMelodyVoiceCount; i++) + voiceOff(i); + + setPitchRange(1); + + enableWaveSelect(true); } -void ADLPlayer::unload() { - AdLib::unload(); +bool AdLib::isPercussionMode() const { + return _percussionMode; } -void ADLPlayer::interpret() { - unsigned char instr; - byte channel; - byte note; - byte volume; - uint16 tempo; +void AdLib::setPercussionMode(bool percussion) { + if (percussion) { + voiceOff(kVoiceBaseDrum); + voiceOff(kVoiceSnareDrum); + voiceOff(kVoiceTom); - // First tempo, we'll ignore it... - if (_first) { - tempo = *(_playPos++); - // Tempo on 2 bytes - if (tempo & 0x80) - tempo = ((tempo & 3) << 8) | *(_playPos++); - } - _first = false; - - // Instruction - instr = *(_playPos++); - channel = instr & 0x0F; - - switch (instr & 0xF0) { - // Note on + Volume - case 0x00: - note = *(_playPos++); - _pollNotes[channel] = note; - setVolume(channel, *(_playPos++)); - setKey(channel, note, true, false); - break; - // Note on - case 0x90: - note = *(_playPos++); - _pollNotes[channel] = note; - setKey(channel, note, true, false); - break; - // Last note off - case 0x80: - note = _pollNotes[channel]; - setKey(channel, note, false, false); - break; - // Frequency on/off - case 0xA0: - note = *(_playPos++); - setKey(channel, note, _notOn[channel], true); - break; - // Volume - case 0xB0: - volume = *(_playPos++); - setVolume(channel, volume); - break; - // Program change - case 0xC0: - setVoice(channel, *(_playPos++), false); - break; - // Special - case 0xF0: - switch (instr & 0x0F) { - case 0xF: // End instruction - _ended = true; - _samplesTillPoll = 0; - return; - default: - warning("ADLPlayer: Unknown special command %X, stopping playback", - instr & 0x0F); - _repCount = 0; - _ended = true; - break; - } - break; - default: - warning("ADLPlayer: Unknown command %X, stopping playback", - instr & 0xF0); - _repCount = 0; - _ended = true; - break; + /* set the frequency for the last 4 percussion voices: */ + setFreq(kVoiceTom, kPitchTom, 0); + setFreq(kVoiceSnareDrum, kPitchSnareDrum, 0); } - // Temporization - tempo = *(_playPos++); - // End tempo - if (tempo == 0xFF) { - _ended = true; - return; - } - // Tempo on 2 bytes - if (tempo & 0x80) - tempo = ((tempo & 3) << 8) | *(_playPos++); - if (!tempo) - tempo ++; + _percussionMode = percussion; + _percussionBits = 0; - _samplesTillPoll = tempo * (_rate / 1000); + initOperatorParams(); + writeTremoloVibratoDepthPercMode(); } -void ADLPlayer::reset() { - AdLib::reset(); +void AdLib::enableWaveSelect(bool enable) { + _enableWaveSelect = enable; + + for (int i = 0; i < kOperatorCount; i++) + writeOPL(0xE0 + kOperatorOffset[i], 0); + + writeOPL(0x011, _enableWaveSelect ? 0x20 : 0); } -void ADLPlayer::rewind() { - _playPos = _data + 3 + (_data[1] + 1) * 0x38; +void AdLib::setPitchRange(uint8 range) { + _pitchRange = CLIP(range, 0, 12); + _pitchRangeStep = _pitchRange * kPitchStepCount; } -void ADLPlayer::setVoices() { - // Definitions of the 9 instruments - for (int i = 0; i < 9; i++) - setVoice(i, i, true); +void AdLib::setTremoloDepth(bool tremoloDepth) { + _tremoloDepth = tremoloDepth; + + writeTremoloVibratoDepthPercMode(); } -void ADLPlayer::setVoice(byte voice, byte instr, bool set) { - uint16 strct[27]; - byte channel; - byte *dataPtr; +void AdLib::setVibratoDepth(bool vibratoDepth) { + _vibratoDepth = vibratoDepth; - // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 - // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 - for (int i = 0; i < 2; i++) { - dataPtr = _data + 3 + instr * 0x38 + i * 0x1A; - for (int j = 0; j < 27; j++) { - strct[j] = READ_LE_UINT16(dataPtr); - dataPtr += 2; - } - channel = _operators[voice] + i * 3; - writeOPL(0xBD, 0x00); - writeOPL(0x08, 0x00); - writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); - if (!i) - writeOPL(0xC0 | voice, - ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); - writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); - writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); - writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | - ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | - ((strct[11] & 1) << 4) | (strct[1] & 0xF)); - if (!i) - writeOPL(0xE0 | channel, (strct[26] & 3)); - else - writeOPL(0xE0 | channel, (strct[14] & 3)); - if (i && set) - writeOPL(0x40 | channel, 0); + writeTremoloVibratoDepthPercMode(); +} + +void AdLib::setKeySplit(bool keySplit) { + _keySplit = keySplit; + + writeKeySplit(); +} + +void AdLib::setVoiceTimbre(uint8 voice, const uint16 *params) { + const uint16 *params0 = params; + const uint16 *params1 = params + kParamCount - 1; + const uint16 *waves = params + 2 * (kParamCount - 1); + + const int voicePerc = voice - kVoiceBaseDrum; + + if (!isPercussionMode() || (voice < kVoiceBaseDrum)) { + setOperatorParams(kVoiceMelodyOperator[0][voice], params0, waves[0]); + setOperatorParams(kVoiceMelodyOperator[1][voice], params1, waves[1]); + } else if (voice == kVoiceBaseDrum) { + setOperatorParams(kVoicePercussionOperator[0][voicePerc], params0, waves[0]); + setOperatorParams(kVoicePercussionOperator[1][voicePerc], params1, waves[1]); + } else { + setOperatorParams(kVoicePercussionOperator[0][voicePerc], params0, waves[0]); } } +void AdLib::setVoiceVolume(uint8 voice, uint8 volume) { + int oper; + + const int voicePerc = voice - kVoiceBaseDrum; + + if (!isPercussionMode() || (voice < kVoiceBaseDrum)) + oper = kVoiceMelodyOperator[1][ voice]; + else + oper = kVoicePercussionOperator[voice == kVoiceBaseDrum ? 1 : 0][voicePerc]; -MDYPlayer::MDYPlayer(Audio::Mixer &mixer) : AdLib(mixer) { - init(); + _operatorVolume[oper] = MIN(volume, kMaxVolume); + writeKeyScaleLevelVolume(oper); } -MDYPlayer::~MDYPlayer() { +void AdLib::bendVoicePitch(uint8 voice, uint16 pitchBend) { + if (isPercussionMode() && (voice > kVoiceBaseDrum)) + return; + + changePitch(voice, MIN(pitchBend, kMaxPitch)); + setFreq(voice, _voiceNote[voice], _voiceOn[voice]); } -void MDYPlayer::init() { - _soundMode = 0; +void AdLib::noteOn(uint8 voice, uint8 note) { + note = MAX(0, note - (kStandardMidC - kOPLMidC)); + + if (isPercussionMode() && (voice >= kVoiceBaseDrum)) { + + if (voice == kVoiceBaseDrum) { + setFreq(kVoiceBaseDrum , note , false); + } else if (voice == kVoiceTom) { + setFreq(kVoiceTom , note , false); + setFreq(kVoiceSnareDrum, note + kPitchTomToSnare, false); + } + + _percussionBits |= kPercussionMasks[voice - kVoiceBaseDrum]; + writeTremoloVibratoDepthPercMode(); - _timbres = 0; - _tbrCount = 0; - _tbrStart = 0; - _timbresSize = 0; + } else + setFreq(voice, note, true); } -bool MDYPlayer::loadMDY(Common::SeekableReadStream &stream) { - unloadMDY(); +void AdLib::noteOff(uint8 voice) { + if (isPercussionMode() && (voice >= kVoiceBaseDrum)) { + _percussionBits &= ~kPercussionMasks[voice - kVoiceBaseDrum]; + writeTremoloVibratoDepthPercMode(); + } else + setFreq(voice, _voiceNote[voice], false); +} - _freeData = true; +void AdLib::writeKeyScaleLevelVolume(uint8 oper) { + uint16 volume = 0; - byte mdyHeader[70]; - stream.read(mdyHeader, 70); + volume = (63 - (_operatorParams[oper][kParamLevel] & 0x3F)) * _operatorVolume[oper]; + volume = 63 - ((2 * volume + kMaxVolume) / (2 * kMaxVolume)); - _tickBeat = mdyHeader[36]; - _beatMeasure = mdyHeader[37]; - _totalTick = mdyHeader[38] + (mdyHeader[39] << 8) + (mdyHeader[40] << 16) + (mdyHeader[41] << 24); - _dataSize = mdyHeader[42] + (mdyHeader[43] << 8) + (mdyHeader[44] << 16) + (mdyHeader[45] << 24); - _nrCommand = mdyHeader[46] + (mdyHeader[47] << 8) + (mdyHeader[48] << 16) + (mdyHeader[49] << 24); -// _soundMode is either 0 (melodic) or 1 (percussive) - _soundMode = mdyHeader[58]; - assert((_soundMode == 0) || (_soundMode == 1)); + uint8 keyScale = _operatorParams[oper][kParamKeyScaleLevel] << 6; - _pitchBendRangeStep = 25*mdyHeader[59]; - _basicTempo = mdyHeader[60] + (mdyHeader[61] << 8); + writeOPL(0x40 + kOperatorOffset[oper], volume | keyScale); +} - if (_pitchBendRangeStep < 25) - _pitchBendRangeStep = 25; - else if (_pitchBendRangeStep > 300) - _pitchBendRangeStep = 300; +void AdLib::writeKeySplit() { + writeOPL(0x08, _keySplit ? 0x40 : 0); +} - _data = new byte[_dataSize]; - stream.read(_data, _dataSize); +void AdLib::writeFeedbackFM(uint8 oper) { + if (kOperatorType[oper] == 1) + return; - reset(); - _playPos = _data; + uint8 value = 0; + + value |= _operatorParams[oper][kParamFeedback] << 1; + value |= _operatorParams[oper][kParamFM] ? 0 : 1; - return true; + writeOPL(0xC0 + kOperatorVoice[oper], value); } -bool MDYPlayer::loadMDY(const char *fileName) { - Common::File song; +void AdLib::writeAttackDecay(uint8 oper) { + uint8 value = 0; - song.open(fileName); - if (!song.isOpen()) - return false; + value |= _operatorParams[oper][kParamAttack] << 4; + value |= _operatorParams[oper][kParamDecay] & 0x0F; - bool loaded = loadMDY(song); + writeOPL(0x60 + kOperatorOffset[oper], value); +} - song.close(); +void AdLib::writeSustainRelease(uint8 oper) { + uint8 value = 0; - return loaded; + value |= _operatorParams[oper][kParamSustain] << 4; + value |= _operatorParams[oper][kParamRelease] & 0x0F; + + writeOPL(0x80 + kOperatorOffset[oper], value); } -bool MDYPlayer::loadTBR(Common::SeekableReadStream &stream) { - unloadTBR(); +void AdLib::writeTremoloVibratoSustainingKeyScaleRateFreqMulti(uint8 oper) { + uint8 value = 0; + + value |= _operatorParams[oper][kParamAM] ? 0x80 : 0; + value |= _operatorParams[oper][kParamVib] ? 0x40 : 0; + value |= _operatorParams[oper][kParamSustaining] ? 0x20 : 0; + value |= _operatorParams[oper][kParamKeyScaleRate] ? 0x10 : 0; + value |= _operatorParams[oper][kParamFreqMulti] & 0x0F; - _timbresSize = stream.size(); + writeOPL(0x20 + kOperatorOffset[oper], value); +} - _timbres = new byte[_timbresSize]; - stream.read(_timbres, _timbresSize); +void AdLib::writeTremoloVibratoDepthPercMode() { + uint8 value = 0; - reset(); - setVoices(); + value |= _tremoloDepth ? 0x80 : 0; + value |= _vibratoDepth ? 0x40 : 0; + value |= isPercussionMode() ? 0x20 : 0; + value |= _percussionBits; - return true; + writeOPL(0xBD, value); } -bool MDYPlayer::loadTBR(const char *fileName) { - Common::File timbres; +void AdLib::writeWaveSelect(uint8 oper) { + uint8 wave = 0; + if (_enableWaveSelect) + wave = _operatorParams[oper][kParamWaveSelect] & 0x03; - timbres.open(fileName); - if (!timbres.isOpen()) - return false; + writeOPL(0xE0 + kOperatorOffset[ oper], wave); +} + +void AdLib::writeAllParams(uint8 oper) { + writeTremoloVibratoDepthPercMode(); + writeKeySplit(); + writeKeyScaleLevelVolume(oper); + writeFeedbackFM(oper); + writeAttackDecay(oper); + writeSustainRelease(oper); + writeTremoloVibratoSustainingKeyScaleRateFreqMulti(oper); + writeWaveSelect(oper); +} - bool loaded = loadTBR(timbres); +void AdLib::initOperatorParams() { + for (int i = 0; i < kOperatorCount; i++) + setOperatorParams(i, kPianoParams[kOperatorType[i]], kPianoParams[kOperatorType[i]][kParamCount - 1]); - timbres.close(); + if (isPercussionMode()) { + setOperatorParams(12, kBaseDrumParams [0], kBaseDrumParams [0][kParamCount - 1]); + setOperatorParams(15, kBaseDrumParams [1], kBaseDrumParams [1][kParamCount - 1]); + setOperatorParams(16, kSnareDrumParams , kSnareDrumParams [kParamCount - 1]); + setOperatorParams(14, kTomParams , kTomParams [kParamCount - 1]); + setOperatorParams(17, kCymbalParams , kCymbalParams [kParamCount - 1]); + setOperatorParams(13, kHihatParams , kHihatParams [kParamCount - 1]); + } +} - return loaded; +void AdLib::initOperatorVolumes() { + for(int i = 0; i < kOperatorCount; i++) + _operatorVolume[i] = kMaxVolume; } -void MDYPlayer::unload() { - unloadTBR(); - unloadMDY(); +void AdLib::setOperatorParams(uint8 oper, const uint16 *params, uint8 wave) { + byte *operParams = _operatorParams[oper]; + + for (int i = 0; i < (kParamCount - 1); i++) + operParams[i] = params[i]; + + operParams[kParamCount - 1] = wave & 0x03; + + writeAllParams(oper); } -void MDYPlayer::unloadMDY() { - AdLib::unload(); +void AdLib::voiceOff(uint8 voice) { + writeOPL(0xA0 + voice, 0); + writeOPL(0xB0 + voice, 0); } -void MDYPlayer::unloadTBR() { - delete[] _timbres; +int32 AdLib::calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom) { + int32 freq = 0; - _timbres = 0; - _timbresSize = 0; + freq = ((deltaDemiToneDenom * 100) + 6 * deltaDemiToneNum) * 52088; + freq /= deltaDemiToneDenom * 2500; + + return (freq * 147456) / 111875; } -void MDYPlayer::interpret() { - unsigned char instr; - byte channel; - byte note; - byte volume; - uint8 tempoMult, tempoFrac; - uint8 ctrlByte1, ctrlByte2; - uint8 timbre; +void AdLib::setFreqs(uint16 *freqs, int32 num, int32 denom) { + int32 val = calcFreq(num, denom); -// TODO : Verify the loop for percussive mode (11 ?) - if (_first) { - for (int i = 0; i < 9; i ++) - setVolume(i, 0); + *freqs++ = (4 + val) >> 3; -// TODO : Set pitch range + for (int i = 1; i < kHalfToneCount; i++) { + val = (val * 106) / 100; - _tempo = _basicTempo; - _wait = *(_playPos++); - _first = false; + *freqs++ = (4 + val) >> 3; } - do { - instr = *_playPos; - debugC(6, kDebugSound, "MDYPlayer::interpret instr 0x%X", instr); - switch (instr) { - case 0xF8: - _wait = *(_playPos++); - break; - case 0xFC: - _ended = true; - _samplesTillPoll = 0; - return; - case 0xF0: - _playPos++; - ctrlByte1 = *(_playPos++); - ctrlByte2 = *(_playPos++); - debugC(6, kDebugSound, "MDYPlayer::interpret ctrlBytes 0x%X 0x%X", ctrlByte1, ctrlByte2); - if (ctrlByte1 != 0x7F || ctrlByte2 != 0) { - _playPos -= 2; - while (*(_playPos++) != 0xF7) - ; - } else { - tempoMult = *(_playPos++); - tempoFrac = *(_playPos++); - _tempo = _basicTempo * tempoMult + (unsigned)(((long)_basicTempo * tempoFrac) >> 7); - _playPos++; - } - _wait = *(_playPos++); - break; - default: - if (instr >= 0x80) { - _playPos++; - } - channel = (int)(instr & 0x0f); - - switch (instr & 0xf0) { - case 0x90: - note = *(_playPos++); - volume = *(_playPos++); - _pollNotes[channel] = note; - setVolume(channel, volume); - setKey(channel, note, true, false); - break; - case 0x80: - _playPos += 2; - note = _pollNotes[channel]; - setKey(channel, note, false, false); - break; - case 0xA0: - setVolume(channel, *(_playPos++)); - break; - case 0xC0: - timbre = *(_playPos++); - setVoice(channel, timbre, false); - break; - case 0xE0: - warning("MDYPlayer: Pitch bend not yet implemented"); +} - note = *(_playPos)++; - note += (unsigned)(*(_playPos++)) << 7; +void AdLib::initFreqs() { + const int numStep = 100 / kPitchStepCount; - setKey(channel, note, _notOn[channel], true); + for (int i = 0; i < kPitchStepCount; i++) + setFreqs(_freqs[i], i * numStep, 100); - break; - case 0xB0: - _playPos += 2; - break; - case 0xD0: - _playPos++; - break; - default: - warning("MDYPlayer: Bad MIDI instr byte: 0%X", instr); - while ((*_playPos) < 0x80) - _playPos++; - if (*_playPos != 0xF8) - _playPos--; - break; - } //switch instr & 0xF0 - _wait = *(_playPos++); - break; - } //switch instr - } while (_wait == 0); - - if (_wait == 0xF8) { - _wait = 0xF0; - if (*_playPos != 0xF8) - _wait += *(_playPos++) & 0x0F; + for (int i = 0; i < kMaxVoiceCount; i++) { + _freqPtr [i] = _freqs[0]; + _halfToneOffset[i] = 0; } -// _playPos++; - _samplesTillPoll = _wait * (_rate / 1000); } -void MDYPlayer::reset() { - AdLib::reset(); +void AdLib::changePitch(uint8 voice, uint16 pitchBend) { + + int full = 0; + int frac = 0; + int amount = ((pitchBend - kMidPitch) * _pitchRangeStep) / kMidPitch; + + if (amount >= 0) { + // Bend up + + full = amount / kPitchStepCount; + frac = amount % kPitchStepCount; -// _soundMode 1 : Percussive mode. - if (_soundMode == 1) { - writeOPL(0xA6, 0); - writeOPL(0xB6, 0); - writeOPL(0xA7, 0); - writeOPL(0xB7, 0); - writeOPL(0xA8, 0); - writeOPL(0xB8, 0); + } else { + // Bend down + + amount = kPitchStepCount - 1 - amount; + + full = -(amount / kPitchStepCount); + frac = (amount - kPitchStepCount + 1) % kPitchStepCount; + if (frac) + frac = kPitchStepCount - frac; -// TODO set the correct frequency for the last 4 percussive voices } + + _halfToneOffset[voice] = full; + _freqPtr [voice] = _freqs[frac]; } -void MDYPlayer::rewind() { - _playPos = _data; -} - -void MDYPlayer::setVoices() { - byte *timbrePtr; - - timbrePtr = _timbres; - debugC(6, kDebugSound, "MDYPlayer::setVoices TBR version: %X.%X", timbrePtr[0], timbrePtr[1]); - timbrePtr += 2; - - _tbrCount = READ_LE_UINT16(timbrePtr); - debugC(6, kDebugSound, "MDYPlayer::setVoices Timbres counter: %d", _tbrCount); - timbrePtr += 2; - _tbrStart = READ_LE_UINT16(timbrePtr); - - timbrePtr += 2; - for (int i = 0; i < _tbrCount; i++) - setVoice(i, i, true); -} - -void MDYPlayer::setVoice(byte voice, byte instr, bool set) { -// uint16 strct[27]; - uint8 strct[27]; - byte channel; - byte *timbrePtr; - char timbreName[10]; - - timbreName[9] = '\0'; - for (int j = 0; j < 9; j++) - timbreName[j] = _timbres[6 + j + (instr * 9)]; - debugC(6, kDebugSound, "MDYPlayer::setVoice Loading timbre %s", timbreName); - - // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 - // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 - for (int i = 0; i < 2; i++) { - timbrePtr = _timbres + _tbrStart + instr * 0x38 + i * 0x1A; - for (int j = 0; j < 27; j++) { - if (timbrePtr >= (_timbres + _timbresSize)) { - warning("MDYPlayer: Instrument %d out of range (%d, %d)", instr, - (uint32) (timbrePtr - _timbres), _timbresSize); - strct[j] = 0; - } else - //strct[j] = READ_LE_UINT16(timbrePtr); - strct[j] = timbrePtr[0]; - //timbrePtr += 2; - timbrePtr++; - } - channel = _operators[voice] + i * 3; - writeOPL(0xBD, 0x00); - writeOPL(0x08, 0x00); - writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); - if (!i) - writeOPL(0xC0 | voice, - ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); - writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); - writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); - writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | - ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | - ((strct[11] & 1) << 4) | (strct[1] & 0xF)); - if (!i) - writeOPL(0xE0 | channel, (strct[26] & 3)); - else { - writeOPL(0xE0 | channel, (strct[14] & 3)); - writeOPL(0x40 | channel, 0); - } - } +void AdLib::setFreq(uint8 voice, uint16 note, bool on) { + _voiceOn [voice] = on; + _voiceNote[voice] = note; + + note = CLIP(note + _halfToneOffset[voice], 0, kNoteCount - 1); + + uint16 freq = _freqPtr[voice][note % kHalfToneCount]; + + uint8 value = 0; + value |= on ? 0x20 : 0; + value |= ((note / kHalfToneCount) << 2) | ((freq >> 8) & 0x03); + + writeOPL(0xA0 + voice, freq); + writeOPL(0xB0 + voice, value); } } // End of namespace Gob diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 934e9966eb..df1b77fd4d 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -20,154 +20,287 @@ * */ -#ifndef GOB_SOUND_ADLIB_H -#define GOB_SOUND_ADLIB_H +#ifndef GOB_SOUND_NEWADLIB_H +#define GOB_SOUND_NEWADLIB_H #include "common/mutex.h" + #include "audio/audiostream.h" #include "audio/mixer.h" -#include "audio/fmopl.h" -namespace Gob { +namespace OPL { + class OPL; +} -class GobEngine; +namespace Gob { +/** Base class for a player of an AdLib music format. */ class AdLib : public Audio::AudioStream { public: AdLib(Audio::Mixer &mixer); virtual ~AdLib(); - bool isPlaying() const; - int getIndex() const; - bool getRepeating() const; + bool isPlaying() const; ///< Are we currently playing? + int32 getRepeating() const; ///< Return number of times left to loop. + /** Set the loop counter. + * + * @param repCount Number of times to loop (i.e. number of additional + * paythroughs to the first one, not overall). + * A negative value means infinite looping. + */ void setRepeating(int32 repCount); void startPlay(); void stopPlay(); - virtual void unload(); - // AudioStream API int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return false; } - bool endOfData() const { return !_playing; } - bool endOfStream() const { return false; } - int getRate() const { return _rate; } + bool isStereo() const; + bool endOfData() const; + bool endOfStream() const; + int getRate() const; protected: - static const unsigned char _operators[]; - static const unsigned char _volRegNums []; + enum kVoice { + kVoiceMelody0 = 0, + kVoiceMelody1 = 1, + kVoiceMelody2 = 2, + kVoiceMelody3 = 3, + kVoiceMelody4 = 4, + kVoiceMelody5 = 5, + kVoiceMelody6 = 6, // Only available in melody mode. + kVoiceMelody7 = 7, // Only available in melody mode. + kVoiceMelody8 = 8, // Only available in melody mode. + kVoiceBaseDrum = 6, // Only available in percussion mode. + kVoiceSnareDrum = 7, // Only available in percussion mode. + kVoiceTom = 8, // Only available in percussion mode. + kVoiceCymbal = 9, // Only available in percussion mode. + kVoiceHihat = 10 // Only available in percussion mode. + }; + + /** Operator parameters. */ + enum kParam { + kParamKeyScaleLevel = 0, + kParamFreqMulti = 1, + kParamFeedback = 2, + kParamAttack = 3, + kParamSustain = 4, + kParamSustaining = 5, + kParamDecay = 6, + kParamRelease = 7, + kParamLevel = 8, + kParamAM = 9, + kParamVib = 10, + kParamKeyScaleRate = 11, + kParamFM = 12, + kParamWaveSelect = 13 + }; + + static const int kOperatorCount = 18; ///< Number of operators. + static const int kParamCount = 14; ///< Number of operator parameters. + static const int kPitchStepCount = 25; ///< Number of pitch bend steps in a half tone. + static const int kOctaveCount = 8; ///< Number of octaves we can play. + static const int kHalfToneCount = 12; ///< Number of half tones in an octave. + + static const int kOperatorsPerVoice = 2; ///< Number of operators per voice. + + static const int kMelodyVoiceCount = 9; ///< Number of melody voices. + static const int kPercussionVoiceCount = 5; ///< Number of percussion voices. + static const int kMaxVoiceCount = 11; ///< Max number of voices. + + /** Number of notes we can play. */ + static const int kNoteCount = kHalfToneCount * kOctaveCount; + + static const int kMaxVolume = 0x007F; + static const int kMaxPitch = 0x3FFF; + static const int kMidPitch = 0x2000; + + static const int kStandardMidC = 60; ///< A mid C in standard MIDI. + static const int kOPLMidC = 48; ///< A mid C for the OPL. + + + /** Return the number of samples per second. */ + uint32 getSamplesPerSecond() const; + + /** Write a value into an OPL register. */ + void writeOPL(byte reg, byte val); + + /** Signal that the playback ended. + * + * @param killRepeat Explicitly request that the song is not to be looped. + */ + void end(bool killRepeat = false); + + /** The callback function that's called for polling more AdLib commands. + * + * @param first Is this the first poll since the start of the song? + * @return The number of samples until the next poll. + */ + virtual uint32 pollMusic(bool first) = 0; + + /** Rewind the song. */ + virtual void rewind() = 0; + + /** Return whether we're in percussion mode. */ + bool isPercussionMode() const; + + /** Set percussion or melody mode. */ + void setPercussionMode(bool percussion); + + /** Enable/Disable the wave select operator parameters. + * + * When disabled, all operators use the sine wave, regardless of the parameter. + */ + void enableWaveSelect(bool enable); + + /** Change the pitch bend range. + * + * @param range The range in half tones from 1 to 12 inclusive. + * See bendVoicePitch() for how this works in practice. + */ + void setPitchRange(uint8 range); + + /** Set the tremolo (amplitude vibrato) depth. + * + * @param tremoloDepth false: 1.0dB, true: 4.8dB. + */ + void setTremoloDepth(bool tremoloDepth); + + /** Set the frequency vibrato depth. + * + * @param vibratoDepth false: 7 cent, true: 14 cent. 1 cent = 1/100 half tone. + */ + void setVibratoDepth(bool vibratoDepth); + + /** Set the keyboard split point. */ + void setKeySplit(bool keySplit); + + /** Set the timbre of a voice. + * + * Layout of the operator parameters is as follows: + * - First 13 parameter for the first operator + * - First 13 parameter for the second operator + * - 14th parameter (wave select) for the first operator + * - 14th parameter (wave select) for the second operator + */ + void setVoiceTimbre(uint8 voice, const uint16 *params); + + /** Set a voice's volume. */ + void setVoiceVolume(uint8 voice, uint8 volume); + + /** Bend a voice's pitch. + * + * The pitchBend parameter is a value between 0 (full down) and kMaxPitch (full up). + * The actual frequency depends on the pitch range set previously by setPitchRange(), + * with full down being -range half tones and full up range half tones. + */ + void bendVoicePitch(uint8 voice, uint16 pitchBend); + + /** Switch a voice on. + * + * Plays one of the kNoteCount notes. However, the valid range of a note is between + * 0 and 127, of which only 12 to 107 are audible. + */ + void noteOn(uint8 voice, uint8 note); + + /** Switch a voice off. */ + void noteOff(uint8 voice); + +private: + static const uint8 kOperatorType [kOperatorCount]; + static const uint8 kOperatorOffset[kOperatorCount]; + static const uint8 kOperatorVoice [kOperatorCount]; + + static const uint8 kVoiceMelodyOperator [kOperatorsPerVoice][kMelodyVoiceCount]; + static const uint8 kVoicePercussionOperator[kOperatorsPerVoice][kPercussionVoiceCount]; + + static const byte kPercussionMasks[kPercussionVoiceCount]; + + static const uint16 kPianoParams [kOperatorsPerVoice][kParamCount]; + static const uint16 kBaseDrumParams [kOperatorsPerVoice][kParamCount]; + + static const uint16 kSnareDrumParams[kParamCount]; + static const uint16 kTomParams [kParamCount]; + static const uint16 kCymbalParams [kParamCount]; + static const uint16 kHihatParams [kParamCount]; + Audio::Mixer *_mixer; Audio::SoundHandle _handle; - FM_OPL *_opl; + OPL::OPL *_opl; Common::Mutex _mutex; uint32 _rate; - byte *_data; - byte *_playPos; - uint32 _dataSize; - - short _freqs[25][12]; - byte _notes[11]; - byte _notCol[11]; - byte _notLin[11]; - bool _notOn[11]; - byte _pollNotes[16]; + uint32 _toPoll; - int _samplesTillPoll; int32 _repCount; - bool _playing; bool _first; + bool _playing; bool _ended; - bool _freeData; + bool _tremoloDepth; + bool _vibratoDepth; + bool _keySplit; - int _index; + bool _enableWaveSelect; - unsigned char _wait; - uint8 _tickBeat; - uint8 _beatMeasure; - uint32 _totalTick; - uint32 _nrCommand; - uint16 _pitchBendRangeStep; - uint16 _basicTempo, _tempo; + bool _percussionMode; + byte _percussionBits; - void writeOPL(byte reg, byte val); - void setFreqs(); - void setKey(byte voice, byte note, bool on, bool spec); - void setVolume(byte voice, byte volume); - void pollMusic(); + uint8 _pitchRange; + uint16 _pitchRangeStep; - virtual void interpret() = 0; + uint8 _voiceNote[kMaxVoiceCount]; // Last note of each voice + uint8 _voiceOn [kMaxVoiceCount]; // Whether each voice is currently on - virtual void reset(); - virtual void rewind() = 0; - virtual void setVoices() = 0; + uint8 _operatorVolume[kOperatorCount]; // Volume of each operator -private: - void init(); -}; + byte _operatorParams[kOperatorCount][kParamCount]; // All operator parameters -class ADLPlayer : public AdLib { -public: - ADLPlayer(Audio::Mixer &mixer); - ~ADLPlayer(); + uint16 _freqs[kPitchStepCount][kHalfToneCount]; + uint16 *_freqPtr[kMaxVoiceCount]; - bool load(const char *fileName); - bool load(byte *data, uint32 size, int index = -1); + int _halfToneOffset[kMaxVoiceCount]; - void unload(); -protected: - void interpret(); + void createOPL(); + void initOPL(); void reset(); - void rewind(); + void allOff(); - void setVoices(); - void setVoice(byte voice, byte instr, bool set); -}; + // Write global parameters into the OPL + void writeTremoloVibratoDepthPercMode(); + void writeKeySplit(); -class MDYPlayer : public AdLib { -public: - MDYPlayer(Audio::Mixer &mixer); - ~MDYPlayer(); - - bool loadMDY(const char *fileName); - bool loadMDY(Common::SeekableReadStream &stream); - bool loadTBR(const char *fileName); - bool loadTBR(Common::SeekableReadStream &stream); - - void unload(); - -protected: - byte _soundMode; - - byte *_timbres; - uint16 _tbrCount; - uint16 _tbrStart; - uint32 _timbresSize; + // Write operator parameters into the OPL + void writeWaveSelect(uint8 oper); + void writeTremoloVibratoSustainingKeyScaleRateFreqMulti(uint8 oper); + void writeSustainRelease(uint8 oper); + void writeAttackDecay(uint8 oper); + void writeFeedbackFM(uint8 oper); + void writeKeyScaleLevelVolume(uint8 oper); + void writeAllParams(uint8 oper); - void interpret(); + void initOperatorParams(); + void initOperatorVolumes(); + void setOperatorParams(uint8 oper, const uint16 *params, uint8 wave); - void reset(); - void rewind(); + void voiceOff(uint8 voice); - void setVoices(); - void setVoice(byte voice, byte instr, bool set); + void initFreqs(); + void setFreqs(uint16 *freqs, int32 num, int32 denom); + int32 calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom); - void unloadTBR(); - void unloadMDY(); + void changePitch(uint8 voice, uint16 pitchBend); -private: - void init(); + void setFreq(uint8 voice, uint16 note, bool on); }; } // End of namespace Gob -#endif // GOB_SOUND_ADLIB_H +#endif // GOB_SOUND_NEWADLIB_H diff --git a/engines/gob/sound/adlplayer.cpp b/engines/gob/sound/adlplayer.cpp new file mode 100644 index 0000000000..ee23191c0d --- /dev/null +++ b/engines/gob/sound/adlplayer.cpp @@ -0,0 +1,257 @@ +/* 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 "common/stream.h" +#include "common/memstream.h" +#include "common/textconsole.h" + +#include "gob/sound/adlplayer.h" + +namespace Gob { + +ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer), + _songData(0), _songDataSize(0), _playPos(0) { + +} + +ADLPlayer::~ADLPlayer() { + unload(); +} + +void ADLPlayer::unload() { + stopPlay(); + + _timbres.clear(); + + delete[] _songData; + + _songData = 0; + _songDataSize = 0; + + _playPos = 0; +} + +uint32 ADLPlayer::pollMusic(bool first) { + if (_timbres.empty() || !_songData || !_playPos || (_playPos >= (_songData + _songDataSize))) { + end(); + return 0; + } + + // We'll ignore the first delay + if (first) + _playPos += (*_playPos & 0x80) ? 2 : 1; + + byte cmd = *_playPos++; + + // Song end marker + if (cmd == 0xFF) { + end(); + return 0; + } + + // Set the instrument that should be modified + if (cmd == 0xFE) + _modifyInstrument = *_playPos++; + + if (cmd >= 0xD0) { + // Modify an instrument + + if (_modifyInstrument == 0xFF) + warning("ADLPlayer: No instrument to modify"); + else if (_modifyInstrument >= _timbres.size()) + warning("ADLPlayer: Can't modify invalid instrument %d (%d)", _modifyInstrument, _timbres.size()); + else + _timbres[_modifyInstrument].params[_playPos[0]] = _playPos[1]; + + _playPos += 2; + + // If we currently have that instrument loaded, reload it + for (int i = 0; i < kMaxVoiceCount; i++) + if (_currentInstruments[i] == _modifyInstrument) + setInstrument(i, _modifyInstrument); + } else { + // Voice command + + uint8 voice = cmd & 0x0F; + uint8 note, volume; + + switch (cmd & 0xF0) { + case 0x00: // Note on with volume + note = *_playPos++; + volume = *_playPos++; + + setVoiceVolume(voice, volume); + noteOn(voice, note); + break; + + case 0xA0: // Pitch bend + bendVoicePitch(voice, ((uint16)*_playPos++) << 7); + break; + + case 0xB0: // Set volume + setVoiceVolume(voice, *_playPos++); + break; + + case 0xC0: // Set instrument + setInstrument(voice, *_playPos++); + break; + + case 0x90: // Note on + noteOn(voice, *_playPos++); + break; + + case 0x80: // Note off + noteOff(voice); + break; + + default: + warning("ADLPlayer: Unsupported command: 0x%02X. Stopping playback.", cmd); + end(true); + return 0; + } + } + + uint16 delay = *_playPos++; + + if (delay & 0x80) + delay = ((delay & 3) << 8) | *_playPos++; + + return getSampleDelay(delay); +} + +uint32 ADLPlayer::getSampleDelay(uint16 delay) const { + if (delay == 0) + return 0; + + return ((uint32)delay * getSamplesPerSecond()) / 1000; +} + +void ADLPlayer::rewind() { + // Reset song data + _playPos = _songData; + + // Set melody/percussion mode + setPercussionMode(_soundMode != 0); + + // Reset instruments + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) + memcpy(t->params, t->startParams, kOperatorsPerVoice * kParamCount * sizeof(uint16)); + + for (int i = 0; i < kMaxVoiceCount; i++) + _currentInstruments[i] = 0; + + // Reset voices + int numVoice = MIN(_timbres.size(), _soundMode ? (int)kMaxVoiceCount : (int)kMelodyVoiceCount); + for (int i = 0; i < numVoice; i++) { + setInstrument(i, _currentInstruments[i]); + setVoiceVolume(i, kMaxVolume); + } + + _modifyInstrument = 0xFF; +} + +bool ADLPlayer::load(Common::SeekableReadStream &adl) { + unload(); + + int timbreCount; + if (!readHeader(adl, timbreCount)) { + unload(); + return false; + } + + if (!readTimbres(adl, timbreCount) || !readSongData(adl) || adl.err()) { + unload(); + return false; + } + + rewind(); + + return true; +} + +bool ADLPlayer::readHeader(Common::SeekableReadStream &adl, int &timbreCount) { + // Sanity check + if (adl.size() < 60) { + warning("ADLPlayer::readHeader(): File too small (%d)", adl.size()); + return false; + } + + _soundMode = adl.readByte(); + timbreCount = adl.readByte() + 1; + + adl.skip(1); + + return true; +} + +bool ADLPlayer::readTimbres(Common::SeekableReadStream &adl, int timbreCount) { + _timbres.resize(timbreCount); + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) { + for (int i = 0; i < (kOperatorsPerVoice * kParamCount); i++) + t->startParams[i] = adl.readUint16LE(); + } + + if (adl.err()) { + warning("ADLPlayer::readTimbres(): Read failed"); + return false; + } + + return true; +} + +bool ADLPlayer::readSongData(Common::SeekableReadStream &adl) { + _songDataSize = adl.size() - adl.pos(); + _songData = new byte[_songDataSize]; + + if (adl.read(_songData, _songDataSize) != _songDataSize) { + warning("ADLPlayer::readSongData(): Read failed"); + return false; + } + + return true; +} + +bool ADLPlayer::load(const byte *data, uint32 dataSize, int index) { + unload(); + + Common::MemoryReadStream stream(data, dataSize); + if (!load(stream)) + return false; + + _index = index; + return true; +} + +void ADLPlayer::setInstrument(int voice, int instrument) { + if ((voice >= kMaxVoiceCount) || ((uint)instrument >= _timbres.size())) + return; + + _currentInstruments[voice] = instrument; + + setVoiceTimbre(voice, _timbres[instrument].params); +} + +int ADLPlayer::getIndex() const { + return _index; +} + +} // End of namespace Gob diff --git a/engines/gob/sound/adlplayer.h b/engines/gob/sound/adlplayer.h new file mode 100644 index 0000000000..9596447bbc --- /dev/null +++ b/engines/gob/sound/adlplayer.h @@ -0,0 +1,85 @@ +/* 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 GOB_SOUND_ADLPLAYER_H +#define GOB_SOUND_ADLPLAYER_H + +#include "common/array.h" + +#include "gob/sound/adlib.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Gob { + +/** A player for Coktel Vision's ADL music format. */ +class ADLPlayer : public AdLib { +public: + ADLPlayer(Audio::Mixer &mixer); + ~ADLPlayer(); + + bool load(Common::SeekableReadStream &adl); + bool load(const byte *data, uint32 dataSize, int index = -1); + void unload(); + + int getIndex() const; + +protected: + // AdLib interface + uint32 pollMusic(bool first); + void rewind(); + +private: + struct Timbre { + uint16 startParams[kOperatorsPerVoice * kParamCount]; + uint16 params[kOperatorsPerVoice * kParamCount]; + }; + + uint8 _soundMode; + + Common::Array _timbres; + + byte *_songData; + uint32 _songDataSize; + + const byte *_playPos; + + int _index; + + uint8 _modifyInstrument; + uint16 _currentInstruments[kMaxVoiceCount]; + + + void setInstrument(int voice, int instrument); + + bool readHeader (Common::SeekableReadStream &adl, int &timbreCount); + bool readTimbres (Common::SeekableReadStream &adl, int timbreCount); + bool readSongData(Common::SeekableReadStream &adl); + + uint32 getSampleDelay(uint16 delay) const; +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_ADLPLAYER_H diff --git a/engines/gob/sound/musplayer.cpp b/engines/gob/sound/musplayer.cpp new file mode 100644 index 0000000000..3e41dc6ed1 --- /dev/null +++ b/engines/gob/sound/musplayer.cpp @@ -0,0 +1,391 @@ +/* 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 "common/stream.h" +#include "common/textconsole.h" + +#include "gob/sound/musplayer.h" + +namespace Gob { + +MUSPlayer::MUSPlayer(Audio::Mixer &mixer) : AdLib(mixer), + _songData(0), _songDataSize(0), _playPos(0), _songID(0) { + +} + +MUSPlayer::~MUSPlayer() { + unload(); +} + +void MUSPlayer::unload() { + stopPlay(); + + unloadSND(); + unloadMUS(); +} + +uint32 MUSPlayer::getSampleDelay(uint16 delay) const { + if (delay == 0) + return 0; + + uint32 freq = (_ticksPerBeat * _tempo) / 60; + + return ((uint32)delay * getSamplesPerSecond()) / freq; +} + +void MUSPlayer::skipToTiming() { + while (*_playPos < 0x80) + _playPos++; + + if (*_playPos != 0xF8) + _playPos--; +} + +uint32 MUSPlayer::pollMusic(bool first) { + if (_timbres.empty() || !_songData || !_playPos || (_playPos >= (_songData + _songDataSize))) { + end(); + return 0; + } + + if (first) + return getSampleDelay(*_playPos++); + + uint16 delay = 0; + while (delay == 0) { + byte cmd = *_playPos; + + // Delay overflow + if (cmd == 0xF8) { + _playPos++; + delay = 0xF8; + break; + } + + // Song end marker + if (cmd == 0xFC) { + end(); + return 0; + } + + // Global command + if (cmd == 0xF0) { + _playPos++; + + byte type1 = *_playPos++; + byte type2 = *_playPos++; + + if ((type1 == 0x7F) && (type2 == 0)) { + // Tempo change, as a fraction of the base tempo + + uint32 num = *_playPos++; + uint32 denom = *_playPos++; + + _tempo = _baseTempo * num + ((_baseTempo * denom) >> 7); + + _playPos++; + } else { + + // Unsupported global command, skip it + _playPos -= 2; + while(*_playPos++ != 0xF7) + ; + } + + delay = *_playPos++; + break; + } + + // Voice command + + if (cmd >= 0x80) { + _playPos++; + + _lastCommand = cmd; + } else + cmd = _lastCommand; + + uint8 voice = cmd & 0x0F; + uint8 note, volume; + uint16 pitch; + + switch (cmd & 0xF0) { + case 0x80: // Note off + _playPos += 2; + noteOff(voice); + break; + + case 0x90: // Note on + note = *_playPos++; + volume = *_playPos++; + + if (volume) { + setVoiceVolume(voice, volume); + noteOn(voice, note); + } else + noteOff(voice); + break; + + case 0xA0: // Set volume + setVoiceVolume(voice, *_playPos++); + break; + + case 0xB0: + _playPos += 2; + break; + + case 0xC0: // Set instrument + setInstrument(voice, *_playPos++); + break; + + case 0xD0: + _playPos++; + break; + + case 0xE0: // Pitch bend + pitch = *_playPos++; + pitch += *_playPos++ << 7; + bendVoicePitch(voice, pitch); + break; + + default: + warning("MUSPlayer: Unsupported command: 0x%02X", cmd); + skipToTiming(); + break; + } + + delay = *_playPos++; + } + + if (delay == 0xF8) { + delay = 240; + + if (*_playPos != 0xF8) + delay += *_playPos++; + } + + return getSampleDelay(delay); +} + +void MUSPlayer::rewind() { + _playPos = _songData; + _tempo = _baseTempo; + + _lastCommand = 0; + + setPercussionMode(_soundMode != 0); + setPitchRange(_pitchBendRange); +} + +bool MUSPlayer::loadSND(Common::SeekableReadStream &snd) { + unloadSND(); + + int timbreCount, timbrePos; + if (!readSNDHeader(snd, timbreCount, timbrePos)) + return false; + + if (!readSNDTimbres(snd, timbreCount, timbrePos) || snd.err()) { + unloadSND(); + return false; + } + + return true; +} + +bool MUSPlayer::readString(Common::SeekableReadStream &stream, Common::String &string, byte *buffer, uint size) { + if (stream.read(buffer, size) != size) + return false; + + buffer[size] = '\0'; + + string = (char *) buffer; + + return true; +} + +bool MUSPlayer::readSNDHeader(Common::SeekableReadStream &snd, int &timbreCount, int &timbrePos) { + // Sanity check + if (snd.size() <= 6) { + warning("MUSPlayer::readSNDHeader(): File too small (%d)", snd.size()); + return false; + } + + // Version + const uint8 versionMajor = snd.readByte(); + const uint8 versionMinor = snd.readByte(); + + if ((versionMajor != 1) && (versionMinor != 0)) { + warning("MUSPlayer::readSNDHeader(): Unsupported version %d.%d", versionMajor, versionMinor); + return false; + } + + // Number of timbres and where they start + timbreCount = snd.readUint16LE(); + timbrePos = snd.readUint16LE(); + + const uint16 minTimbrePos = 6 + timbreCount * 9; + + // Sanity check + if (timbrePos < minTimbrePos) { + warning("MUSPlayer::readSNDHeader(): Timbre offset too small: %d < %d", timbrePos, minTimbrePos); + return false; + } + + const uint32 timbreParametersSize = snd.size() - timbrePos; + const uint32 paramSize = kOperatorsPerVoice * kParamCount * sizeof(uint16); + + // Sanity check + if (timbreParametersSize != (timbreCount * paramSize)) { + warning("MUSPlayer::loadSND(): Timbre parameters size mismatch: %d != %d", + timbreParametersSize, timbreCount * paramSize); + return false; + } + + return true; +} + +bool MUSPlayer::readSNDTimbres(Common::SeekableReadStream &snd, int timbreCount, int timbrePos) { + _timbres.resize(timbreCount); + + // Read names + byte nameBuffer[10]; + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) { + if (!readString(snd, t->name, nameBuffer, 9)) { + warning("MUSPlayer::readMUSTimbres(): Failed to read timbre name"); + return false; + } + } + + if (!snd.seek(timbrePos)) { + warning("MUSPlayer::readMUSTimbres(): Failed to seek to timbres"); + return false; + } + + // Read parameters + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) { + for (int i = 0; i < (kOperatorsPerVoice * kParamCount); i++) + t->params[i] = snd.readUint16LE(); + } + + return true; +} + +bool MUSPlayer::loadMUS(Common::SeekableReadStream &mus) { + unloadMUS(); + + if (!readMUSHeader(mus) || !readMUSSong(mus) || mus.err()) { + unloadMUS(); + return false; + } + + rewind(); + + return true; +} + +bool MUSPlayer::readMUSHeader(Common::SeekableReadStream &mus) { + // Sanity check + if (mus.size() <= 6) + return false; + + // Version + const uint8 versionMajor = mus.readByte(); + const uint8 versionMinor = mus.readByte(); + + if ((versionMajor != 1) && (versionMinor != 0)) { + warning("MUSPlayer::readMUSHeader(): Unsupported version %d.%d", versionMajor, versionMinor); + return false; + } + + _songID = mus.readUint32LE(); + + byte nameBuffer[31]; + if (!readString(mus, _songName, nameBuffer, 30)) { + warning("MUSPlayer::readMUSHeader(): Failed to read the song name"); + return false; + } + + _ticksPerBeat = mus.readByte(); + _beatsPerMeasure = mus.readByte(); + + mus.skip(4); // Length of song in ticks + + _songDataSize = mus.readUint32LE(); + + mus.skip(4); // Number of commands + mus.skip(8); // Unused + + _soundMode = mus.readByte(); + _pitchBendRange = mus.readByte(); + _baseTempo = mus.readUint16LE(); + + mus.skip(8); // Unused + + return true; +} + +bool MUSPlayer::readMUSSong(Common::SeekableReadStream &mus) { + const uint32 realSongDataSize = mus.size() - mus.pos(); + + if (realSongDataSize < _songDataSize) { + warning("MUSPlayer::readMUSSong(): File too small for the song data: %d < %d", realSongDataSize, _songDataSize); + return false; + } + + _songData = new byte[_songDataSize]; + + if (mus.read(_songData, _songDataSize) != _songDataSize) { + warning("MUSPlayer::readMUSSong(): Read failed"); + return false; + } + + return true; +} + +void MUSPlayer::unloadSND() { + _timbres.clear(); +} + +void MUSPlayer::unloadMUS() { + delete[] _songData; + + _songData = 0; + _songDataSize = 0; + + _playPos = 0; +} + +uint32 MUSPlayer::getSongID() const { + return _songID; +} + +const Common::String &MUSPlayer::getSongName() const { + return _songName; +} + +void MUSPlayer::setInstrument(uint8 voice, uint8 instrument) { + if (instrument >= _timbres.size()) + return; + + setVoiceTimbre(voice, _timbres[instrument].params); +} + +} // End of namespace Gob diff --git a/engines/gob/sound/musplayer.h b/engines/gob/sound/musplayer.h new file mode 100644 index 0000000000..6cc2a2d2ca --- /dev/null +++ b/engines/gob/sound/musplayer.h @@ -0,0 +1,109 @@ +/* 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 GOB_SOUND_MUSPLAYER_H +#define GOB_SOUND_MUSPLAYER_H + +#include "common/str.h" +#include "common/array.h" + +#include "gob/sound/adlib.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Gob { + +/** A player for the AdLib MUS format, with the instrument information in SND files. + * + * In the Gob engine, those files are usually named .MDY and .TBR instead. + */ +class MUSPlayer : public AdLib { +public: + MUSPlayer(Audio::Mixer &mixer); + ~MUSPlayer(); + + /** Load the instruments (.SND or .TBR) */ + bool loadSND(Common::SeekableReadStream &snd); + /** Load the melody (.MUS or .MDY) */ + bool loadMUS(Common::SeekableReadStream &mus); + + void unload(); + + uint32 getSongID() const; + const Common::String &getSongName() const; + +protected: + // AdLib interface + uint32 pollMusic(bool first); + void rewind(); + +private: + struct Timbre { + Common::String name; + + uint16 params[kOperatorsPerVoice * kParamCount]; + }; + + Common::Array _timbres; + + byte *_songData; + uint32 _songDataSize; + + const byte *_playPos; + + uint32 _songID; + Common::String _songName; + + uint8 _ticksPerBeat; + uint8 _beatsPerMeasure; + + uint8 _soundMode; + uint8 _pitchBendRange; + + uint16 _baseTempo; + + uint16 _tempo; + + byte _lastCommand; + + + void unloadSND(); + void unloadMUS(); + + bool readSNDHeader (Common::SeekableReadStream &snd, int &timbreCount, int &timbrePos); + bool readSNDTimbres(Common::SeekableReadStream &snd, int timbreCount, int timbrePos); + + bool readMUSHeader(Common::SeekableReadStream &mus); + bool readMUSSong (Common::SeekableReadStream &mus); + + uint32 getSampleDelay(uint16 delay) const; + void setInstrument(uint8 voice, uint8 instrument); + void skipToTiming(); + + static bool readString(Common::SeekableReadStream &stream, Common::String &string, byte *buffer, uint size); +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_MUSPLAYER_H diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index bfe0394390..f14e9b150a 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -30,7 +30,8 @@ #include "gob/sound/pcspeaker.h" #include "gob/sound/soundblaster.h" -#include "gob/sound/adlib.h" +#include "gob/sound/adlplayer.h" +#include "gob/sound/musplayer.h" #include "gob/sound/infogrames.h" #include "gob/sound/protracker.h" #include "gob/sound/cdrom.h" @@ -131,10 +132,7 @@ void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdLib, int index) { if (noteAdLib) { if (_adlPlayer) if ((index == -1) || (_adlPlayer->getIndex() == index)) - _adlPlayer->stopPlay(); - if (_mdyPlayer) - if ((index == -1) || (_mdyPlayer->getIndex() == index)) - _mdyPlayer->stopPlay(); + _adlPlayer->unload(); } } else { @@ -235,7 +233,17 @@ bool Sound::adlibLoadADL(const char *fileName) { debugC(1, kDebugSound, "AdLib: Loading ADL data (\"%s\")", fileName); - return _adlPlayer->load(fileName); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); + if (!stream) { + warning("Can't open ADL file \"%s\"", fileName); + return false; + } + + bool loaded = _adlPlayer->load(*stream); + + delete stream; + + return loaded; } bool Sound::adlibLoadADL(byte *data, uint32 size, int index) { @@ -267,7 +275,7 @@ bool Sound::adlibLoadMDY(const char *fileName) { return false; if (!_mdyPlayer) - _mdyPlayer = new MDYPlayer(*_vm->_mixer); + _mdyPlayer = new MUSPlayer(*_vm->_mixer); debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName); @@ -277,7 +285,7 @@ bool Sound::adlibLoadMDY(const char *fileName) { return false; } - bool loaded = _mdyPlayer->loadMDY(*stream); + bool loaded = _mdyPlayer->loadMUS(*stream); delete stream; @@ -289,7 +297,7 @@ bool Sound::adlibLoadTBR(const char *fileName) { return false; if (!_mdyPlayer) - _mdyPlayer = new MDYPlayer(*_vm->_mixer); + _mdyPlayer = new MUSPlayer(*_vm->_mixer); Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); if (!stream) { @@ -299,7 +307,7 @@ bool Sound::adlibLoadTBR(const char *fileName) { debugC(1, kDebugSound, "AdLib: Loading MDY instruments (\"%s\")", fileName); - bool loaded = _mdyPlayer->loadTBR(*stream); + bool loaded = _mdyPlayer->loadSND(*stream); delete stream; @@ -316,11 +324,8 @@ void Sound::adlibPlayTrack(const char *trackname) { if (_adlPlayer->isPlaying()) return; - debugC(1, kDebugSound, "AdLib: Playing ADL track \"%s\"", trackname); - - _adlPlayer->unload(); - _adlPlayer->load(trackname); - _adlPlayer->startPlay(); + if (adlibLoadADL(trackname)) + adlibPlay(); } void Sound::adlibPlayBgMusic() { @@ -331,7 +336,7 @@ void Sound::adlibPlayBgMusic() { _adlPlayer = new ADLPlayer(*_vm->_mixer); static const char *const tracksMac[] = { -// "musmac1.adl", // TODO: This track isn't played correctly at all yet +// "musmac1.adl", // This track seems to be missing instruments... "musmac2.adl", "musmac3.adl", "musmac4.adl", @@ -398,13 +403,11 @@ int Sound::adlibGetIndex() const { if (_adlPlayer) return _adlPlayer->getIndex(); - if (_mdyPlayer) - return _mdyPlayer->getIndex(); return -1; } -bool Sound::adlibGetRepeating() const { +int32 Sound::adlibGetRepeating() const { if (!_hasAdLib) return false; diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index 585cf36703..ea7d639ffe 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -32,7 +32,7 @@ class GobEngine; class PCSpeaker; class SoundBlaster; class ADLPlayer; -class MDYPlayer; +class MUSPlayer; class Infogrames; class Protracker; class CDROM; @@ -92,7 +92,7 @@ public: bool adlibIsPlaying() const; int adlibGetIndex() const; - bool adlibGetRepeating() const; + int32 adlibGetRepeating() const; void adlibSetRepeating(int32 repCount); @@ -145,14 +145,23 @@ private: SoundDesc _sounds[kSoundsCount]; + // Speaker PCSpeaker *_pcspeaker; + + // PCM based SoundBlaster *_blaster; + BackgroundAtmosphere *_bgatmos; + + // AdLib + MUSPlayer *_mdyPlayer; ADLPlayer *_adlPlayer; - MDYPlayer *_mdyPlayer; + + // Amiga Paula Infogrames *_infogrames; Protracker *_protracker; + + // Audio CD CDROM *_cdrom; - BackgroundAtmosphere *_bgatmos; }; } // End of namespace Gob -- cgit v1.2.3 From 8548dea13d56e1d69b2f4743361932cf14dd6eee Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 05:09:58 +0200 Subject: GOB: Hook up the MDY player in Fascination --- engines/gob/init_fascin.cpp | 6 +++--- engines/gob/inter_fascin.cpp | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/engines/gob/init_fascin.cpp b/engines/gob/init_fascin.cpp index b87d816406..e6d82faa68 100644 --- a/engines/gob/init_fascin.cpp +++ b/engines/gob/init_fascin.cpp @@ -44,10 +44,10 @@ void Init_Fascination::updateConfig() { } void Init_Fascination::initGame() { -// HACK - Suppress ADLIB_FLAG as the MDY/TBR player is not working. suppress -// the PC Speaker too, as the script checks in the intro for it's presence +// HACK - Suppress +// the PC Speaker, as the script checks in the intro for it's presence // to play or not some noices. - _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG; + _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG | ADLIB_FLAG; Init::initGame(); } diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp index 081b48fbad..001ec06635 100644 --- a/engines/gob/inter_fascin.cpp +++ b/engines/gob/inter_fascin.cpp @@ -248,12 +248,11 @@ void Inter_Fascination::oFascin_playTira(OpGobParams ¶ms) { void Inter_Fascination::oFascin_loadExtasy(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("extasy.tbr"); _vm->_sound->adlibLoadMDY("extasy.mdy"); + _vm->_sound->adlibSetRepeating(-1); } void Inter_Fascination::oFascin_adlibPlay(OpGobParams ¶ms) { -#ifdef ENABLE_FASCIN_ADLIB _vm->_sound->adlibPlay(); -#endif } void Inter_Fascination::oFascin_adlibStop(OpGobParams ¶ms) { -- cgit v1.2.3 From a64e8a6d30fbef1de52684b75bb6f4536b28d988 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 05:10:24 +0200 Subject: GOB: Hook up the MDY player in Geisha --- engines/gob/init.h | 1 - engines/gob/init_geisha.cpp | 7 ------- engines/gob/inter_geisha.cpp | 5 ++--- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/engines/gob/init.h b/engines/gob/init.h index 946a3fa4f1..ac460fd654 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -62,7 +62,6 @@ public: ~Init_Geisha(); void initVideo(); - void initGame(); }; class Init_v2 : public Init_v1 { diff --git a/engines/gob/init_geisha.cpp b/engines/gob/init_geisha.cpp index b5bbcff400..01081a5af6 100644 --- a/engines/gob/init_geisha.cpp +++ b/engines/gob/init_geisha.cpp @@ -44,11 +44,4 @@ void Init_Geisha::initVideo() { _vm->_draw->_transparentCursor = 1; } -void Init_Geisha::initGame() { - // HACK - Since the MDY/TBR player is not working, claim we have no AdLib - _vm->_global->_soundFlags = 0; - - Init::initGame(); -} - } // End of namespace Gob diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 75204a3f55..8a4d4246b6 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -298,9 +298,8 @@ void Inter_Geisha::oGeisha_loadTitleMusic(OpGobParams ¶ms) { } void Inter_Geisha::oGeisha_playMusic(OpGobParams ¶ms) { - // TODO: The MDYPlayer is still broken! - warning("Geisha Stub: oGeisha_playMusic"); - // _vm->_sound->adlibPlay(); + _vm->_sound->adlibSetRepeating(-1); + _vm->_sound->adlibPlay(); } void Inter_Geisha::oGeisha_stopMusic(OpGobParams ¶ms) { -- cgit v1.2.3 From 385bd7c6a045b1a4c7b64ebef4471805020bdadd Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 05:24:30 +0200 Subject: NEWS: Mention Gob news for 1.5.0 --- NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 7ce4f255dd..acff8b8473 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,11 @@ For a more comprehensive changelog of the latest experimental code, see: Cine: - Implemented Roland MT-32 output driver. + Gob: + - Fixed a crash in Lost in Time + - Rewrote the AdLib player. Enabled the now working MDY player in + Fascination and Geisha. + SCUMM: - Added support for the Macintosh version of SPY Fox in Hold the Mustard. - Added a difficulty selection dialog for Loom FM-TOWNS. -- cgit v1.2.3 From fe44939eba096bad083254b1c5152ef070ac4dc8 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 06:11:53 +0200 Subject: GOB: Play the music on the title screen of Gob1 EGA The EGA version of Gobliiins comes with an MDY track. While the original doesn't play it, we thought it might be a nice idea to play it nevertheless. --- engines/gob/detection_tables.h | 4 ++-- engines/gob/inter_v1.cpp | 34 +++++++++++++++++++++++++-- engines/gob/sound/adlib.h | 6 ++--- engines/gob/sound/sound.cpp | 53 ++++++++++++++++++++++++++++++------------ engines/gob/sound/sound.h | 4 ++++ 5 files changed, 79 insertions(+), 22 deletions(-) diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index 7aa58b9b97..77b54a19cd 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -34,7 +34,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, kGameTypeGob1, - kFeaturesEGA, + kFeaturesEGA | kFeaturesAdLib, 0, 0, 0 }, { @@ -48,7 +48,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, kGameTypeGob1, - kFeaturesEGA, + kFeaturesEGA | kFeaturesAdLib, 0, 0, 0 }, { // Supplied by Theruler76 in bug report #1201233 diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 4aa54f720b..6fc472a0ac 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -286,10 +286,40 @@ void Inter_v1::o1_loadMult() { } void Inter_v1::o1_playMult() { - int16 checkEscape; + // NOTE: The EGA version of Gobliiins has an MDY tune. + // While the original doesn't play it, we do. + bool isGob1EGAIntro = _vm->getGameType() == kGameTypeGob1 && + _vm->isEGA() && + _vm->_game->_script->pos() == 1010 && + _vm->isCurrentTot("intro.tot") && + VAR(57) != 0xFFFFFFFF && + _vm->_dataIO->hasFile("goblins.mdy") && + _vm->_dataIO->hasFile("goblins.tbr"); + + int16 checkEscape = _vm->_game->_script->readInt16(); + + if (isGob1EGAIntro) { + _vm->_sound->adlibLoadTBR("goblins.tbr"); + _vm->_sound->adlibLoadMDY("goblins.mdy"); + _vm->_sound->adlibSetRepeating(-1); + + _vm->_sound->adlibPlay(); + } - checkEscape = _vm->_game->_script->readInt16(); _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); + + if (isGob1EGAIntro) { + + // User didn't escape the intro mult, wait for an escape here + if (VAR(57) != 0xFFFFFFFF) { + while (_vm->_util->getKey() != kKeyEscape) { + _vm->_util->processInput(); + _vm->_util->longDelay(1); + } + } + + _vm->_sound->adlibUnload(); + } } void Inter_v1::o1_freeMultKeys() { diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index df1b77fd4d..17ab950752 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -20,8 +20,8 @@ * */ -#ifndef GOB_SOUND_NEWADLIB_H -#define GOB_SOUND_NEWADLIB_H +#ifndef GOB_SOUND_ADLIB_H +#define GOB_SOUND_ADLIB_H #include "common/mutex.h" @@ -303,4 +303,4 @@ private: } // End of namespace Gob -#endif // GOB_SOUND_NEWADLIB_H +#endif // GOB_SOUND_ADLIB_H diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index f14e9b150a..9f72d1a98f 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -51,6 +51,8 @@ Sound::Sound(GobEngine *vm) : _vm(vm) { _hasAdLib = (!_vm->_noMusic && _vm->hasAdLib()); + _hasAdLibBg = _hasAdLib; + if (!_vm->_noMusic && (_vm->getPlatform() == Common::kPlatformAmiga)) { _infogrames = new Infogrames(*_vm->_mixer); _protracker = new Protracker(*_vm->_mixer); @@ -274,8 +276,7 @@ bool Sound::adlibLoadMDY(const char *fileName) { if (!_hasAdLib) return false; - if (!_mdyPlayer) - _mdyPlayer = new MUSPlayer(*_vm->_mixer); + createMDYPlayer(); debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName); @@ -296,8 +297,7 @@ bool Sound::adlibLoadTBR(const char *fileName) { if (!_hasAdLib) return false; - if (!_mdyPlayer) - _mdyPlayer = new MUSPlayer(*_vm->_mixer); + createMDYPlayer(); Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); if (!stream) { @@ -318,8 +318,7 @@ void Sound::adlibPlayTrack(const char *trackname) { if (!_hasAdLib) return; - if (!_adlPlayer) - _adlPlayer = new ADLPlayer(*_vm->_mixer); + createADLPlayer(); if (_adlPlayer->isPlaying()) return; @@ -329,11 +328,10 @@ void Sound::adlibPlayTrack(const char *trackname) { } void Sound::adlibPlayBgMusic() { - if (!_hasAdLib) + if (!_hasAdLib || _hasAdLibBg) return; - if (!_adlPlayer) - _adlPlayer = new ADLPlayer(*_vm->_mixer); + createADLPlayer(); static const char *const tracksMac[] = { // "musmac1.adl", // This track seems to be missing instruments... @@ -352,13 +350,18 @@ void Sound::adlibPlayBgMusic() { "musmac5.mid" }; - if (_vm->getPlatform() == Common::kPlatformWindows) { - int track = _vm->_util->getRandom(ARRAYSIZE(tracksWin)); - adlibPlayTrack(tracksWin[track]); - } else { - int track = _vm->_util->getRandom(ARRAYSIZE(tracksMac)); - adlibPlayTrack(tracksMac[track]); + const char *track = 0; + if (_vm->getPlatform() == Common::kPlatformWindows) + track = tracksWin[ARRAYSIZE(tracksWin)]; + else + track = tracksMac[_vm->_util->getRandom(ARRAYSIZE(tracksMac))]; + + if (!track || !_vm->_dataIO->hasFile(track)) { + _hasAdLibBg = false; + return; } + + adlibPlayTrack(track); } void Sound::adlibPlay() { @@ -722,4 +725,24 @@ void Sound::bgUnshade() { _bgatmos->unshade(); } +void Sound::createMDYPlayer() { + if (_mdyPlayer) + return; + + delete _adlPlayer; + _adlPlayer = 0; + + _mdyPlayer = new MUSPlayer(*_vm->_mixer); +} + +void Sound::createADLPlayer() { + if (_adlPlayer) + return; + + delete _mdyPlayer; + _mdyPlayer= 0; + + _adlPlayer = new ADLPlayer(*_vm->_mixer); +} + } // End of namespace Gob diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index ea7d639ffe..064a249253 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -142,6 +142,7 @@ private: GobEngine *_vm; bool _hasAdLib; + bool _hasAdLibBg; SoundDesc _sounds[kSoundsCount]; @@ -162,6 +163,9 @@ private: // Audio CD CDROM *_cdrom; + + void createMDYPlayer(); + void createADLPlayer(); }; } // End of namespace Gob -- cgit v1.2.3 From 0ccfd614aa935ed38a4fce7888c91ff1429691f1 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 11 Jun 2012 11:48:49 +0300 Subject: SCI: Add more verbose debug output for DoAudio in SCI2.1 --- engines/sci/engine/ksound.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index c469f775f9..b378b4d58b 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -140,8 +140,12 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) { ((argv[3].toUint16() & 0xff) << 16) | ((argv[4].toUint16() & 0xff) << 8) | (argv[5].toUint16() & 0xff); - if (argc == 8) - warning("kDoAudio: Play called with SQ6 extra parameters"); + if (argc == 8) { + // argv[6] is always 1 + // argv[7] is the contents of global 229 (0xE5) + warning("kDoAudio: Play called with SCI2.1 extra parameters: %04x:%04x and %04x:%04x", + PRINT_REG(argv[6]), PRINT_REG(argv[7])); + } } else { warning("kDoAudio: Play called with an unknown number of parameters (%d)", argc); return NULL_REG; -- cgit v1.2.3 From b812ed50c8f6d9a24b607831a88a398730458d9a Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 11 Jun 2012 11:51:54 +0300 Subject: SCI: Bugfix for negative numbers in kString(at) Fixes one of the bugs in the savegame selection screen in Phantasmagoria --- engines/sci/engine/kstring.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index fe8d631497..0877e37a65 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -653,10 +653,18 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { case 1: // Size return make_reg(0, s->_segMan->getString(argv[1]).size()); case 2: { // At (return value at an index) - if (argv[1].segment == s->_segMan->getStringSegmentId()) - return make_reg(0, s->_segMan->lookupString(argv[1])->getRawData()[argv[2].toUint16()]); - - return make_reg(0, s->_segMan->getString(argv[1])[argv[2].toUint16()]); + // Note that values need to be truncated to bytes, otherwise + // 0xff (negative char -1) will incorrectly be changed to + // 0xffff (negative int16 -1) + if (argv[1].segment == s->_segMan->getStringSegmentId()) { + SciString *string = s->_segMan->lookupString(argv[1]); + byte val = string->getRawData()[argv[2].toUint16()]; + return make_reg(0, val); + } else { + Common::String string = s->_segMan->getString(argv[1]); + byte val = string[argv[2].toUint16()]; + return make_reg(0, val); + } } case 3: { // Atput (put value at an index) SciString *string = s->_segMan->lookupString(argv[1]); -- cgit v1.2.3 From f538b7658684aad26a38b2e3685a322ecc14a720 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 14:59:12 +0200 Subject: GOB: Don't recalculate the AdLib frequencies table on every player reset --- engines/gob/sound/adlib.cpp | 8 +++++++- engines/gob/sound/adlib.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index 3f46f6cf4b..d9fc362547 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -98,6 +98,8 @@ AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0), _rate = _mixer->getOutputRate(); + initFreqs(); + createOPL(); initOPL(); @@ -295,7 +297,7 @@ void AdLib::initOPL() { _opl->reset(); initOperatorVolumes(); - initFreqs(); + resetFreqs(); setPercussionMode(false); @@ -581,6 +583,10 @@ void AdLib::initFreqs() { for (int i = 0; i < kPitchStepCount; i++) setFreqs(_freqs[i], i * numStep, 100); + resetFreqs(); +} + +void AdLib::resetFreqs() { for (int i = 0; i < kMaxVoiceCount; i++) { _freqPtr [i] = _freqs[0]; _halfToneOffset[i] = 0; diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 17ab950752..bd1778d2ed 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -295,6 +295,7 @@ private: void initFreqs(); void setFreqs(uint16 *freqs, int32 num, int32 denom); int32 calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom); + void resetFreqs(); void changePitch(uint8 voice, uint16 pitchBend); -- cgit v1.2.3 From c3f89b78c9462b406821a7b80ebf99d8a5245132 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 15:04:46 +0200 Subject: README: Update Gob game list --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index 81b28830c2..1024c6764b 100644 --- a/README +++ b/README @@ -235,13 +235,17 @@ AGOS Games by Adventuresoft/Horrorsoft: The Feeble Files [feeble] GOB Games by Coktel Vision: + Bambou le sauveur de la jungle [bambou] Bargon Attack [bargon] + Fascination [fascination] + Geisha [geisha] Gobliiins [gob1] Gobliins 2 [gob2] Goblins 3 [gob3] Lost in Time [lostintime] The Bizarre Adventures of Woodruff and the Schnibble [woodruff] + Urban Runner [urban] Ween: The Prophecy [ween] MADE Games by Activision: -- cgit v1.2.3 From a3db17033f9b251760e76d4ba7c7e66003cc228d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 15:07:01 +0200 Subject: GOB: Update list of games in the comment --- engines/gob/gob.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/gob/gob.h b/engines/gob/gob.h index ea2323807a..6277585015 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -50,6 +50,10 @@ class StaticTextWidget; * - Bargon Attack * - Lost in Time * - The Bizarre Adventures of Woodruff and the Schnibble + * - Fascination + * - Urban Runner + * - Bambou le sauveur de la jungle + * - Geisha */ namespace Gob { -- cgit v1.2.3 From f87e8b53f333c6799302d620a2c36668b92c77f0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 15:09:48 +0200 Subject: GOB: Fix an AmigaOS compile error Should close bug #3534287. --- engines/gob/minigames/geisha/meter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp index 719ecf3d18..7ec3119866 100644 --- a/engines/gob/minigames/geisha/meter.cpp +++ b/engines/gob/minigames/geisha/meter.cpp @@ -67,7 +67,7 @@ int32 Meter::increase(int32 n) { if (n < 0) return decrease(-n); - int32 overflow = MAX(0, (_value + n) - _maxValue); + int32 overflow = MAX(0, (_value + n) - _maxValue); int32 value = CLIP(_value + n, 0, _maxValue); if (_value == value) @@ -83,7 +83,7 @@ int32 Meter::decrease(int32 n) { if (n < 0) return increase(-n); - int32 underflow = -MIN(0, _value - n); + int32 underflow = -MIN(0, _value - n); int32 value = CLIP(_value - n, 0, _maxValue); if (_value == value) -- cgit v1.2.3 From 734a361f2e49c15b4ac1029c39b478ff2843c924 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 11 Jun 2012 10:16:07 -0400 Subject: SCUMM: Fix basketball ini name --- engines/scumm/he/script_v60he.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp index dbeee567bf..5e359385b6 100644 --- a/engines/scumm/he/script_v60he.cpp +++ b/engines/scumm/he/script_v60he.cpp @@ -124,8 +124,6 @@ int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) { } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path // The default game data path is set to './' by ScummVM r = 2; - } else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI - r = 13; } else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (Windows HE72 - HE100) // The default save game path is set to '*/' by ScummVM r = 2; -- cgit v1.2.3 From 52b14de72a113a4f88b9da6b4f6b1965466bac8a Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 11 Jun 2012 18:34:36 +0200 Subject: KYRA: Mark Kyra 1 russian floppy version as fan translation. --- engines/kyra/detection_tables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h index 884fca659b..79ef11e7a9 100644 --- a/engines/kyra/detection_tables.h +++ b/engines/kyra/detection_tables.h @@ -159,7 +159,7 @@ const KYRAGameDescription adGameDescs[] = { }, KYRA1_FLOPPY_FLAGS }, - { + { // russian fan translation { "kyra1", "Extracted", -- cgit v1.2.3 From 3fde390e006963f354c0678640c70f49753907ef Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 11 Jun 2012 20:21:47 +0300 Subject: SCI: Added another French version of Torin's Passage Thanks to LePhilousophe for providing the file details. Also fixed all of the detection entries for Torin's Passage --- engines/sci/detection_tables.h | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index 506f79b4d8..6e66c48ff1 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -3744,53 +3744,61 @@ static const struct ADGameDescription SciGameDescriptions[] = { #ifdef ENABLE_SCI32 // Torin's Passage - English Windows Interactive Demo - // SCI interpreter version 2.100.002 (just a guess) + // SCI interpreter version 2.100.002 {"torin", "Demo", { {"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403}, {"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // Torin's Passage - English Windows - // SCI interpreter version 2.100.002 (just a guess) + // Torin's Passage (Multilingual) - English Windows CD + // SCI interpreter version 2.100.002 {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // Torin's Passage - Spanish Windows (from jvprat) + // Torin's Passage (Multilingual) - Spanish Windows CD (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.0" {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, // TODO: depend on one of the patches? AD_LISTEND}, - Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + Common::ES_ESP, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // Torin's Passage - French Windows - // SCI interpreter version 2.100.002 (just a guess) + // Torin's Passage (Multilingual) - French Windows CD + // SCI interpreter version 2.100.002 {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // Torin's Passage - German Windows - // SCI interpreter version 2.100.002 (just a guess) + // Torin's Passage (Multilingual) - German Windows CD + // SCI interpreter version 2.100.002 {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, - Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // Torin's Passage - Italian Windows CD (from glorifindel) - // SCI interpreter version 2.100.002 (just a guess) + // Torin's Passage (Multilingual) - Italian Windows CD (from glorifindel) + // SCI interpreter version 2.100.002 {"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, AD_LISTEND}, Common::IT_ITA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + + // Torin's Passage - French Windows (from LePhilousophe) + // SCI interpreter version 2.100.002 + {"torin", "", { + {"resmap.000", 0, "66ed46e3e56f487e688d52f05b33d0ba", 9787}, + {"ressci.000", 0, "118f9bec04bfe17c4f87bbb5ddb43c18", 56126981}, + AD_LISTEND}, + Common::FR_FRA, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, #endif // ENABLE_SCI32 // SCI Fanmade Games -- cgit v1.2.3 From 15306bc554b926e7d50f6a443766065e684557f3 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 11 Jun 2012 20:28:28 +0300 Subject: SCI: Return the default value for unknown configuration settings Based on a patch by LePhilousophe --- engines/sci/engine/kmisc.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index f243cf2ffe..1cbaf0708d 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -396,18 +396,17 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { reg_t kGetSierraProfileInt(EngineState *s, int argc, reg_t *argv) { Common::String category = s->_segMan->getString(argv[0]); // always "config" category.toLowercase(); - if (category != "config") - error("GetSierraProfileInt: category isn't 'config', it's '%s'", category.c_str()); - Common::String setting = s->_segMan->getString(argv[1]); setting.toLowercase(); - if (setting != "videospeed") - error("GetSierraProfileInt: setting isn't 'videospeed', it's '%s'", setting.c_str()); + // The third parameter is the default value returned if the configuration key is missing - // The third parameter is 425 (the default if the configuration key is missing) + if (category == "config" && setting == "videospeed") { + // We return the same fake value for videospeed as with kGetConfig + return make_reg(0, 500); + } - // We return the same fake value for videospeed as with kGetConfig - return make_reg(0, 500); + warning("kGetSierraProfileInt: Returning default value %d for unknown setting %s.%s", argv[2].toSint16(), category.c_str(), setting.c_str()); + return argv[2]; } #endif -- cgit v1.2.3 From ea06210b92a45f8fca6b9be19057bcd607988ee7 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 11 Jun 2012 21:14:08 +0300 Subject: SCI: Add support for variable selectors in kListFirstTrue / kListAllTrue This is used by Torin's Passage (e.g. when trying to open the menu). Based on a slightly modified patch by LePhilousophe --- engines/sci/engine/klists.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 2a33df26bc..5a608af034 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -575,8 +575,11 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) { // First, check if the target selector is a variable if (lookupSelector(s->_segMan, curObject, slc, &address, NULL) == kSelectorVariable) { - // Can this happen with variable selectors? - error("kListFirstTrue: Attempted to access a variable selector"); + // If it's a variable selector, check its value. + // Example: script 64893 in Torin, MenuHandler::isHilited checks + // all children for variable selector 0x03ba (bHilited). + if (!readSelector(s->_segMan, curObject, slc).isNull()) + return curObject; } else { invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2); @@ -609,16 +612,16 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) { // First, check if the target selector is a variable if (lookupSelector(s->_segMan, curObject, slc, &address, NULL) == kSelectorVariable) { - // Can this happen with variable selectors? - error("kListAllTrue: Attempted to access a variable selector"); + // If it's a variable selector, check its value + s->r_acc = readSelector(s->_segMan, curObject, slc); } else { invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2); - - // Check if the result isn't true - if (s->r_acc.isNull()) - break; } + // Check if the result isn't true + if (s->r_acc.isNull()) + break; + curNode = s->_segMan->lookupNode(nextNode); } -- cgit v1.2.3 From 9c14f4419b4b9f573d4a955be136108e575266fe Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 11 Jun 2012 20:34:42 +0200 Subject: AUDIO: Make VOC decoder a bit more failsafe by still playing parts of invalid VOC files. Formerly when an unsupported block was found the opening would fail. Instead now all the valid blocks till that occasion will be played. This fixes an missing sound in Full Throttle (thanks to clone2727 for reporting), which is using a VOC file which fails to specify the proper block length for its sound block. --- audio/decoders/voc.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp index f0b5b2777d..fa330c6f2c 100644 --- a/audio/decoders/voc.cpp +++ b/audio/decoders/voc.cpp @@ -321,9 +321,14 @@ void VocStream::preProcess() { // In case we hit a "Terminator" block we also break here. if (_stream->eos() || block.code == 0) break; - // We also allow 128 as terminator, since Simon 1 Amiga CD32 uses it. - if (block.code == 128) { - debug(3, "VocStream::preProcess: Caught 128 as terminator"); + // We will allow invalid block numbers as terminators. This is needed, + // since some games ship broken VOC files. The following occasions are + // known: + // - 128 is used as terminator in Simon 1 Amiga CD32 + // - Full Throttle contains a VOC file with an incorrect block length + // resulting in a sample (127) to be read as block code. + if (block.code > 9) { + warning("VocStream::preProcess: Caught %d as terminator", block.code); break; } @@ -482,7 +487,8 @@ void VocStream::preProcess() { default: warning("Unhandled code %d in VOC file (len %d)", block.code, block.length); - return; + // Skip the whole block and try to use the next one. + skip = block.length; } // Premature end of stream => error! -- cgit v1.2.3 From ef8239df4877772762876ca1a98ad48676af8d5c Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 11 Jun 2012 20:10:49 -0400 Subject: SCI: Fix comment in kString(at) --- engines/sci/engine/kstring.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 0877e37a65..33b8c15e9f 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -653,9 +653,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) { case 1: // Size return make_reg(0, s->_segMan->getString(argv[1]).size()); case 2: { // At (return value at an index) - // Note that values need to be truncated to bytes, otherwise - // 0xff (negative char -1) will incorrectly be changed to - // 0xffff (negative int16 -1) + // Note that values are put in bytes to avoid sign extension if (argv[1].segment == s->_segMan->getStringSegmentId()) { SciString *string = s->_segMan->lookupString(argv[1]); byte val = string->getRawData()[argv[2].toUint16()]; -- cgit v1.2.3 From 0075fa2f98eb3deb4674a4f1af95a84669098d7c Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 12 Jun 2012 04:13:00 +0200 Subject: GRAPHICS: Replace OverlayColor with uint16 in scaler code. Scalers are actually fixed at 2Bpp right now and not at the depth of OverlayColor. --- graphics/scaler.cpp | 9 ++++----- graphics/scaler/aspect.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/graphics/scaler.cpp b/graphics/scaler.cpp index 9ade0e6c57..b81e8937a8 100644 --- a/graphics/scaler.cpp +++ b/graphics/scaler.cpp @@ -167,12 +167,12 @@ void DestroyScalers(){ void Normal1x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { // Spot the case when it can all be done in 1 hit - if ((srcPitch == sizeof(OverlayColor) * (uint)width) && (dstPitch == sizeof(OverlayColor) * (uint)width)) { - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width * height); + if ((srcPitch == sizeof(uint16) * (uint)width) && (dstPitch == sizeof(uint16) * (uint)width)) { + memcpy(dstPtr, srcPtr, sizeof(uint16) * width * height); return; } while (height--) { - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width); + memcpy(dstPtr, srcPtr, sizeof(uint16) * width); srcPtr += srcPitch; dstPtr += dstPitch; } @@ -207,11 +207,10 @@ void Normal2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPit uint8 *r; assert(IS_ALIGNED(dstPtr, 4)); - assert(sizeof(OverlayColor) == 2); while (height--) { r = dstPtr; for (int i = 0; i < width; ++i, r += 4) { - uint32 color = *(((const OverlayColor *)srcPtr) + i); + uint32 color = *(((const uint16 *)srcPtr) + i); color |= color << 16; diff --git a/graphics/scaler/aspect.cpp b/graphics/scaler/aspect.cpp index 7ad37b1ba8..f0ae732a40 100644 --- a/graphics/scaler/aspect.cpp +++ b/graphics/scaler/aspect.cpp @@ -160,14 +160,14 @@ int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, i #if ASPECT_MODE == kSuperFastAndUglyAspectMode if (srcPtr == dstPtr) break; - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width); + memcpy(dstPtr, srcPtr, sizeof(uint16) * width); #else // Bilinear filter switch (y % 6) { case 0: case 5: if (srcPtr != dstPtr) - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width); + memcpy(dstPtr, srcPtr, sizeof(uint16) * width); break; case 1: interpolate5Line((uint16 *)dstPtr, (const uint16 *)(srcPtr - pitch), (const uint16 *)srcPtr, width); @@ -206,13 +206,13 @@ void Normal1xAspectTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, #if ASPECT_MODE == kSuperFastAndUglyAspectMode if ((y % 6) == 5) srcPtr -= srcPitch; - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width); + memcpy(dstPtr, srcPtr, sizeof(uint16) * width); #else // Bilinear filter five input lines onto six output lines switch (y % 6) { case 0: // First output line is copied from first input line - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width); + memcpy(dstPtr, srcPtr, sizeof(uint16) * width); break; case 1: // Second output line is mixed from first and second input line @@ -233,7 +233,7 @@ void Normal1xAspectTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, case 5: // Sixth (and last) output line is copied from fifth (and last) input line srcPtr -= srcPitch; - memcpy(dstPtr, srcPtr, sizeof(OverlayColor) * width); + memcpy(dstPtr, srcPtr, sizeof(uint16) * width); break; } #endif -- cgit v1.2.3 From 13f93494578818b5a1272d793f7412b6810f3321 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 12 Jun 2012 04:16:51 +0200 Subject: GUI: Take advantage of Surface::fillRect in GraphicsWidget::setGfx. --- gui/widget.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gui/widget.cpp b/gui/widget.cpp index fc6510b976..657245c815 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -643,14 +643,7 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { _gfx.free(); _gfx.create(w, h, overlayFormat); - - OverlayColor *dst = (OverlayColor *)_gfx.pixels; - OverlayColor fillCol = overlayFormat.RGBToColor(r, g, b); - while (h--) { - for (int i = 0; i < w; ++i) { - *dst++ = fillCol; - } - } + _gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b)); } void GraphicsWidget::drawWidget() { -- cgit v1.2.3 From 3324aef8d0972d713f4fcfe09b2ada65dca365a8 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 11 Jun 2012 23:06:28 -0400 Subject: MOHAWK: Make sure we convert video surfaces if they're not in the screen format --- engines/mohawk/video.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp index c10b986c60..15103b2021 100644 --- a/engines/mohawk/video.cpp +++ b/engines/mohawk/video.cpp @@ -227,17 +227,19 @@ bool VideoManager::updateMovies() { Graphics::Surface *convertedFrame = 0; if (frame && _videoStreams[i].enabled) { - // Convert from 8bpp to the current screen format if necessary Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat(); - if (frame->format.bytesPerPixel == 1) { - if (pixelFormat.bytesPerPixel == 1) { - if (_videoStreams[i]->hasDirtyPalette()) - _videoStreams[i]->setSystemPalette(); - } else { - convertedFrame = frame->convertTo(pixelFormat, _videoStreams[i]->getPalette()); - frame = convertedFrame; - } + if (frame->format != pixelFormat) { + // We don't support downconverting to 8bpp + if (pixelFormat.bytesPerPixel == 1) + error("Cannot convert high color video frame to 8bpp"); + + // Convert to the current screen format + convertedFrame = frame->convertTo(pixelFormat, _videoStreams[i]->getPalette()); + frame = convertedFrame; + } else if (pixelFormat.bytesPerPixel == 1 && _videoStreams[i]->hasDirtyPalette()) { + // Set the palette when running in 8bpp mode only + _videoStreams[i]->setSystemPalette(); } // Clip the width/height to make sure we stay on the screen (Myst does this a few times) -- cgit v1.2.3 From e16ad39e533608d5bfac9bfba167e7e2dfb606cb Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 11 Jun 2012 23:07:37 -0400 Subject: VIDEO: Cleanup QTRLE In particular, the colors are not converted to the screen format upon decoding. The code should also now work with 32bpp screen formats. --- video/codecs/qtrle.cpp | 135 ++++++++++++++++++++++++++----------------------- video/codecs/qtrle.h | 3 +- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/video/codecs/qtrle.cpp b/video/codecs/qtrle.cpp index f01720ec86..d2cdea27de 100644 --- a/video/codecs/qtrle.cpp +++ b/video/codecs/qtrle.cpp @@ -37,28 +37,25 @@ namespace Video { QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() { _bitsPerPixel = bitsPerPixel; - _pixelFormat = g_system->getScreenFormat(); - // We need to increase the surface size to a multiple of 4 + // We need to ensure the width is a multiple of 4 uint16 wMod = width % 4; - if(wMod != 0) + if (wMod != 0) width += 4 - wMod; - debug(2, "QTRLE corrected width: %d", width); - _surface = new Graphics::Surface(); - _surface->create(width, height, _bitsPerPixel <= 8 ? Graphics::PixelFormat::createFormatCLUT8() : _pixelFormat); + _surface->create(width, height, getPixelFormat()); } #define CHECK_STREAM_PTR(n) \ if ((stream->pos() + n) > stream->size()) { \ - warning ("Problem: stream out of bounds (%d >= %d)", stream->pos() + n, stream->size()); \ + warning("QTRLE Problem: stream out of bounds (%d > %d)", stream->pos() + n, stream->size()); \ return; \ } #define CHECK_PIXEL_PTR(n) \ if ((int32)pixelPtr + n > _surface->w * _surface->h) { \ - warning ("Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \ + warning("QTRLE Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \ return; \ } \ @@ -132,8 +129,6 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, for (int8 i = numPixels - 1; i >= 0; i--) { pi[numPixels - 1 - i] = (stream->readByte() >> ((i * bpp) & 0x07)) & ((1 << bpp) - 1); - // FIXME: Is this right? - //stream_ptr += ((i & ((num_pixels>>2)-1)) == 0); if ((i & ((numPixels >> 2) - 1)) == 0) stream->readByte(); } @@ -215,7 +210,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) { uint32 pixelPtr = 0; - OverlayColor *rgb = (OverlayColor *)_surface->pixels; + uint16 *rgb = (uint16 *)_surface->pixels; while (linesToChange--) { CHECK_STREAM_PTR(2); @@ -235,25 +230,15 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u CHECK_PIXEL_PTR(rleCode); - while (rleCode--) { - // Convert from RGB555 to the format specified by the Overlay - byte r = 0, g = 0, b = 0; - Graphics::colorToRGB >(rgb16, r, g, b); - rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b); - } + while (rleCode--) + rgb[pixelPtr++] = rgb16; } else { CHECK_STREAM_PTR(rleCode * 2); CHECK_PIXEL_PTR(rleCode); // copy pixels directly to output - while (rleCode--) { - uint16 rgb16 = stream->readUint16BE(); - - // Convert from RGB555 to the format specified by the Overlay - byte r = 0, g = 0, b = 0; - Graphics::colorToRGB >(rgb16, r, g, b); - rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b); - } + while (rleCode--) + rgb[pixelPtr++] = stream->readUint16BE(); } } @@ -263,7 +248,7 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) { uint32 pixelPtr = 0; - OverlayColor *rgb = (OverlayColor *)_surface->pixels; + uint32 *rgb = (uint32 *)_surface->pixels; while (linesToChange--) { CHECK_STREAM_PTR(2); @@ -283,11 +268,12 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u byte r = stream->readByte(); byte g = stream->readByte(); byte b = stream->readByte(); + uint32 color = _surface->format.RGBToColor(r, g, b); CHECK_PIXEL_PTR(rleCode); while (rleCode--) - rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b); + rgb[pixelPtr++] = color; } else { CHECK_STREAM_PTR(rleCode * 3); CHECK_PIXEL_PTR(rleCode); @@ -297,7 +283,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u byte r = stream->readByte(); byte g = stream->readByte(); byte b = stream->readByte(); - rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b); + rgb[pixelPtr++] = _surface->format.RGBToColor(r, g, b); } } } @@ -308,7 +294,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) { uint32 pixelPtr = 0; - OverlayColor *rgb = (OverlayColor *)_surface->pixels; + uint32 *rgb = (uint32 *)_surface->pixels; while (linesToChange--) { CHECK_STREAM_PTR(2); @@ -329,11 +315,12 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u byte r = stream->readByte(); byte g = stream->readByte(); byte b = stream->readByte(); + uint32 color = _surface->format.ARGBToColor(a, r, g, b); CHECK_PIXEL_PTR(rleCode); while (rleCode--) - rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b); + rgb[pixelPtr++] = color; } else { CHECK_STREAM_PTR(rleCode * 4); CHECK_PIXEL_PTR(rleCode); @@ -344,7 +331,7 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u byte r = stream->readByte(); byte g = stream->readByte(); byte b = stream->readByte(); - rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b); + rgb[pixelPtr++] = _surface->format.ARGBToColor(a, r, g, b); } } } @@ -354,7 +341,7 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u } const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *stream) { - uint16 start_line = 0; + uint16 startLine = 0; uint16 height = _surface->h; // check if this frame is even supposed to change @@ -369,44 +356,45 @@ const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *s // if a header is present, fetch additional decoding parameters if (header & 8) { - if(stream->size() < 14) + if (stream->size() < 14) return _surface; - start_line = stream->readUint16BE(); + + startLine = stream->readUint16BE(); stream->readUint16BE(); // Unknown height = stream->readUint16BE(); stream->readUint16BE(); // Unknown } - uint32 row_ptr = _surface->w * start_line; + uint32 rowPtr = _surface->w * startLine; switch (_bitsPerPixel) { - case 1: - case 33: - decode1(stream, row_ptr, height); - break; - case 2: - case 34: - decode2_4(stream, row_ptr, height, 2); - break; - case 4: - case 36: - decode2_4(stream, row_ptr, height, 4); - break; - case 8: - case 40: - decode8(stream, row_ptr, height); - break; - case 16: - decode16(stream, row_ptr, height); - break; - case 24: - decode24(stream, row_ptr, height); - break; - case 32: - decode32(stream, row_ptr, height); - break; - default: - error ("Unsupported bits per pixel %d", _bitsPerPixel); + case 1: + case 33: + decode1(stream, rowPtr, height); + break; + case 2: + case 34: + decode2_4(stream, rowPtr, height, 2); + break; + case 4: + case 36: + decode2_4(stream, rowPtr, height, 4); + break; + case 8: + case 40: + decode8(stream, rowPtr, height); + break; + case 16: + decode16(stream, rowPtr, height); + break; + case 24: + decode24(stream, rowPtr, height); + break; + case 32: + decode32(stream, rowPtr, height); + break; + default: + error("Unsupported QTRLE bits per pixel %d", _bitsPerPixel); } return _surface; @@ -417,4 +405,27 @@ QTRLEDecoder::~QTRLEDecoder() { delete _surface; } +Graphics::PixelFormat QTRLEDecoder::getPixelFormat() const { + switch (_bitsPerPixel) { + case 1: + case 33: + case 2: + case 34: + case 4: + case 36: + case 8: + case 40: + return Graphics::PixelFormat::createFormatCLUT8(); + case 16: + return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); + case 24: + case 32: + return Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24); + default: + error("Unsupported QTRLE bits per pixel %d", _bitsPerPixel); + } + + return Graphics::PixelFormat(); +} + } // End of namespace Video diff --git a/video/codecs/qtrle.h b/video/codecs/qtrle.h index 6f8e113ca5..d9db58ab23 100644 --- a/video/codecs/qtrle.h +++ b/video/codecs/qtrle.h @@ -34,13 +34,12 @@ public: ~QTRLEDecoder(); const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream); - Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; } + Graphics::PixelFormat getPixelFormat() const; private: byte _bitsPerPixel; Graphics::Surface *_surface; - Graphics::PixelFormat _pixelFormat; void decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange); void decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp); -- cgit v1.2.3 From 2a1193a6b1d19664b876fb98568fa677463781a6 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 12 Jun 2012 09:33:21 -0400 Subject: VIDEO: Make rpza decode to its own pixel format --- video/codecs/rpza.cpp | 22 +++++----------------- video/codecs/rpza.h | 3 +-- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/video/codecs/rpza.cpp b/video/codecs/rpza.cpp index df5738202e..acc1b7f358 100644 --- a/video/codecs/rpza.cpp +++ b/video/codecs/rpza.cpp @@ -28,22 +28,17 @@ #include "common/system.h" #include "common/stream.h" #include "common/textconsole.h" -#include "graphics/colormasks.h" namespace Video { RPZADecoder::RPZADecoder(uint16 width, uint16 height) : Codec() { - _pixelFormat = g_system->getScreenFormat(); - // We need to increase the surface size to a multiple of 4 uint16 wMod = width % 4; - if(wMod != 0) + if (wMod != 0) width += 4 - wMod; - debug(2, "RPZA corrected width: %d", width); - _surface = new Graphics::Surface(); - _surface->create(width, height, _pixelFormat); + _surface->create(width, height, getPixelFormat()); } RPZADecoder::~RPZADecoder() { @@ -59,18 +54,11 @@ RPZADecoder::~RPZADecoder() { } \ totalBlocks--; \ if (totalBlocks < 0) \ - error("block counter just went negative (this should not happen)") \ + error("rpza block counter just went negative (this should not happen)") \ -// Convert from RGB555 to the format specified by the screen #define PUT_PIXEL(color) \ - if ((int32)blockPtr < _surface->w * _surface->h) { \ - byte r = 0, g = 0, b = 0; \ - Graphics::colorToRGB >(color, r, g, b); \ - if (_pixelFormat.bytesPerPixel == 2) \ - *((uint16 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \ - else \ - *((uint32 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \ - } \ + if ((int32)blockPtr < _surface->w * _surface->h) \ + WRITE_UINT16((uint16 *)_surface->pixels + blockPtr, color); \ blockPtr++ const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *stream) { diff --git a/video/codecs/rpza.h b/video/codecs/rpza.h index 809a69f444..f082d25549 100644 --- a/video/codecs/rpza.h +++ b/video/codecs/rpza.h @@ -34,11 +34,10 @@ public: ~RPZADecoder(); const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream); - Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; } + Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); } private: Graphics::Surface *_surface; - Graphics::PixelFormat _pixelFormat; }; } // End of namespace Video -- cgit v1.2.3 From 34c57519489186ae62a28072199b247211c05161 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Jun 2012 04:13:16 +0200 Subject: KYRA: Reduce amount of updateScreen calls. This fixes some slowdowns in Kyra2 with the OpenGL backend for me. Most of the updateScreen calls saved were introduced by us implementing the original behavior of hiding the mouse before drawing onto the screen and showing it again afterwards, since the mouse cursor is not drawn on the game screen in our implementation (and unlike in the original) this is not necessary. --- engines/kyra/animator_hof.cpp | 2 -- engines/kyra/animator_mr.cpp | 4 ---- engines/kyra/gui_hof.cpp | 35 ----------------------------------- engines/kyra/gui_lok.cpp | 6 ------ engines/kyra/gui_mr.cpp | 25 ------------------------- engines/kyra/gui_v1.cpp | 9 --------- engines/kyra/gui_v2.cpp | 10 ---------- engines/kyra/items_hof.cpp | 5 ----- engines/kyra/items_lok.cpp | 16 ---------------- engines/kyra/items_mr.cpp | 10 ---------- engines/kyra/items_v2.cpp | 7 ------- engines/kyra/kyra_hof.cpp | 10 ---------- engines/kyra/kyra_lok.cpp | 8 -------- engines/kyra/kyra_mr.cpp | 2 -- engines/kyra/kyra_v2.cpp | 3 --- engines/kyra/screen.cpp | 4 ---- engines/kyra/screen_lok.cpp | 2 -- engines/kyra/script_hof.cpp | 4 ---- engines/kyra/script_lok.cpp | 4 ---- engines/kyra/script_mr.cpp | 4 ---- engines/kyra/sequences_lok.cpp | 2 -- engines/kyra/text_hof.cpp | 9 --------- engines/kyra/text_lok.cpp | 6 ------ engines/kyra/text_mr.cpp | 6 ------ 24 files changed, 193 deletions(-) diff --git a/engines/kyra/animator_hof.cpp b/engines/kyra/animator_hof.cpp index 5a2378f4d0..59112504d6 100644 --- a/engines/kyra/animator_hof.cpp +++ b/engines/kyra/animator_hof.cpp @@ -104,9 +104,7 @@ void KyraEngine_HoF::refreshAnimObjects(int force) { if (height + y > 143) height -= height + y - 144; - _screen->hideMouse(); _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); curObject->needRefresh = false; } diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp index 29fa3aba80..83e774e2fc 100644 --- a/engines/kyra/animator_mr.cpp +++ b/engines/kyra/animator_mr.cpp @@ -175,9 +175,7 @@ void KyraEngine_MR::refreshAnimObjects(int force) { height -= height + y - (maxY + 1); if (height > 0) { - _screen->hideMouse(); _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); } curObject->needRefresh = false; @@ -209,9 +207,7 @@ void KyraEngine_MR::updateItemAnimations() { nextFrame = true; _screen->drawShape(2, getShapePtr(422 + i), 9, 0, 0, 0); _screen->drawShape(2, getShapePtr(shpIdx), 9, 0, 0, 0); - _screen->hideMouse(); _screen->copyRegion(9, 0, _inventoryX[i], _inventoryY[i], 24, 20, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); } } } diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp index c1bfee066f..36fbb0b40a 100644 --- a/engines/kyra/gui_hof.cpp +++ b/engines/kyra/gui_hof.cpp @@ -121,14 +121,12 @@ int KyraEngine_HoF::buttonInventory(Button *button) { if (_itemInHand == kItemNone) { if (item == kItemNone) return 0; - _screen->hideMouse(); clearInventorySlot(inventorySlot, 0); snd_playSoundEffect(0x0B); setMouseCursor(item); int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7; updateCommandLineEx(item+54, string, 0xD6); _itemInHand = (int16)item; - _screen->showMouse(); _mainCharacter.inventory[inventorySlot] = kItemNone; } else { if (_mainCharacter.inventory[inventorySlot] != kItemNone) { @@ -137,23 +135,19 @@ int KyraEngine_HoF::buttonInventory(Button *button) { item = _mainCharacter.inventory[inventorySlot]; snd_playSoundEffect(0x0B); - _screen->hideMouse(); clearInventorySlot(inventorySlot, 0); drawInventoryShape(0, _itemInHand, inventorySlot); setMouseCursor(item); int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7; updateCommandLineEx(item+54, string, 0xD6); - _screen->showMouse(); _mainCharacter.inventory[inventorySlot] = _itemInHand; setHandItem(item); } else { snd_playSoundEffect(0x0C); - _screen->hideMouse(); drawInventoryShape(0, _itemInHand, inventorySlot); _screen->setMouseCursor(0, 0, getShapePtr(0)); int string = (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 8; updateCommandLineEx(_itemInHand+54, string, 0xD6); - _screen->showMouse(); _mainCharacter.inventory[inventorySlot] = _itemInHand; _itemInHand = kItemNone; } @@ -172,9 +166,7 @@ int KyraEngine_HoF::scrollInventory(Button *button) { memcpy(src+5, dst, sizeof(Item)*5); memcpy(dst, dst+5, sizeof(Item)*5); memcpy(dst+5, temp, sizeof(Item)*5); - _screen->hideMouse(); _screen->copyRegion(0x46, 0x90, 0x46, 0x90, 0x71, 0x2E, 0, 2); - _screen->showMouse(); redrawInventory(2); scrollInventoryWheel(); return 0; @@ -199,9 +191,7 @@ int KyraEngine_HoF::findFreeVisibleInventorySlot() { void KyraEngine_HoF::removeSlotFromInventory(int slot) { _mainCharacter.inventory[slot] = kItemNone; if (slot < 10) { - _screen->hideMouse(); clearInventorySlot(slot, 0); - _screen->showMouse(); } } @@ -223,15 +213,12 @@ bool KyraEngine_HoF::checkInventoryItemExchange(Item handItem, int slot) { snd_playSoundEffect(0x68); _mainCharacter.inventory[slot] = newItem; - _screen->hideMouse(); clearInventorySlot(slot, 0); drawInventoryShape(0, newItem, slot); if (removeItem) removeHandItem(); - _screen->showMouse(); - if (_lang != 1) updateCommandLineEx(newItem+54, 0x2E, 0xD6); @@ -243,12 +230,10 @@ bool KyraEngine_HoF::checkInventoryItemExchange(Item handItem, int slot) { void KyraEngine_HoF::drawInventoryShape(int page, Item item, int slot) { _screen->drawShape(page, getShapePtr(item+64), _inventoryX[slot], _inventoryY[slot], 0, 0); - _screen->updateScreen(); } void KyraEngine_HoF::clearInventorySlot(int slot, int page) { _screen->drawShape(page, getShapePtr(240+slot), _inventoryX[slot], _inventoryY[slot], 0, 0); - _screen->updateScreen(); } void KyraEngine_HoF::redrawInventory(int page) { @@ -256,7 +241,6 @@ void KyraEngine_HoF::redrawInventory(int page) { _screen->_curPage = page; const Item *inventory = _mainCharacter.inventory; - _screen->hideMouse(); for (int i = 0; i < 10; ++i) { clearInventorySlot(i, page); if (inventory[i] != kItemNone) { @@ -264,7 +248,6 @@ void KyraEngine_HoF::redrawInventory(int page) { drawInventoryShape(page, inventory[i], i); } } - _screen->showMouse(); _screen->updateScreen(); _screen->_curPage = pageBackUp; @@ -277,17 +260,13 @@ void KyraEngine_HoF::scrollInventoryWheel() { memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000); uint8 overlay[0x100]; _screen->generateOverlay(_screen->getPalette(0), overlay, 0, 50); - _screen->hideMouse(); _screen->copyRegion(0x46, 0x90, 0x46, 0x79, 0x71, 0x17, 0, 2, Screen::CR_NO_P_CHECK); - _screen->showMouse(); snd_playSoundEffect(0x25); bool breakFlag = false; for (int i = 0; i <= 6 && !breakFlag; ++i) { if (movie.opened()) { - _screen->hideMouse(); movie.displayFrame(i % frames, 0, 0, 0, 0, 0, 0); - _screen->showMouse(); _screen->updateScreen(); } @@ -355,9 +334,7 @@ int KyraEngine_HoF::bookButton(Button *button) { _bookNewPage = _bookCurPage; if (_screenBuffer) { - _screen->hideMouse(); memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); - _screen->showMouse(); } _screen->copyPalette(2, 0); @@ -382,9 +359,7 @@ int KyraEngine_HoF::bookButton(Button *button) { restorePage3(); if (_screenBuffer) { - _screen->hideMouse(); _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); - _screen->showMouse(); } setHandItem(_itemInHand); @@ -471,7 +446,6 @@ void KyraEngine_HoF::showBookPage() { int rightPageY = _bookPageYOffset[_bookCurPage+1]; - _screen->hideMouse(); if (leftPage) { bookDecodeText(leftPage); bookPrintText(2, leftPage, 20, leftPageY+20, 0x31); @@ -483,7 +457,6 @@ void KyraEngine_HoF::showBookPage() { bookPrintText(2, rightPage, 176, rightPageY+20, 0x31); delete[] rightPage; } - _screen->showMouse(); } void KyraEngine_HoF::bookLoop() { @@ -517,10 +490,8 @@ void KyraEngine_HoF::bookLoop() { loadBookBkgd(); showBookPage(); snd_playSoundEffect(0x64); - _screen->hideMouse(); _screen->copyRegion(0, 0, 0, 0, 0x140, 0xC8, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); - _screen->showMouse(); } _system->delayMillis(10); } @@ -550,9 +521,7 @@ void KyraEngine_HoF::bookPrintText(int dstPage, const uint8 *str, int x, int y, Screen::FontId oldFont = _screen->setFont(_flags.lang == Common::JA_JPN ? Screen::FID_SJIS_FNT : Screen::FID_BOOKFONT_FNT); _screen->_charWidth = -2; - _screen->hideMouse(); _screen->printText((const char *)str, x, y, color, (_flags.lang == Common::JA_JPN) ? 0xf6 : 0); - _screen->showMouse(); _screen->_charWidth = 0; _screen->setFont(oldFont); @@ -679,9 +648,7 @@ int GUI_HoF::optionsButton(Button *button) { _restartGame = false; _reloadTemporarySave = false; - _screen->hideMouse(); updateButton(&_vm->_inventoryButtons[0]); - _screen->showMouse(); if (!_screen->isMouseVisible() && button) return 0; @@ -690,9 +657,7 @@ int GUI_HoF::optionsButton(Button *button) { if (_vm->_mouseState < -1) { _vm->_mouseState = -1; - _screen->hideMouse(); _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); - _screen->showMouse(); return 0; } diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp index b4e5148b64..8e18ff910d 100644 --- a/engines/kyra/gui_lok.cpp +++ b/engines/kyra/gui_lok.cpp @@ -48,19 +48,16 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { snd_playSoundEffect(0x36); return 0; } else { - _screen->hideMouse(); _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12); snd_playSoundEffect(0x35); setMouseItem(inventoryItem); updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179); _itemInHand = inventoryItem; - _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = kItemNone; } } else { if (inventoryItem != kItemNone) { snd_playSoundEffect(0x35); - _screen->hideMouse(); _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12); _screen->drawShape(0, _shapes[216 + _itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); setMouseItem(inventoryItem); @@ -69,16 +66,13 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) { updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179); else updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[1], 179); - _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = _itemInHand; _itemInHand = inventoryItem; } else { snd_playSoundEffect(0x32); - _screen->hideMouse(); _screen->drawShape(0, _shapes[216 + _itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); _screen->setMouseCursor(1, 1, _shapes[0]); updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _placedList[0], 179); - _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = _itemInHand; _itemInHand = kItemNone; } diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp index e88b7fdffb..37526f9a5f 100644 --- a/engines/kyra/gui_mr.cpp +++ b/engines/kyra/gui_mr.cpp @@ -104,7 +104,6 @@ int KyraEngine_MR::callbackButton3(Button *button) { void KyraEngine_MR::showMessage(const char *string, uint8 c0, uint8 c1) { _shownMessage = string; - _screen->hideMouse(); restoreCommandLine(); _restoreCommandLine = false; @@ -118,8 +117,6 @@ void KyraEngine_MR::showMessage(const char *string, uint8 c0, uint8 c1) { _screen->updateScreen(); setCommandLineRestoreTimer(7); } - - _screen->showMouse(); } void KyraEngine_MR::showMessageFromCCode(int string, uint8 c0, int) { @@ -330,10 +327,8 @@ void KyraEngine_MR::drawMalcolmsMoodText() { _screen->_curPage = 2; } - _screen->hideMouse(); _screen->drawShape(_screen->_curPage, getShapePtr(432), 244, 189, 0, 0); _text->printText(string, x, y+1, 0xFF, 0xF0, 0x00); - _screen->showMouse(); _screen->_curPage = pageBackUp; } @@ -441,7 +436,6 @@ void KyraEngine_MR::redrawInventory(int page) { int pageBackUp = _screen->_curPage; _screen->_curPage = page; - _screen->hideMouse(); for (int i = 0; i < 10; ++i) { clearInventorySlot(i, page); @@ -451,7 +445,6 @@ void KyraEngine_MR::redrawInventory(int page) { } } - _screen->showMouse(); _screen->_curPage = pageBackUp; if (page == 0 || page == 1) @@ -489,14 +482,12 @@ int KyraEngine_MR::buttonInventory(Button *button) { if (slotItem == kItemNone) return 0; - _screen->hideMouse(); clearInventorySlot(slot, 0); snd_playSoundEffect(0x0B, 0xC8); setMouseCursor(slotItem); updateItemCommand(slotItem, (_lang == 1) ? getItemCommandStringPickUp(slotItem) : 0, 0xFF); _itemInHand = slotItem; _mainCharacter.inventory[slot] = kItemNone; - _screen->showMouse(); } else if (_itemInHand == 27) { if (_chatText) return 0; @@ -508,21 +499,17 @@ int KyraEngine_MR::buttonInventory(Button *button) { snd_playSoundEffect(0x0B, 0xC8); - _screen->hideMouse(); clearInventorySlot(slot, 0); drawInventorySlot(0, _itemInHand, slot); setMouseCursor(slotItem); updateItemCommand(slotItem, (_lang == 1) ? getItemCommandStringPickUp(slotItem) : 0, 0xFF); _mainCharacter.inventory[slot] = _itemInHand; _itemInHand = slotItem; - _screen->showMouse(); } else { snd_playSoundEffect(0x0C, 0xC8); - _screen->hideMouse(); drawInventorySlot(0, _itemInHand, slot); _screen->setMouseCursor(0, 0, getShapePtr(0)); updateItemCommand(_itemInHand, (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 2, 0xFF); - _screen->showMouse(); _mainCharacter.inventory[slot] = _itemInHand; _itemInHand = kItemNone; } @@ -624,22 +611,18 @@ int KyraEngine_MR::buttonShowScore(Button *button) { int KyraEngine_MR::buttonJesterStaff(Button *button) { makeCharFacingMouse(); if (_itemInHand == 27) { - _screen->hideMouse(); removeHandItem(); snd_playSoundEffect(0x0C, 0xC8); drawJestersStaff(1, 0); updateItemCommand(27, 2, 0xFF); setGameFlag(0x97); - _screen->showMouse(); } else if (_itemInHand == kItemNone) { if (queryGameFlag(0x97)) { - _screen->hideMouse(); snd_playSoundEffect(0x0B, 0xC8); setHandItem(27); drawJestersStaff(0, 0); updateItemCommand(27, 0, 0xFF); resetGameFlag(0x97); - _screen->showMouse(); } else { if (queryGameFlag(0x2F)) objectChat((const char *)getTableEntry(_cCodeFile, 20), 0, 204, 20); @@ -1108,9 +1091,7 @@ int GUI_MR::redrawButtonCallback(Button *button) { if (!_displayMenu) return 0; - _screen->hideMouse(); _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xD0); - _screen->showMouse(); return 0; } @@ -1119,9 +1100,7 @@ int GUI_MR::redrawShadedButtonCallback(Button *button) { if (!_displayMenu) return 0; - _screen->hideMouse(); _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xD1, 0xCF); - _screen->showMouse(); return 0; } @@ -1162,9 +1141,7 @@ int GUI_MR::quitGame(Button *caller) { int GUI_MR::optionsButton(Button *button) { PauseTimer pause(*_vm->_timer); - _screen->hideMouse(); updateButton(&_vm->_mainButtonData[0]); - _screen->showMouse(); if (!_vm->_inventoryState && button && !_vm->_menuDirectlyToLoad) return 0; @@ -1179,9 +1156,7 @@ int GUI_MR::optionsButton(Button *button) { if (_vm->_mouseState < -1) { _vm->_mouseState = -1; - _screen->hideMouse(); _screen->setMouseCursor(1, 1, _vm->getShapePtr(0)); - _screen->showMouse(); return 0; } diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp index f3459ddfe3..cec6562dd9 100644 --- a/engines/kyra/gui_v1.cpp +++ b/engines/kyra/gui_v1.cpp @@ -70,8 +70,6 @@ void GUI_v1::initMenuLayout(Menu &menu) { void GUI_v1::initMenu(Menu &menu) { _menuButtonList = 0; - _screen->hideMouse(); - int textX; int textY; @@ -192,7 +190,6 @@ void GUI_v1::initMenu(Menu &menu) { updateMenuButton(scrollDownButton); } - _screen->showMouse(); _screen->updateScreen(); } @@ -309,10 +306,8 @@ void GUI_v1::updateMenuButton(Button *button) { if (!_displayMenu) return; - _screen->hideMouse(); updateButton(button); _screen->updateScreen(); - _screen->showMouse(); } void GUI_v1::updateButton(Button *button) { @@ -340,12 +335,10 @@ int GUI_v1::redrawButtonCallback(Button *button) { if (!_displayMenu) return 0; - _screen->hideMouse(); if (_vm->gameFlags().platform == Common::kPlatformAmiga) _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17); else _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8); - _screen->showMouse(); return 0; } @@ -354,12 +347,10 @@ int GUI_v1::redrawShadedButtonCallback(Button *button) { if (!_displayMenu) return 0; - _screen->hideMouse(); if (_vm->gameFlags().platform == Common::kPlatformAmiga) _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18); else _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA); - _screen->showMouse(); return 0; } diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index 65f8bd45e5..1df4149d2e 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -105,15 +105,11 @@ void GUI_v2::processButton(Button *button) { switch (val1 - 1) { case 0: - _screen->hideMouse(); _screen->drawShape(_screen->_curPage, dataPtr, x, y, button->dimTableIndex, 0x10); - _screen->showMouse(); break; case 1: - _screen->hideMouse(); _screen->printText((const char *)dataPtr, x, y, val2, val3); - _screen->showMouse(); break; case 3: @@ -122,22 +118,16 @@ void GUI_v2::processButton(Button *button) { break; case 4: - _screen->hideMouse(); _screen->drawBox(x, y, x2, y2, val2); - _screen->showMouse(); break; case 5: - _screen->hideMouse(); _screen->fillRect(x, y, x2, y2, val2, -1, true); - _screen->showMouse(); break; default: break; } - - _screen->updateScreen(); } int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWheel) { diff --git a/engines/kyra/items_hof.cpp b/engines/kyra/items_hof.cpp index 711e1b8f7c..ef2c50c0c5 100644 --- a/engines/kyra/items_hof.cpp +++ b/engines/kyra/items_hof.cpp @@ -300,8 +300,6 @@ void KyraEngine_HoF::itemDropDown(int startX, int startY, int dstX, int dstY, in } void KyraEngine_HoF::exchangeMouseItem(int itemPos) { - _screen->hideMouse(); - deleteItemAnimEntry(itemPos); int itemId = _itemList[itemPos].id; @@ -317,7 +315,6 @@ void KyraEngine_HoF::exchangeMouseItem(int itemPos) { str2 = getItemCommandStringPickUp(itemId); updateCommandLineEx(itemId + 54, str2, 0xD6); - _screen->showMouse(); runSceneScript6(); } @@ -331,7 +328,6 @@ bool KyraEngine_HoF::pickUpItem(int x, int y) { if (_itemInHand >= 0) { exchangeMouseItem(itemPos); } else { - _screen->hideMouse(); deleteItemAnimEntry(itemPos); int itemId = _itemList[itemPos].id; _itemList[itemPos].id = kItemNone; @@ -344,7 +340,6 @@ bool KyraEngine_HoF::pickUpItem(int x, int y) { updateCommandLineEx(itemId + 54, str2, 0xD6); _itemInHand = itemId; - _screen->showMouse(); runSceneScript6(); } diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp index 2937038463..b92cd616c1 100644 --- a/engines/kyra/items_lok.cpp +++ b/engines/kyra/items_lok.cpp @@ -163,17 +163,13 @@ void KyraEngine_LoK::placeItemInGenericMapScene(int item, int index) { } void KyraEngine_LoK::setHandItem(Item item) { - _screen->hideMouse(); setMouseItem(item); _itemInHand = item; - _screen->showMouse(); } void KyraEngine_LoK::removeHandItem() { - _screen->hideMouse(); _screen->setMouseCursor(1, 1, _shapes[0]); _itemInHand = kItemNone; - _screen->showMouse(); } void KyraEngine_LoK::setMouseItem(Item item) { @@ -415,7 +411,6 @@ int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, in } void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { - _screen->hideMouse(); _animator->animRemoveGameItem(itemIndex); assert(sceneId < _roomTableSize); Room *currentRoom = &_roomTable[sceneId]; @@ -432,7 +427,6 @@ void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) { updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[0], 179); else updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[1], 179); - _screen->showMouse(); clickEventHandler2(); } @@ -720,9 +714,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) { _itemInHand = kItemNone; } else { _characterList[0].inventoryItems[itemPos] = kItemNone; - _screen->hideMouse(); _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); - _screen->showMouse(); } _screen->showMouse(); @@ -793,9 +785,7 @@ void KyraEngine_LoK::magicInMouseItem(int animIndex, int item, int itemPos) { _itemInHand = item; } else { _characterList[0].inventoryItems[itemPos] = item; - _screen->hideMouse(); _screen->drawShape(0, _shapes[216 + item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0); - _screen->showMouse(); } _screen->showMouse(); _screen->_curPage = videoPageBackUp; @@ -846,9 +836,7 @@ void KyraEngine_LoK::updatePlayerItemsForScene() { ++_itemInHand; if (_itemInHand > 33) _itemInHand = 33; - _screen->hideMouse(); _screen->setMouseCursor(8, 15, _shapes[216 + _itemInHand]); - _screen->showMouse(); } bool redraw = false; @@ -864,9 +852,7 @@ void KyraEngine_LoK::updatePlayerItemsForScene() { } if (redraw) { - _screen->hideMouse(); redrawInventory(0); - _screen->showMouse(); } if (_itemInHand == 33) @@ -884,7 +870,6 @@ void KyraEngine_LoK::updatePlayerItemsForScene() { void KyraEngine_LoK::redrawInventory(int page) { int videoPageBackUp = _screen->_curPage; _screen->_curPage = page; - _screen->hideMouse(); for (int i = 0; i < 10; ++i) { _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, page); @@ -893,7 +878,6 @@ void KyraEngine_LoK::redrawInventory(int page) { _screen->drawShape(page, _shapes[216 + item], _itemPosX[i], _itemPosY[i], 0, 0); } } - _screen->showMouse(); _screen->_curPage = videoPageBackUp; _screen->updateScreen(); } diff --git a/engines/kyra/items_mr.cpp b/engines/kyra/items_mr.cpp index c731627026..029f676538 100644 --- a/engines/kyra/items_mr.cpp +++ b/engines/kyra/items_mr.cpp @@ -319,7 +319,6 @@ void KyraEngine_MR::exchangeMouseItem(int itemPos, int runScript) { return; } - _screen->hideMouse(); deleteItemAnimEntry(itemPos); Item itemId = _itemList[itemPos].id; @@ -335,7 +334,6 @@ void KyraEngine_MR::exchangeMouseItem(int itemPos, int runScript) { str2 = getItemCommandStringPickUp(itemId); updateItemCommand(itemId, str2, 0xFF); - _screen->showMouse(); if (runScript) runSceneScript6(); @@ -350,7 +348,6 @@ bool KyraEngine_MR::pickUpItem(int x, int y, int runScript) { if (_itemInHand >= 0) { exchangeMouseItem(itemPos, runScript); } else { - _screen->hideMouse(); deleteItemAnimEntry(itemPos); Item itemId = _itemList[itemPos].id; _itemList[itemPos].id = kItemNone; @@ -363,7 +360,6 @@ bool KyraEngine_MR::pickUpItem(int x, int y, int runScript) { updateItemCommand(itemId, itemString, 0xFF); _itemInHand = itemId; - _screen->showMouse(); if (runScript) runSceneScript6(); @@ -401,7 +397,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) { assert(animObjIndex != -1); - _screen->hideMouse(); snd_playSoundEffect(0x93, 0xC8); for (int i = 109; i <= 141; ++i) { _animObjects[animObjIndex].shapeIndex1 = i+248; @@ -411,7 +406,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) { deleteItemAnimEntry(itemSlot); _itemList[itemSlot].id = kItemNone; - _screen->showMouse(); return true; } @@ -440,7 +434,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) { _itemList[itemSlot].id = (int8)resItem; - _screen->hideMouse(); deleteItemAnimEntry(itemSlot); addItemToAnimList(itemSlot); @@ -448,7 +441,6 @@ bool KyraEngine_MR::itemListMagic(Item handItem, int itemSlot) { removeHandItem(); else if (newItem != 0xFF) setHandItem(newItem); - _screen->showMouse(); if (_lang != 1) updateItemCommand(resItem, 3, 0xFF); @@ -500,7 +492,6 @@ bool KyraEngine_MR::itemInventoryMagic(Item handItem, int invSlot) { _mainCharacter.inventory[invSlot] = (int8)resItem; - _screen->hideMouse(); clearInventorySlot(invSlot, 0); drawInventorySlot(0, resItem, invSlot); @@ -508,7 +499,6 @@ bool KyraEngine_MR::itemInventoryMagic(Item handItem, int invSlot) { removeHandItem(); else if (newItem != 0xFF) setHandItem(newItem); - _screen->showMouse(); if (_lang != 1) updateItemCommand(resItem, 3, 0xFF); diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp index c191c2e62b..2145a2c2f0 100644 --- a/engines/kyra/items_v2.cpp +++ b/engines/kyra/items_v2.cpp @@ -82,26 +82,19 @@ void KyraEngine_v2::resetItem(int index) { } void KyraEngine_v2::setHandItem(Item item) { - Screen *scr = screen(); - scr->hideMouse(); - if (item == kItemNone) { removeHandItem(); } else { setMouseCursor(item); _itemInHand = item; } - - scr->showMouse(); } void KyraEngine_v2::removeHandItem() { Screen *scr = screen(); - scr->hideMouse(); scr->setMouseCursor(0, 0, getShapePtr(0)); _itemInHand = kItemNone; _mouseState = kItemNone; - scr->showMouse(); } } // end of namesapce Kyra diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp index 0ba173d9d0..7fbecb7f53 100644 --- a/engines/kyra/kyra_hof.cpp +++ b/engines/kyra/kyra_hof.cpp @@ -419,8 +419,6 @@ void KyraEngine_HoF::startup() { _screen->loadPalette("PALETTE.COL", _screen->getPalette(0)); _screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0); _screen->copyPage(3, 0); - _screen->showMouse(); - _screen->hideMouse(); clearAnimObjects(); @@ -784,20 +782,16 @@ void KyraEngine_HoF::updateMouse() { if (type != 0 && _mouseState != type && _screen->isMouseVisible()) { _mouseState = type; - _screen->hideMouse(); _screen->setMouseCursor(xOffset, yOffset, getShapePtr(shapeIndex)); - _screen->showMouse(); } if (type == 0 && _mouseState != _itemInHand && _screen->isMouseVisible()) { if ((mouse.y > 145) || (mouse.x > 6 && mouse.x < 312 && mouse.y > 6 && mouse.y < 135)) { _mouseState = _itemInHand; - _screen->hideMouse(); if (_itemInHand == kItemNone) _screen->setMouseCursor(0, 0, getShapePtr(0)); else _screen->setMouseCursor(8, 15, getShapePtr(_itemInHand+64)); - _screen->showMouse(); } } } @@ -914,7 +908,6 @@ void KyraEngine_HoF::showMessageFromCCode(int id, int16 palIndex, int) { void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) { _shownMessage = string; - _screen->hideMouse(); _screen->fillRect(0, 190, 319, 199, 0xCF); if (string) { @@ -932,7 +925,6 @@ void KyraEngine_HoF::showMessage(const char *string, int16 palIndex) { } _fadeMessagePalette = false; - _screen->showMouse(); } void KyraEngine_HoF::showChapterMessage(int id, int16 palIndex) { @@ -1116,9 +1108,7 @@ int KyraEngine_HoF::getDrawLayer(int x, int y) { void KyraEngine_HoF::backUpPage0() { if (_screenBuffer) { - _screen->hideMouse(); memcpy(_screenBuffer, _screen->getCPagePtr(0), 64000); - _screen->showMouse(); } } diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp index ece4a0daba..27bc2ad22a 100644 --- a/engines/kyra/kyra_lok.cpp +++ b/engines/kyra/kyra_lok.cpp @@ -454,10 +454,8 @@ void KyraEngine_LoK::mainLoop() { if (_deathHandler != -1) { snd_playWanderScoreViaMap(0, 1); snd_playSoundEffect(49); - _screen->hideMouse(); _screen->setMouseCursor(1, 1, _shapes[0]); removeHandItem(); - _screen->showMouse(); _gui->buttonMenuCallback(0); _deathHandler = -1; } @@ -706,7 +704,6 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) { uint8 item = findItemAtPos(xpos, ypos); if (item != 0xFF) { if (_itemInHand == kItemNone) { - _screen->hideMouse(); _animator->animRemoveGameItem(item); snd_playSoundEffect(53); assert(_currentCharacter->sceneId < _roomTableSize); @@ -717,7 +714,6 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) { assert(_itemList && _takenList); updateSentenceCommand(_itemList[getItemListIndex(item2)], _takenList[0], 179); _itemInHand = item2; - _screen->showMouse(); clickEventHandler2(); return 1; } else { @@ -834,21 +830,17 @@ void KyraEngine_LoK::updateMousePointer(bool forceUpdate) { if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { _mouseState = newMouseState; - _screen->hideMouse(); _screen->setMouseCursor(newX, newY, _shapes[shape]); - _screen->showMouse(); } if (!newMouseState) { if (_mouseState != _itemInHand || forceUpdate) { if (mouse.y > 158 || (mouse.x >= 12 && mouse.x < 308 && mouse.y < 136 && mouse.y >= 12) || forceUpdate) { _mouseState = _itemInHand; - _screen->hideMouse(); if (_itemInHand == kItemNone) _screen->setMouseCursor(1, 1, _shapes[0]); else _screen->setMouseCursor(8, 15, _shapes[216 + _itemInHand]); - _screen->showMouse(); } } } diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp index 39ed0d038a..448e4ef70d 100644 --- a/engines/kyra/kyra_mr.cpp +++ b/engines/kyra/kyra_mr.cpp @@ -1298,7 +1298,6 @@ bool KyraEngine_MR::updateScore(int scoreId, int strId) { setNextIdleAnimTimer(); _scoreFlagTable[scoreIndex] |= (1 << scoreBit); - _screen->hideMouse(); strcpy(_stringBuffer, (const char *)getTableEntry(_scoreFile, strId)); strcat(_stringBuffer, ": "); @@ -1308,7 +1307,6 @@ bool KyraEngine_MR::updateScore(int scoreId, int strId) { if (count > 0) scoreIncrease(count, _stringBuffer); - _screen->showMouse(); setNextIdleAnimTimer(); return true; } diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index 75b568a00a..848fb18b6a 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -198,8 +198,6 @@ void KyraEngine_v2::moveCharacter(int facing, int x, int y) { y &= ~1; _mainCharacter.facing = facing; - Screen *scr = screen(); - scr->hideMouse(); switch (facing) { case 0: while (_mainCharacter.y1 > y) @@ -224,7 +222,6 @@ void KyraEngine_v2::moveCharacter(int facing, int x, int y) { default: break; } - scr->showMouse(); } void KyraEngine_v2::updateCharPosWithUpdate() { diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 711fe15348..4fd5985a09 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -1128,8 +1128,6 @@ void Screen::drawBox(int x1, int y1, int x2, int y2, int color) { void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2) { assert(x1 >= 0 && y1 >= 0); - hideMouse(); - fillRect(x1, y1, x2, y1 + 1, color1); fillRect(x2 - 1, y1, x2, y2, color1); @@ -1137,8 +1135,6 @@ void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color drawClippedLine(x1 + 1, y1 + 1, x1 + 1, y2 - 1, color2); drawClippedLine(x1, y2 - 1, x2 - 1, y2 - 1, color2); drawClippedLine(x1, y2, x2, y2, color2); - - showMouse(); } void Screen::drawClippedLine(int x1, int y1, int x2, int y2, int color) { diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp index f32a898dd9..f028f93294 100644 --- a/engines/kyra/screen_lok.cpp +++ b/engines/kyra/screen_lok.cpp @@ -190,7 +190,6 @@ void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) { _curPage = page; int curX = x; - hideMouse(); copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2); for (int i = 0; i < 19; ++i) { int tempX = curX + 1; @@ -208,7 +207,6 @@ void Screen_LoK::copyBackgroundBlock(int x, int page, int flag) { curX = curX % 38; } } - showMouse(); _curPage = oldVideoPage; } diff --git a/engines/kyra/script_hof.cpp b/engines/kyra/script_hof.cpp index b80b8105a1..fca83ae632 100644 --- a/engines/kyra/script_hof.cpp +++ b/engines/kyra/script_hof.cpp @@ -325,7 +325,6 @@ int KyraEngine_HoF::o2_drawShape(EMCState *script) { if (modeFlag) { _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0); } else { - _screen->hideMouse(); restorePage3(); _screen->drawShape(2, shp, x, y, 2, dsFlag ? 1 : 0); memcpy(_gamePlayBuffer, _screen->getCPagePtr(3), 46080); @@ -334,7 +333,6 @@ int KyraEngine_HoF::o2_drawShape(EMCState *script) { flagAnimObjsForRefresh(); flagAnimObjsSpecialRefresh(); refreshAnimObjectsIfNeed(); - _screen->showMouse(); } return 0; @@ -492,7 +490,6 @@ int KyraEngine_HoF::o2_drawSceneShape(EMCState *script) { int y = stackPos(2); int flag = (stackPos(3) != 0) ? 1 : 0; - _screen->hideMouse(); restorePage3(); _screen->drawShape(2, _sceneShapeTable[shape], x, y, 2, flag); @@ -504,7 +501,6 @@ int KyraEngine_HoF::o2_drawSceneShape(EMCState *script) { flagAnimObjsSpecialRefresh(); flagAnimObjsForRefresh(); refreshAnimObjectsIfNeed(); - _screen->showMouse(); return 0; } diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp index 8342bccab6..db9e01cabb 100644 --- a/engines/kyra/script_lok.cpp +++ b/engines/kyra/script_lok.cpp @@ -157,7 +157,6 @@ int KyraEngine_LoK::o1_dropItemInScene(EMCState *script) { int KyraEngine_LoK::o1_drawAnimShapeIntoScene(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); - _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); int shape = stackPos(0); int xpos = stackPos(1); @@ -169,7 +168,6 @@ int KyraEngine_LoK::o1_drawAnimShapeIntoScene(EMCState *script) { _animator->preserveAnyChangedBackgrounds(); _animator->flagAllObjectsForRefresh(); _animator->updateAllObjectShapes(); - _screen->showMouse(); return 0; } @@ -1298,7 +1296,6 @@ int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) { if (onlyHidPage) { _screen->drawShape(2, _shapes[216 + item], x, y, 0, flags); } else { - _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); _screen->drawShape(2, _shapes[216 + item], x, y, 0, flags); _screen->drawShape(0, _shapes[216 + item], x, y, 0, flags); @@ -1306,7 +1303,6 @@ int KyraEngine_LoK::o1_drawItemShapeIntoScene(EMCState *script) { _animator->preserveAnyChangedBackgrounds(); _animator->flagAllObjectsForRefresh(); _animator->updateAllObjectShapes(); - _screen->showMouse(); } return 0; } diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp index afe11aba02..22d0bc4e95 100644 --- a/engines/kyra/script_mr.cpp +++ b/engines/kyra/script_mr.cpp @@ -150,9 +150,7 @@ int KyraEngine_MR::o3_addItemToInventory(EMCState *script) { if (slot >= 0) { _mainCharacter.inventory[slot] = stackPos(0); if (_inventoryState) { - _screen->hideMouse(); redrawInventory(0); - _screen->showMouse(); } } return slot; @@ -330,7 +328,6 @@ int KyraEngine_MR::o3_drawSceneShape(EMCState *script) { int shape = stackPos(0); int flag = (stackPos(1) != 0) ? 1 : 0; - _screen->hideMouse(); restorePage3(); const int x = _sceneShapeDescs[shape].drawX; @@ -344,7 +341,6 @@ int KyraEngine_MR::o3_drawSceneShape(EMCState *script) { flagAnimObjsForRefresh(); refreshAnimObjectsIfNeed(); - _screen->showMouse(); return 0; } diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp index dd49d6faaa..e63d0a7d8f 100644 --- a/engines/kyra/sequences_lok.cpp +++ b/engines/kyra/sequences_lok.cpp @@ -838,9 +838,7 @@ void KyraEngine_LoK::seq_fillFlaskWithWater(int item, int type) { if (newItem == -1) return; - _screen->hideMouse(); setMouseItem(newItem); - _screen->showMouse(); _itemInHand = newItem; assert(_fullFlask); diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp index 4a52d7d740..06067d6693 100644 --- a/engines/kyra/text_hof.cpp +++ b/engines/kyra/text_hof.cpp @@ -42,9 +42,7 @@ void TextDisplayer_HoF::restoreTalkTextMessageBkgd(int srcPage, int dstPage) { void TextDisplayer_HoF::restoreScreen() { _vm->restorePage3(); _vm->drawAnimObjects(); - _screen->hideMouse(); _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); _vm->flagAnimObjsForRefresh(); _vm->refreshAnimObjects(0); } @@ -58,8 +56,6 @@ void TextDisplayer_HoF::printCustomCharacterText(const char *text, int x, int y, int x1 = 0, x2 = 0; calcWidestLineBounds(x1, x2, w, x); - _screen->hideMouse(); - _talkCoords.x = x1; _talkCoords.w = w+2; _talkCoords.y = y; @@ -78,7 +74,6 @@ void TextDisplayer_HoF::printCustomCharacterText(const char *text, int x, int y, } _screen->_curPage = curPageBackUp; - _screen->showMouse(); } char *TextDisplayer_HoF::preprocessString(const char *str) { @@ -248,8 +243,6 @@ void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, in restorePage3(); _text->backupTalkTextMessageBkgd(2, 2); - _screen->hideMouse(); - _chatTextEnabled = textEnabled(); if (_chatTextEnabled) { objectChatPrintText(str, object); @@ -264,8 +257,6 @@ void KyraEngine_HoF::objectChatInit(const char *str, int object, int vocHigh, in } else { _chatVocHigh = _chatVocLow = -1; } - - _screen->showMouse(); } void KyraEngine_HoF::objectChatPrintText(const char *str, int object) { diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp index 62bdf18816..a557940868 100644 --- a/engines/kyra/text_lok.cpp +++ b/engines/kyra/text_lok.cpp @@ -296,10 +296,8 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu _animator->restoreAllObjectBackgrounds(); _screen->copyRegion(12, _text->_talkMessageY, 12, 136, 296, _text->_talkMessageH, 2, 2); - _screen->hideMouse(); _text->printCharacterText(processedString, charNum, _characterList[charNum].x1); - _screen->showMouse(); } if (chatDuration == -2) @@ -317,10 +315,8 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu _screen->copyRegion(12, 136, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 2); _animator->preserveAllBackgrounds(); _animator->prepDrawAllObjects(); - _screen->hideMouse(); _screen->copyRegion(12, _text->_talkMessageY, 12, _text->_talkMessageY, 296, _text->_talkMessageH, 2, 0); - _screen->showMouse(); _animator->flagAllObjectsForRefresh(); _animator->copyChangedObjectsForward(0); } @@ -332,7 +328,6 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu } void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) { - _screen->hideMouse(); _screen->fillRect(8, 143, 311, 152, _flags.platform == Common::kPlatformAmiga ? 19 : 12); if (_flags.platform == Common::kPlatformAmiga) { @@ -354,7 +349,6 @@ void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) { } _text->printText(sentence, 8, 143, 0xFF, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0); - _screen->showMouse(); setTextFadeTimerCountdown(15); _fadeText = false; } diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp index b680e9c6f9..10b0880f29 100644 --- a/engines/kyra/text_mr.cpp +++ b/engines/kyra/text_mr.cpp @@ -145,9 +145,7 @@ void TextDisplayer_MR::printText(const char *str, int x, int y, uint8 c0, uint8 void TextDisplayer_MR::restoreScreen() { _vm->restorePage3(); _vm->drawAnimObjects(); - _screen->hideMouse(); _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, 2, 0, Screen::CR_NO_P_CHECK); - _screen->showMouse(); _vm->flagAnimObjsForRefresh(); _vm->refreshAnimObjects(0); } @@ -261,8 +259,6 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int restorePage3(); - _screen->hideMouse(); - _chatTextEnabled = textEnabled(); if (_chatTextEnabled) { objectChatPrintText(str, object); @@ -277,8 +273,6 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int } else { _chatVocHigh = _chatVocLow = -1; } - - _screen->showMouse(); } void KyraEngine_MR::objectChatPrintText(const char *str, int object) { -- cgit v1.2.3 From d5eb3e3c06a1f396f578b21c4a3aaff3519513a5 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Jun 2012 04:32:11 +0200 Subject: GUI: Allow querying of the pixel format used by ThemeEngine. --- gui/ThemeEngine.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 67221d98ce..21711e2955 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -275,6 +275,11 @@ public: void enable(); void disable(); + /** + * Query the set up pixel format. + */ + const Graphics::PixelFormat getPixelFormat() const { return _overlayFormat; } + /** * Implementation of the GUI::Theme API. Called when a * new dialog is opened. Note that the boolean parameter -- cgit v1.2.3 From cebbc11dac77d30fac3be4cc0ebdc6bc059636ef Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Jun 2012 04:44:39 +0200 Subject: GUI: Allow Surfaces with abitrary RGB pixel formats to be used in PicButtonWidget and GraphicsWidget. Only 1Bpp aka paletted surfaces are not supported. --- gui/widget.cpp | 79 ++++++++++++++++++++++++++++++++++++++++------------------ gui/widget.h | 4 +-- 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/gui/widget.cpp b/gui/widget.cpp index 657245c815..1b68e36ea8 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -376,7 +376,7 @@ void ButtonWidget::wantTickle(bool tickled) { PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey) : ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey), - _gfx(), _alpha(256), _transparency(false) { + _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) { setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); _type = kButtonWidget; @@ -384,38 +384,54 @@ PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, co PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey) : ButtonWidget(boss, name, "", tooltip, cmd, hotkey), - _alpha(256), _transparency(false) { + _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) { setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); _type = kButtonWidget; } PicButtonWidget::~PicButtonWidget() { - _gfx.free(); + _gfx->free(); + delete _gfx; } void PicButtonWidget::setGfx(const Graphics::Surface *gfx) { - _gfx.free(); + _gfx->free(); if (!gfx || !gfx->pixels) return; + if (gfx->format.bytesPerPixel == 1) { + warning("PicButtonWidget::setGfx got paletted surface passed"); + return; + } + + if (gfx->w > _w || gfx->h > _h) { warning("PicButtonWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h); return; } - // TODO: add conversion to OverlayColor - _gfx.copyFrom(*gfx); + _gfx->copyFrom(*gfx); } void PicButtonWidget::drawWidget() { g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags()); - if (sizeof(OverlayColor) == _gfx.format.bytesPerPixel && _gfx.pixels) { - const int x = _x + (_w - _gfx.w) / 2; - const int y = _y + (_h - _gfx.h) / 2; + if (_gfx->pixels) { + // Check whether the set up surface needs to be converted to the GUI + // color format. + const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); + if (_gfx->format != requiredFormat) { + Graphics::Surface *converted = _gfx->convertTo(requiredFormat); + _gfx->free(); + delete _gfx; + _gfx = converted; + } + + const int x = _x + (_w - _gfx->w) / 2; + const int y = _y + (_h - _gfx->h) / 2; - g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency); + g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx->w, y + _gfx->h), *_gfx, _state, _alpha, _transparency); } } @@ -603,34 +619,39 @@ int SliderWidget::posToValue(int pos) { #pragma mark - GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip) - : Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(256), _transparency(false) { + : Widget(boss, x, y, w, h, tooltip), _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) { setFlags(WIDGET_ENABLED | WIDGET_CLEARBG); _type = kGraphicsWidget; } GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip) - : Widget(boss, name, tooltip), _gfx(), _alpha(256), _transparency(false) { + : Widget(boss, name, tooltip), _gfx(new Graphics::Surface()), _alpha(256), _transparency(false) { setFlags(WIDGET_ENABLED | WIDGET_CLEARBG); _type = kGraphicsWidget; } GraphicsWidget::~GraphicsWidget() { - _gfx.free(); + _gfx->free(); + delete _gfx; } void GraphicsWidget::setGfx(const Graphics::Surface *gfx) { - _gfx.free(); + _gfx->free(); if (!gfx || !gfx->pixels) return; + if (gfx->format.bytesPerPixel == 1) { + warning("GraphicsWidget::setGfx got paletted surface passed"); + return; + } + if (gfx->w > _w || gfx->h > _h) { warning("GraphicsWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h); return; } - // TODO: add conversion to OverlayColor - _gfx.copyFrom(*gfx); + _gfx->copyFrom(*gfx); } void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { @@ -639,19 +660,29 @@ void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) { if (h == -1) h = _h; - Graphics::PixelFormat overlayFormat = g_system->getOverlayFormat(); + const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); - _gfx.free(); - _gfx.create(w, h, overlayFormat); - _gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b)); + _gfx->free(); + _gfx->create(w, h, requiredFormat); + _gfx->fillRect(Common::Rect(0, 0, w, h), _gfx->format.RGBToColor(r, g, b)); } void GraphicsWidget::drawWidget() { - if (sizeof(OverlayColor) == _gfx.format.bytesPerPixel && _gfx.pixels) { - const int x = _x + (_w - _gfx.w) / 2; - const int y = _y + (_h - _gfx.h) / 2; + if (_gfx->pixels) { + // Check whether the set up surface needs to be converted to the GUI + // color format. + const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat(); + if (_gfx->format != requiredFormat) { + Graphics::Surface *converted = _gfx->convertTo(requiredFormat); + _gfx->free(); + delete _gfx; + _gfx = converted; + } + + const int x = _x + (_w - _gfx->w) / 2; + const int y = _y + (_h - _gfx->h) / 2; - g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency); + g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx->w, y + _gfx->h), *_gfx, _state, _alpha, _transparency); } } diff --git a/gui/widget.h b/gui/widget.h index 6a6c67ced9..6de56862c3 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -227,7 +227,7 @@ public: protected: void drawWidget(); - Graphics::Surface _gfx; + Graphics::Surface *_gfx; int _alpha; bool _transparency; }; @@ -355,7 +355,7 @@ public: protected: void drawWidget(); - Graphics::Surface _gfx; + Graphics::Surface *_gfx; int _alpha; bool _transparency; }; -- cgit v1.2.3 From d99eb1e6141ba6dc33ca9f600267d4787a67db48 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Jun 2012 04:57:55 +0200 Subject: COMMON: Remove last traces of 8bpp overlay support from OSystem docs. --- common/system.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/common/system.h b/common/system.h index 976a3d2c4a..60c0e0f8ef 100644 --- a/common/system.h +++ b/common/system.h @@ -389,10 +389,7 @@ public: * graphics have a resolution of 320x200; then the overlay shall * have a resolution of 640x400, but it still has the same * physical size as the game graphics. - * The overlay usually uses 16bpp, but on some ports, only 8bpp - * are availble, so that is supported, too, via a compile time - * switch (see also the OverlayColor typedef in scummsys.h). - * + * The overlay is forced to a 16bpp mode right now. * * Finally, there is the mouse layer. This layer doesn't have to * actually exist within the backend -- it all depends on how a @@ -758,13 +755,11 @@ public: * In order to be able to display dialogs atop the game graphics, backends * must provide an overlay mode. * - * The overlay can be 8 or 16 bpp. Depending on which it is, OverlayColor - * is 8 or 16 bit. + * The overlay is currently forced at 16 bpp. * * For 'coolness' we usually want to have an overlay which is blended over * the game graphics. On backends which support alpha blending, this is - * no issue; but on other systems (in particular those which only support - * 8bpp), this needs some trickery. + * no issue; but on other systems this needs some trickery. * * Essentially, we fake (alpha) blending on these systems by copying the * current game graphics into the overlay buffer when activating the overlay, -- cgit v1.2.3 From 09ea48978a80e5148be74a7a5ffb2ff099e74ad7 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Jun 2012 05:06:58 +0200 Subject: COMMON: Remove traces of overlay scale from the OSystem documentation. --- common/system.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/common/system.h b/common/system.h index 60c0e0f8ef..97205846cb 100644 --- a/common/system.h +++ b/common/system.h @@ -380,15 +380,15 @@ public: * * * The next layer is the overlay. It is composed over the game - * graphics. By default, it has exactly the same size and - * resolution as the game graphics. However, client code can - * specify an overlay scale (as an additional parameter to - * initSize()). This is meant to increase the resolution of the - * overlay while keeping its size the same as that of the game - * graphics. For example, if the overlay scale is 2, and the game - * graphics have a resolution of 320x200; then the overlay shall - * have a resolution of 640x400, but it still has the same - * physical size as the game graphics. + * graphics. Historically the overlay size had always been a + * multiple of the game resolution, for example when the game + * resolution was 320x200 and the user selected a 2x scaler and did + * not enable aspect ratio correction it had a size of 640x400. + * An exception was the aspect ratio correction, which did allow + * for non multiples of the vertical resolution of the game screen. + * Nowadays the overlay size does not need to have any relation to + * the game resolution though, for example the overlay resolution + * might be the same as the physical screen resolution. * The overlay is forced to a 16bpp mode right now. * * Finally, there is the mouse layer. This layer doesn't have to -- cgit v1.2.3 From 51466ecfbb8158792931c27ff00c3bf937adfd40 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Jun 2012 05:09:02 +0200 Subject: COMMON: Remove traces of mouse cursor target scale from OSystem docs. --- common/system.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/common/system.h b/common/system.h index 97205846cb..94bf7f01eb 100644 --- a/common/system.h +++ b/common/system.h @@ -396,14 +396,6 @@ public: * backend chooses to implement mouse cursors, but in the default * SDL backend, it really is a separate layer. The mouse can * have a palette of its own, if the backend supports it. - * The scale of the mouse cursor is called 'cursorTargetScale'. - * This is meant as a hint to the backend. For example, let us - * assume the overlay is not visible, and the game graphics are - * displayed using a 2x scaler. If a mouse cursor with a - * cursorTargetScale of 1 is set, then it should be scaled by - * factor 2x, too, just like the game graphics. But if it has a - * cursorTargetScale of 2, then it shouldn't be scaled again by - * the game graphics scaler. * * On a note for OSystem users here. We do not require our graphics * to be thread safe and in fact most/all backends using OpenGL are -- cgit v1.2.3 From 04b6af91765ddf9d1c5c5ec6f9722795bf2e4f27 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 09:40:11 +0200 Subject: SWORD25: Janitorial: Apply coding conventions --- engines/sword25/gfx/image/art.cpp | 28 ++++++++++------------------ engines/sword25/gfx/image/art.h | 2 +- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/engines/sword25/gfx/image/art.cpp b/engines/sword25/gfx/image/art.cpp index 3944a207c8..9c4b9fe8bd 100644 --- a/engines/sword25/gfx/image/art.cpp +++ b/engines/sword25/gfx/image/art.cpp @@ -2367,38 +2367,30 @@ ArtSVPRenderAAIter *art_svp_render_aa_iter(const ArtSVP *svp, return iter; } -#define ADD_STEP(xpos, xdelta) \ +#define ADD_STEP(xpos, xdelta) \ /* stereotype code fragment for adding a step */ \ - if (n_steps == 0 || steps[n_steps - 1].x < xpos) \ - { \ + if (n_steps == 0 || steps[n_steps - 1].x < xpos) { \ sx = n_steps; \ steps[sx].x = xpos; \ steps[sx].delta = xdelta; \ n_steps++; \ - } \ - else \ - { \ - for (sx = n_steps; sx > 0; sx--) \ - { \ - if (steps[sx - 1].x == xpos) \ - { \ + } else { \ + for (sx = n_steps; sx > 0; sx--) { \ + if (steps[sx - 1].x == xpos) { \ steps[sx - 1].delta += xdelta; \ sx = n_steps; \ break; \ - } \ - else if (steps[sx - 1].x < xpos) \ - { \ + } else if (steps[sx - 1].x < xpos) { \ break; \ - } \ - } \ - if (sx < n_steps) \ - { \ + } \ + } \ + if (sx < n_steps) { \ memmove (&steps[sx + 1], &steps[sx], \ (n_steps - sx) * sizeof(steps[0])); \ steps[sx].x = xpos; \ steps[sx].delta = xdelta; \ n_steps++; \ - } \ + } \ } void art_svp_render_aa_iter_step(ArtSVPRenderAAIter *iter, int *p_start, diff --git a/engines/sword25/gfx/image/art.h b/engines/sword25/gfx/image/art.h index 8c9c97bc57..40bcb55aa7 100644 --- a/engines/sword25/gfx/image/art.h +++ b/engines/sword25/gfx/image/art.h @@ -50,7 +50,7 @@ namespace Sword25 { be variables. They can also be pstruct->el lvalues. */ #define art_expand(p, type, max) \ do { \ - if(max) {\ + if (max) {\ type *tmp = art_renew(p, type, max <<= 1); \ if (!tmp) error("Cannot reallocate memory for art data"); \ p = tmp; \ -- cgit v1.2.3 From f76c71d9682e193af3c852e27c3923950137445d Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 03:48:39 +0300 Subject: SCI: Add debug code to automatically skip robot videos --- engines/sci/engine/kvideo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sci/engine/kvideo.cpp b/engines/sci/engine/kvideo.cpp index c9cf652013..f176a13721 100644 --- a/engines/sci/engine/kvideo.cpp +++ b/engines/sci/engine/kvideo.cpp @@ -259,6 +259,7 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) { warning("kRobot(%d)", subop); break; case 8: // sync + //if (false) { // debug: automatically skip all robot videos if ((uint32)g_sci->_robotDecoder->getCurFrame() != g_sci->_robotDecoder->getFrameCount() - 1) { writeSelector(s->_segMan, argv[1], SELECTOR(signal), NULL_REG); } else { -- cgit v1.2.3 From aeac51d7263bf5233f3fb1f24d8a0789a9f8ca18 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 11:00:58 +0300 Subject: SCI: Implement the file operations needed for the save dialog in Phantasmagoria Phantasmagoria's scripts keep polling for the existence of the savegame index file and request to read and write it using the same parameters when opening it. The index file is closed and reopened for every save slot, which is slow and can be much slower on non-desktop devices. Also, the game scripts request seeking in writable streams and request to expand the existing index file. To provide this functionality and to reduce constant slow file opening and closing, this virtual class has been introduced --- engines/sci/engine/file.cpp | 139 ++++++++++++++++++++++++++++++++++++++ engines/sci/engine/file.h | 75 +++++++++++++++++++++ engines/sci/engine/kfile.cpp | 156 +++++++++++++++++++++++++++++++++---------- engines/sci/engine/state.cpp | 12 +++- engines/sci/engine/state.h | 5 ++ engines/sci/module.mk | 1 + 6 files changed, 351 insertions(+), 37 deletions(-) create mode 100644 engines/sci/engine/file.cpp create mode 100644 engines/sci/engine/file.h diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp new file mode 100644 index 0000000000..8876f3c46c --- /dev/null +++ b/engines/sci/engine/file.cpp @@ -0,0 +1,139 @@ +/* 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 "common/savefile.h" +#include "common/stream.h" + +#include "sci/sci.h" +#include "sci/engine/file.h" + +namespace Sci { + +#ifdef ENABLE_SCI32 + +VirtualIndexFile::VirtualIndexFile(Common::String fileName) : _fileName(fileName), _changed(false) { + Common::SeekableReadStream *inFile = g_sci->getSaveFileManager()->openForLoading(fileName); + + _bufferSize = inFile->size(); + _buffer = new char[_bufferSize]; + inFile->read(_buffer, _bufferSize); + _ptr = _buffer; + delete inFile; +} + +VirtualIndexFile::~VirtualIndexFile() { + close(); + + _bufferSize = 0; + delete[] _buffer; + _buffer = 0; +} + +uint32 VirtualIndexFile::read(char *buffer, uint32 size) { + uint32 curPos = _ptr - _buffer; + uint32 finalSize = MIN(size, _bufferSize - curPos); + char *localPtr = buffer; + + for (uint32 i = 0; i < finalSize; i++) + *localPtr++ = *_ptr++; + + return finalSize; +} + +uint32 VirtualIndexFile::write(const char *buffer, uint32 size) { + _changed = true; + uint32 curPos = _ptr - _buffer; + + // Check if the buffer needs to be resized + if (curPos + size >= _bufferSize) { + _bufferSize = curPos + size + 1; + char *tmp = _buffer; + _buffer = new char[_bufferSize]; + _ptr = _buffer + curPos; + memcpy(_buffer, tmp, _bufferSize); + delete[] tmp; + } + + for (uint32 i = 0; i < size; i++) + *_ptr++ = *buffer++; + + return size; +} + +uint32 VirtualIndexFile::readLine(char *buffer, uint32 size) { + uint32 startPos = _ptr - _buffer; + uint32 bytesRead = 0; + char *localPtr = buffer; + + // This is not a full-blown implementation of readLine, but it + // suffices for Phantasmagoria + while (startPos + bytesRead < size) { + bytesRead++; + + if (*_ptr == 0 || *_ptr == 0x0A) { + _ptr++; + *localPtr = 0; + return bytesRead; + } else { + *localPtr++ = *_ptr++; + } + } + + return bytesRead; +} + +bool VirtualIndexFile::seek(int32 offset, int whence) { + uint32 startPos = _ptr - _buffer; + assert(offset >= 0); + + switch (whence) { + case SEEK_CUR: + assert(startPos + offset < _bufferSize); + _ptr += offset; + break; + case SEEK_SET: + assert(offset < _bufferSize); + _ptr = _buffer + offset; + break; + case SEEK_END: + assert(_bufferSize - offset >= 0); + _ptr = _buffer + (_bufferSize - offset); + break; + } + + return true; +} + +void VirtualIndexFile::close() { + if (_changed) { + Common::WriteStream *outFile = g_sci->getSaveFileManager()->openForSaving(_fileName); + outFile->write(_buffer, _bufferSize); + delete outFile; + } + + // Maintain the buffer, and seek to the beginning of it + _ptr = _buffer; +} + +#endif + +} // End of namespace Sci diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h new file mode 100644 index 0000000000..e7b1090c91 --- /dev/null +++ b/engines/sci/engine/file.h @@ -0,0 +1,75 @@ +/* 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 SCI_ENGINE_FILE_H +#define SCI_ENGINE_FILE_H + +#include "common/scummsys.h" + +namespace Sci { + +#ifdef ENABLE_SCI32 + +/** + * An implementation of a virtual file that supports basic read and write + * operations simultaneously. + * + * This class has been initially implemented for Phantasmagoria, which has its + * own custom save/load code. The load code keeps checking for the existence + * of the save index file and keeps closing and reopening it for each save + * slot. This is notoriously slow and clumsy, and introduces noticeable delays, + * especially for non-desktop systems. Also, its game scripts request to open + * the index file for reading and writing with the same parameters + * (SaveManager::setCurrentSave and SaveManager::getCurrentSave). Moreover, + * the game scripts reopen the index file for writing in order to update it + * and seek within it. We do not support seeking in writeable streams, and the + * fact that our saved games are ZIP files makes this operation even more + * expensive. Finally, the savegame index file is supposed to be expanded when + * a new save slot is added. + * For the aforementioned reasons, this class has been implemented, which offers + * the basic functionality needed by the game scripts in Phantasmagoria. + */ +class VirtualIndexFile { +public: + VirtualIndexFile(Common::String fileName); + ~VirtualIndexFile(); + + uint32 read(char *buffer, uint32 size); + uint32 readLine(char *buffer, uint32 size); + uint32 write(const char *buffer, uint32 size); + bool seek(int32 offset, int whence); + void close(); + +private: + char *_buffer; + uint32 _bufferSize; + char *_ptr; + + Common::String _fileName; + bool _changed; +}; + +#endif + +} // End of namespace Sci + +#endif // SCI_ENGINE_FILE_H diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 42f8b8832c..0dd2296f41 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -33,6 +33,7 @@ #include "gui/saveload.h" #include "sci/sci.h" +#include "sci/engine/file.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" #include "sci/engine/savegame.h" @@ -72,8 +73,6 @@ struct SavegameDesc { * for reading only. */ - - FileHandle::FileHandle() : _in(0), _out(0) { } @@ -93,15 +92,14 @@ bool FileHandle::isOpen() const { return _in || _out; } - - enum { _K_FILE_MODE_OPEN_OR_CREATE = 0, _K_FILE_MODE_OPEN_OR_FAIL = 1, _K_FILE_MODE_CREATE = 2 }; - +#define VIRTUALFILE_HANDLE 200 +#define PHANTASMAGORIA_SAVEGAME_INDEX "phantsg.dir" reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) { Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH); @@ -130,6 +128,7 @@ reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool u outFile = saveFileMan->openForSaving(wrappedName); if (!outFile) debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); + // QfG1 opens the character export file with _K_FILE_MODE_CREATE first, // closes it immediately and opens it again with this here. Perhaps // other games use this for read access as well. I guess changing this @@ -171,8 +170,8 @@ reg_t kFOpen(EngineState *s, int argc, reg_t *argv) { } static FileHandle *getFileFromHandle(EngineState *s, uint handle) { - if (handle == 0) { - error("Attempt to use file handle 0"); + if (handle == 0 || handle == VIRTUALFILE_HANDLE) { + error("Attempt to use invalid file handle (%d)", handle); return 0; } @@ -738,6 +737,21 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) { reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); +#ifdef ENABLE_SCI32 + if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { + if (s->_virtualIndexFile) { + return make_reg(0, VIRTUALFILE_HANDLE); + } else { + Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH); + Common::String wrappedName = g_sci->wrapFilename(englishName); + if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) { + s->_virtualIndexFile = new VirtualIndexFile(wrappedName); + return make_reg(0, VIRTUALFILE_HANDLE); + } + } + } +#endif + // SCI32 can call K_FILEIO_OPEN with only one argument. It seems to // just be checking if it exists. int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16(); @@ -780,7 +794,16 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16()); - FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + uint16 handle = argv[0].toUint16(); + +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + s->_virtualIndexFile->close(); + return SIGNAL_REG; + } +#endif + + FileHandle *f = getFileFromHandle(s, handle); if (f) { f->close(); return SIGNAL_REG; @@ -789,39 +812,56 @@ reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { } reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) { - int handle = argv[0].toUint16(); - int size = argv[2].toUint16(); + uint16 handle = argv[0].toUint16(); + uint16 size = argv[2].toUint16(); int bytesRead = 0; char *buf = new char[size]; debugC(kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size); - FileHandle *f = getFileFromHandle(s, handle); - if (f) { - bytesRead = f->_in->read(buf, size); - // TODO: What happens if less bytes are read than what has - // been requested? (i.e. if bytesRead is non-zero, but still - // less than size) - if (bytesRead > 0) - s->_segMan->memcpy(argv[1], (const byte*)buf, size); +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + bytesRead = s->_virtualIndexFile->read(buf, size); + } else { +#endif + FileHandle *f = getFileFromHandle(s, handle); + if (f) + bytesRead = f->_in->read(buf, size); +#ifdef ENABLE_SCI32 } +#endif + + // TODO: What happens if less bytes are read than what has + // been requested? (i.e. if bytesRead is non-zero, but still + // less than size) + if (bytesRead > 0) + s->_segMan->memcpy(argv[1], (const byte*)buf, size); delete[] buf; return make_reg(0, bytesRead); } reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { - int handle = argv[0].toUint16(); - int size = argv[2].toUint16(); + uint16 handle = argv[0].toUint16(); + uint16 size = argv[2].toUint16(); char *buf = new char[size]; bool success = false; s->_segMan->memcpy((byte *)buf, argv[1], size); debugC(kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size); - FileHandle *f = getFileFromHandle(s, handle); - if (f) { - f->_out->write(buf, size); +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + s->_virtualIndexFile->write(buf, size); success = true; + } else { +#endif + FileHandle *f = getFileFromHandle(s, handle); + if (f) { + f->_out->write(buf, size); + success = true; + } +#ifdef ENABLE_SCI32 } +#endif delete[] buf; if (success) @@ -854,9 +894,19 @@ reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { name = g_sci->getSavegameName(savedir_nr); result = saveFileMan->removeSavefile(name); } else if (getSciVersion() >= SCI_VERSION_2) { - // We don't need to wrap the filename in SCI32 games, as it's already - // constructed here + // The file name may be already wrapped, so check both cases result = saveFileMan->removeSavefile(name); + if (!result) { + const Common::String wrappedName = g_sci->wrapFilename(name); + result = saveFileMan->removeSavefile(wrappedName); + } + +#ifdef ENABLE_SCI32 + if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { + delete s->_virtualIndexFile; + s->_virtualIndexFile = 0; + } +#endif } else { const Common::String wrappedName = g_sci->wrapFilename(name); result = saveFileMan->removeSavefile(wrappedName); @@ -869,15 +919,22 @@ reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { } reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { - int size = argv[1].toUint16(); + uint16 size = argv[1].toUint16(); char *buf = new char[size]; - int handle = argv[2].toUint16(); + uint16 handle = argv[2].toUint16(); debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size); + uint32 bytesRead; + +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) + bytesRead = s->_virtualIndexFile->readLine(buf, size); + else +#endif + bytesRead = fgets_wrapper(s, buf, size, handle); - int readBytes = fgets_wrapper(s, buf, size, handle); s->_segMan->memcpy(argv[0], (const byte*)buf, size); delete[] buf; - return readBytes ? argv[0] : NULL_REG; + return bytesRead ? argv[0] : NULL_REG; } reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { @@ -885,6 +942,13 @@ reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { Common::String str = s->_segMan->getString(argv[1]); debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle); +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + s->_virtualIndexFile->write(str.c_str(), str.size()); + return NULL_REG; + } +#endif + FileHandle *f = getFileFromHandle(s, handle); if (f) { @@ -896,15 +960,31 @@ reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { } reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { - int handle = argv[0].toUint16(); - int offset = argv[1].toUint16(); - int whence = argv[2].toUint16(); + uint16 handle = argv[0].toUint16(); + uint16 offset = ABS(argv[1].toSint16()); // can be negative + uint16 whence = argv[2].toUint16(); debugC(kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence); +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) + return make_reg(0, s->_virtualIndexFile->seek(offset, whence)); +#endif + FileHandle *f = getFileFromHandle(s, handle); - if (f) - s->r_acc = make_reg(0, f->_in->seek(offset, whence)); + if (f && f->_in) { + // Backward seeking isn't supported in zip file streams, thus adapt the + // parameters accordingly if games ask for such a seek mode. A known + // case where this is requested is the save file manager in Phantasmagoria + if (whence == SEEK_END) { + whence = SEEK_SET; + offset = f->_in->size() - offset; + } + + return make_reg(0, f->_in->seek(offset, whence)); + } else if (f && f->_out) { + error("kFileIOSeek: Unsupported seek operation on a writeable stream (offset: %d, whence: %d)", offset, whence); + } return SIGNAL_REG; } @@ -1027,6 +1107,14 @@ reg_t kFileIOFindNext(EngineState *s, int argc, reg_t *argv) { reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); +#ifdef ENABLE_SCI32 + // Cache the file existence result for the Phantasmagoria + // save index file, as the game scripts keep checking for + // its existence. + if (name == PHANTASMAGORIA_SAVEGAME_INDEX && s->_virtualIndexFile) + return TRUE_REG; +#endif + bool exists = false; // Check for regular file diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 28818cddef..237c6b54a6 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -26,6 +26,7 @@ #include "sci/debug.h" // for g_debug_sleeptime_factor #include "sci/event.h" +#include "sci/engine/file.h" #include "sci/engine/kernel.h" #include "sci/engine/state.h" #include "sci/engine/selector.h" @@ -68,21 +69,26 @@ static const uint16 s_halfWidthSJISMap[256] = { }; EngineState::EngineState(SegManager *segMan) -: _segMan(segMan), _dirseeker() { +: _segMan(segMan), +#ifdef ENABLE_SCI32 + _virtualIndexFile(0), +#endif + _dirseeker() { reset(false); } EngineState::~EngineState() { delete _msgState; +#ifdef ENABLE_SCI32 + delete _virtualIndexFile; +#endif } void EngineState::reset(bool isRestoring) { if (!isRestoring) { _memorySegmentSize = 0; - _fileHandles.resize(5); - abortScriptProcessing = kAbortNone; } diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index dcffe6dbb3..6f1f6a6bda 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -45,6 +45,7 @@ namespace Sci { class EventManager; class MessageState; class SoundCommandParser; +class VirtualIndexFile; enum AbortGameState { kAbortNone = 0, @@ -163,6 +164,10 @@ public: int16 _lastSaveVirtualId; // last virtual id fed to kSaveGame, if no kGetSaveFiles was called inbetween int16 _lastSaveNewId; // last newly created filename-id by kSaveGame +#ifdef ENABLE_SCI32 + VirtualIndexFile *_virtualIndexFile; +#endif + uint _chosenQfGImportItem; // Remembers the item selected in QfG import rooms bool _cursorWorkaroundActive; // ffs. GfxCursor::setPosition() diff --git a/engines/sci/module.mk b/engines/sci/module.mk index b6d5837b31..6b6058c819 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -10,6 +10,7 @@ MODULE_OBJS := \ sci.o \ util.o \ engine/features.o \ + engine/file.o \ engine/gc.o \ engine/kernel.o \ engine/kevent.o \ -- cgit v1.2.3 From a209359a678ea19935c875da96fbdb1015bcee74 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 11:02:00 +0300 Subject: SCI: Reorder the file kernel functions a bit --- engines/sci/engine/kfile.cpp | 82 ++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 0dd2296f41..dddbc2710e 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -869,6 +869,47 @@ reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 6); // DOS - invalid handle } +reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { + uint16 size = argv[1].toUint16(); + char *buf = new char[size]; + uint16 handle = argv[2].toUint16(); + debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size); + uint32 bytesRead; + +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) + bytesRead = s->_virtualIndexFile->readLine(buf, size); + else +#endif + bytesRead = fgets_wrapper(s, buf, size, handle); + + s->_segMan->memcpy(argv[0], (const byte*)buf, size); + delete[] buf; + return bytesRead ? argv[0] : NULL_REG; +} + +reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { + int handle = argv[0].toUint16(); + Common::String str = s->_segMan->getString(argv[1]); + debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle); + +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + s->_virtualIndexFile->write(str.c_str(), str.size()); + return NULL_REG; + } +#endif + + FileHandle *f = getFileFromHandle(s, handle); + + if (f) { + f->_out->write(str.c_str(), str.size()); + return NULL_REG; + } + + return make_reg(0, 6); // DOS - invalid handle +} + reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); @@ -918,47 +959,6 @@ reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 2); // DOS - file not found error code } -reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { - uint16 size = argv[1].toUint16(); - char *buf = new char[size]; - uint16 handle = argv[2].toUint16(); - debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size); - uint32 bytesRead; - -#ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) - bytesRead = s->_virtualIndexFile->readLine(buf, size); - else -#endif - bytesRead = fgets_wrapper(s, buf, size, handle); - - s->_segMan->memcpy(argv[0], (const byte*)buf, size); - delete[] buf; - return bytesRead ? argv[0] : NULL_REG; -} - -reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { - int handle = argv[0].toUint16(); - Common::String str = s->_segMan->getString(argv[1]); - debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle); - -#ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) { - s->_virtualIndexFile->write(str.c_str(), str.size()); - return NULL_REG; - } -#endif - - FileHandle *f = getFileFromHandle(s, handle); - - if (f) { - f->_out->write(str.c_str(), str.size()); - return NULL_REG; - } - - return make_reg(0, 6); // DOS - invalid handle -} - reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { uint16 handle = argv[0].toUint16(); uint16 offset = ABS(argv[1].toSint16()); // can be negative -- cgit v1.2.3 From 5a17ea058583fb0a3d00392b8e07b2a1f414fded Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 11:29:14 +0300 Subject: SCI: Move all file-related functions in file.* This way, there is a clear separation of the actual SCI kernel file functions and the file classes and wrappers of ScummVM --- engines/sci/console.cpp | 21 +++ engines/sci/engine/file.cpp | 308 +++++++++++++++++++++++++++++++++++++- engines/sci/engine/file.h | 66 ++++++++- engines/sci/engine/kernel.h | 3 - engines/sci/engine/kfile.cpp | 343 +------------------------------------------ engines/sci/engine/state.h | 43 +----- 6 files changed, 401 insertions(+), 383 deletions(-) diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 5b5301b468..6a44972a4b 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -1216,6 +1216,27 @@ bool Console::cmdRestartGame(int argc, const char **argv) { return Cmd_Exit(0, 0); } +// The scripts get IDs ranging from 100->199, because the scripts require us to assign unique ids THAT EVEN STAY BETWEEN +// SAVES and the scripts also use "saves-count + 1" to create a new savedgame slot. +// SCI1.1 actually recycles ids, in that case we will currently get "0". +// This behavior is required especially for LSL6. In this game, it's possible to quick save. The scripts will use +// the last-used id for that feature. If we don't assign sticky ids, the feature will overwrite different saves all the +// time. And sadly we can't just use the actual filename ids directly, because of the creation method for new slots. + +extern void listSavegames(Common::Array &saves); + +bool Console::cmdListSaves(int argc, const char **argv) { + Common::Array saves; + listSavegames(saves); + + for (uint i = 0; i < saves.size(); i++) { + Common::String filename = g_sci->getSavegameName(saves[i].id); + DebugPrintf("%s: '%s'\n", filename.c_str(), saves[i].name); + } + + return true; +} + bool Console::cmdClassTable(int argc, const char **argv) { DebugPrintf("Available classes (parse a parameter to filter the table by a specific class):\n"); diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp index 8876f3c46c..66f54d67df 100644 --- a/engines/sci/engine/file.cpp +++ b/engines/sci/engine/file.cpp @@ -25,9 +25,315 @@ #include "sci/sci.h" #include "sci/engine/file.h" +#include "sci/engine/kernel.h" +#include "sci/engine/savegame.h" +#include "sci/engine/selector.h" +#include "sci/engine/state.h" namespace Sci { +/* + * Note on how file I/O is implemented: In ScummVM, one can not create/write + * arbitrary data files, simply because many of our target platforms do not + * support this. The only files one can create are savestates. But SCI has an + * opcode to create and write to seemingly 'arbitrary' files. This is mainly + * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used + * for persisting the results of the "age quiz" across restarts) and in LSL5 + * for MEMORY.DRV (which is again a game data file and contains the game's + * password, XOR encrypted). + * To implement that opcode, we combine the SaveFileManager with regular file + * code, similarly to how the SCUMM HE engine does it. + * + * To handle opening a file called "foobar", what we do is this: First, we + * create an 'augmented file name', by prepending the game target and a dash, + * so if we running game target sq1sci, the name becomes "sq1sci-foobar". + * Next, we check if such a file is known to the SaveFileManager. If so, we + * we use that for reading/writing, delete it, whatever. + * + * If no such file is present but we were only asked to *read* the file, + * we fallback to looking for a regular file called "foobar", and open that + * for reading only. + */ + +reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) { + Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH); + Common::String wrappedName = unwrapFilename ? g_sci->wrapFilename(englishName) : englishName; + Common::SeekableReadStream *inFile = 0; + Common::WriteStream *outFile = 0; + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + + if (mode == _K_FILE_MODE_OPEN_OR_FAIL) { + // Try to open file, abort if not possible + inFile = saveFileMan->openForLoading(wrappedName); + // If no matching savestate exists: fall back to reading from a regular + // file + if (!inFile) + inFile = SearchMan.createReadStreamForMember(englishName); + + if (!inFile) + debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); + } else if (mode == _K_FILE_MODE_CREATE) { + // Create the file, destroying any content it might have had + outFile = saveFileMan->openForSaving(wrappedName); + if (!outFile) + debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); + } else if (mode == _K_FILE_MODE_OPEN_OR_CREATE) { + // Try to open file, create it if it doesn't exist + outFile = saveFileMan->openForSaving(wrappedName); + if (!outFile) + debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); + + // QfG1 opens the character export file with _K_FILE_MODE_CREATE first, + // closes it immediately and opens it again with this here. Perhaps + // other games use this for read access as well. I guess changing this + // whole code into using virtual files and writing them after close + // would be more appropriate. + } else { + error("file_open: unsupported mode %d (filename '%s')", mode, englishName.c_str()); + } + + if (!inFile && !outFile) { // Failed + debugC(kDebugLevelFile, " -> file_open() failed"); + return SIGNAL_REG; + } + + // Find a free file handle + uint handle = 1; // Ignore _fileHandles[0] + while ((handle < s->_fileHandles.size()) && s->_fileHandles[handle].isOpen()) + handle++; + + if (handle == s->_fileHandles.size()) { + // Hit size limit => Allocate more space + s->_fileHandles.resize(s->_fileHandles.size() + 1); + } + + s->_fileHandles[handle]._in = inFile; + s->_fileHandles[handle]._out = outFile; + s->_fileHandles[handle]._name = englishName; + + debugC(kDebugLevelFile, " -> opened file '%s' with handle %d", englishName.c_str(), handle); + return make_reg(0, handle); +} + +FileHandle *getFileFromHandle(EngineState *s, uint handle) { + if (handle == 0 || handle == VIRTUALFILE_HANDLE) { + error("Attempt to use invalid file handle (%d)", handle); + return 0; + } + + if ((handle >= s->_fileHandles.size()) || !s->_fileHandles[handle].isOpen()) { + warning("Attempt to use invalid/unused file handle %d", handle); + return 0; + } + + return &s->_fileHandles[handle]; +} + +int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle) { + FileHandle *f = getFileFromHandle(s, handle); + if (!f) + return 0; + + if (!f->_in) { + error("fgets_wrapper: Trying to read from file '%s' opened for writing", f->_name.c_str()); + return 0; + } + int readBytes = 0; + if (maxsize > 1) { + memset(dest, 0, maxsize); + f->_in->readLine(dest, maxsize); + readBytes = strlen(dest); // FIXME: sierra sci returned byte count and didn't react on NUL characters + // The returned string must not have an ending LF + if (readBytes > 0) { + if (dest[readBytes - 1] == 0x0A) + dest[readBytes - 1] = 0; + } + } else { + *dest = 0; + } + + debugC(kDebugLevelFile, " -> FGets'ed \"%s\"", dest); + return readBytes; +} + +static bool _savegame_sort_byDate(const SavegameDesc &l, const SavegameDesc &r) { + if (l.date != r.date) + return (l.date > r.date); + return (l.time > r.time); +} + +// Create a sorted array containing all found savedgames +void listSavegames(Common::Array &saves) { + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + + // Load all saves + Common::StringArray saveNames = saveFileMan->listSavefiles(g_sci->getSavegamePattern()); + + for (Common::StringArray::const_iterator iter = saveNames.begin(); iter != saveNames.end(); ++iter) { + Common::String filename = *iter; + Common::SeekableReadStream *in; + if ((in = saveFileMan->openForLoading(filename))) { + SavegameMetadata meta; + if (!get_savegame_metadata(in, &meta) || meta.name.empty()) { + // invalid + delete in; + continue; + } + delete in; + + SavegameDesc desc; + desc.id = strtol(filename.end() - 3, NULL, 10); + desc.date = meta.saveDate; + // We need to fix date in here, because we save DDMMYYYY instead of + // YYYYMMDD, so sorting wouldn't work + desc.date = ((desc.date & 0xFFFF) << 16) | ((desc.date & 0xFF0000) >> 8) | ((desc.date & 0xFF000000) >> 24); + desc.time = meta.saveTime; + desc.version = meta.version; + + if (meta.name.lastChar() == '\n') + meta.name.deleteLastChar(); + + Common::strlcpy(desc.name, meta.name.c_str(), SCI_MAX_SAVENAME_LENGTH); + + debug(3, "Savegame in file %s ok, id %d", filename.c_str(), desc.id); + + saves.push_back(desc); + } + } + + // Sort the list by creation date of the saves + Common::sort(saves.begin(), saves.end(), _savegame_sort_byDate); +} + +// Find a savedgame according to virtualId and return the position within our array +int findSavegame(Common::Array &saves, int16 savegameId) { + for (uint saveNr = 0; saveNr < saves.size(); saveNr++) { + if (saves[saveNr].id == savegameId) + return saveNr; + } + return -1; +} + + +FileHandle::FileHandle() : _in(0), _out(0) { +} + +FileHandle::~FileHandle() { + close(); +} + +void FileHandle::close() { + delete _in; + delete _out; + _in = 0; + _out = 0; + _name.clear(); +} + +bool FileHandle::isOpen() const { + return _in || _out; +} + + +void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask) { + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask); + if (!foundFiles.empty()) { + _files.push_back(title); + _virtualFiles.push_back(""); + Common::StringArray::iterator it; + Common::StringArray::iterator it_end = foundFiles.end(); + + for (it = foundFiles.begin(); it != it_end; it++) { + Common::String regularFilename = *it; + Common::String wrappedFilename = Common::String(regularFilename.c_str() + fileMask.size() - 1); + + Common::SeekableReadStream *testfile = saveFileMan->openForLoading(regularFilename); + int32 testfileSize = testfile->size(); + delete testfile; + if (testfileSize > 1024) // check, if larger than 1k. in that case its a saved game. + continue; // and we dont want to have those in the list + // We need to remove the prefix for display purposes + _files.push_back(wrappedFilename); + // but remember the actual name as well + _virtualFiles.push_back(regularFilename); + } + } +} + +Common::String DirSeeker::getVirtualFilename(uint fileNumber) { + if (fileNumber >= _virtualFiles.size()) + error("invalid virtual filename access"); + return _virtualFiles[fileNumber]; +} + +reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) { + // Verify that we are given a valid buffer + if (!buffer.segment) { + error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str()); + return NULL_REG; + } + _outbuffer = buffer; + _files.clear(); + _virtualFiles.clear(); + + int QfGImport = g_sci->inQfGImportRoom(); + if (QfGImport) { + _files.clear(); + addAsVirtualFiles("-QfG1-", "qfg1-*"); + addAsVirtualFiles("-QfG1VGA-", "qfg1vga-*"); + if (QfGImport > 2) + addAsVirtualFiles("-QfG2-", "qfg2-*"); + if (QfGImport > 3) + addAsVirtualFiles("-QfG3-", "qfg3-*"); + + if (QfGImport == 3) { + // QfG3 sorts the filelisting itself, we can't let that happen otherwise our + // virtual list would go out-of-sync + reg_t savedHeros = segMan->findObjectByName("savedHeros"); + if (!savedHeros.isNull()) + writeSelectorValue(segMan, savedHeros, SELECTOR(sort), 0); + } + + } else { + // Prefix the mask + const Common::String wrappedMask = g_sci->wrapFilename(mask); + + // Obtain a list of all files matching the given mask + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + _files = saveFileMan->listSavefiles(wrappedMask); + } + + // Reset the list iterator and write the first match to the output buffer, + // if any. + _iter = _files.begin(); + return nextFile(segMan); +} + +reg_t DirSeeker::nextFile(SegManager *segMan) { + if (_iter == _files.end()) { + return NULL_REG; + } + + Common::String string; + + if (_virtualFiles.empty()) { + // Strip the prefix, if we don't got a virtual filelisting + const Common::String wrappedString = *_iter; + string = g_sci->unwrapFilename(wrappedString); + } else { + string = *_iter; + } + if (string.size() > 12) + string = Common::String(string.c_str(), 12); + segMan->strcpy(_outbuffer, string.c_str()); + + // Return the result and advance the list iterator :) + ++_iter; + return _outbuffer; +} + + #ifdef ENABLE_SCI32 VirtualIndexFile::VirtualIndexFile(Common::String fileName) : _fileName(fileName), _changed(false) { @@ -111,7 +417,7 @@ bool VirtualIndexFile::seek(int32 offset, int whence) { _ptr += offset; break; case SEEK_SET: - assert(offset < _bufferSize); + assert(offset < (int32)_bufferSize); _ptr = _buffer + offset; break; case SEEK_END: diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h index e7b1090c91..896dcd2a42 100644 --- a/engines/sci/engine/file.h +++ b/engines/sci/engine/file.h @@ -23,10 +23,74 @@ #ifndef SCI_ENGINE_FILE_H #define SCI_ENGINE_FILE_H -#include "common/scummsys.h" +#include "common/str-array.h" +#include "common/stream.h" namespace Sci { +enum { + _K_FILE_MODE_OPEN_OR_CREATE = 0, + _K_FILE_MODE_OPEN_OR_FAIL = 1, + _K_FILE_MODE_CREATE = 2 +}; + +/* Maximum length of a savegame name (including terminator character). */ +#define SCI_MAX_SAVENAME_LENGTH 0x24 + +enum { + MAX_SAVEGAME_NR = 20 /**< Maximum number of savegames */ +}; + +#define VIRTUALFILE_HANDLE 200 +#define PHANTASMAGORIA_SAVEGAME_INDEX "phantsg.dir" + +struct SavegameDesc { + int16 id; + int virtualId; // straight numbered, according to id but w/o gaps + int date; + int time; + int version; + char name[SCI_MAX_SAVENAME_LENGTH]; +}; + +class FileHandle { +public: + Common::String _name; + Common::SeekableReadStream *_in; + Common::WriteStream *_out; + +public: + FileHandle(); + ~FileHandle(); + + void close(); + bool isOpen() const; +}; + + +class DirSeeker { +protected: + reg_t _outbuffer; + Common::StringArray _files; + Common::StringArray _virtualFiles; + Common::StringArray::const_iterator _iter; + +public: + DirSeeker() { + _outbuffer = NULL_REG; + _iter = _files.begin(); + } + + reg_t firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan); + reg_t nextFile(SegManager *segMan); + + Common::String getVirtualFilename(uint fileNumber); + +private: + void addAsVirtualFiles(Common::String title, Common::String fileMask); +}; + + #ifdef ENABLE_SCI32 /** diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index d9fdbefbc2..25ca082a9a 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -276,9 +276,6 @@ private: const Common::String _invalid; }; -/* Maximum length of a savegame name (including terminator character). */ -#define SCI_MAX_SAVENAME_LENGTH 0x24 - /******************** Kernel functions ********************/ reg_t kStrLen(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index dddbc2710e..36e5273b06 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -41,125 +41,11 @@ namespace Sci { -struct SavegameDesc { - int16 id; - int virtualId; // straight numbered, according to id but w/o gaps - int date; - int time; - int version; - char name[SCI_MAX_SAVENAME_LENGTH]; -}; - -/* - * Note on how file I/O is implemented: In ScummVM, one can not create/write - * arbitrary data files, simply because many of our target platforms do not - * support this. The only files one can create are savestates. But SCI has an - * opcode to create and write to seemingly 'arbitrary' files. This is mainly - * used in LSL3 for LARRY3.DRV (which is a game data file, not a driver, used - * for persisting the results of the "age quiz" across restarts) and in LSL5 - * for MEMORY.DRV (which is again a game data file and contains the game's - * password, XOR encrypted). - * To implement that opcode, we combine the SaveFileManager with regular file - * code, similarly to how the SCUMM HE engine does it. - * - * To handle opening a file called "foobar", what we do is this: First, we - * create an 'augmented file name', by prepending the game target and a dash, - * so if we running game target sq1sci, the name becomes "sq1sci-foobar". - * Next, we check if such a file is known to the SaveFileManager. If so, we - * we use that for reading/writing, delete it, whatever. - * - * If no such file is present but we were only asked to *read* the file, - * we fallback to looking for a regular file called "foobar", and open that - * for reading only. - */ - -FileHandle::FileHandle() : _in(0), _out(0) { -} - -FileHandle::~FileHandle() { - close(); -} - -void FileHandle::close() { - delete _in; - delete _out; - _in = 0; - _out = 0; - _name.clear(); -} - -bool FileHandle::isOpen() const { - return _in || _out; -} - -enum { - _K_FILE_MODE_OPEN_OR_CREATE = 0, - _K_FILE_MODE_OPEN_OR_FAIL = 1, - _K_FILE_MODE_CREATE = 2 -}; - -#define VIRTUALFILE_HANDLE 200 -#define PHANTASMAGORIA_SAVEGAME_INDEX "phantsg.dir" - -reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename) { - Common::String englishName = g_sci->getSciLanguageString(filename, K_LANG_ENGLISH); - Common::String wrappedName = unwrapFilename ? g_sci->wrapFilename(englishName) : englishName; - Common::SeekableReadStream *inFile = 0; - Common::WriteStream *outFile = 0; - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - - if (mode == _K_FILE_MODE_OPEN_OR_FAIL) { - // Try to open file, abort if not possible - inFile = saveFileMan->openForLoading(wrappedName); - // If no matching savestate exists: fall back to reading from a regular - // file - if (!inFile) - inFile = SearchMan.createReadStreamForMember(englishName); - - if (!inFile) - debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_OPEN_OR_FAIL): failed to open file '%s'", englishName.c_str()); - } else if (mode == _K_FILE_MODE_CREATE) { - // Create the file, destroying any content it might have had - outFile = saveFileMan->openForSaving(wrappedName); - if (!outFile) - debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); - } else if (mode == _K_FILE_MODE_OPEN_OR_CREATE) { - // Try to open file, create it if it doesn't exist - outFile = saveFileMan->openForSaving(wrappedName); - if (!outFile) - debugC(kDebugLevelFile, " -> file_open(_K_FILE_MODE_CREATE): failed to create file '%s'", englishName.c_str()); - - // QfG1 opens the character export file with _K_FILE_MODE_CREATE first, - // closes it immediately and opens it again with this here. Perhaps - // other games use this for read access as well. I guess changing this - // whole code into using virtual files and writing them after close - // would be more appropriate. - } else { - error("file_open: unsupported mode %d (filename '%s')", mode, englishName.c_str()); - } - - if (!inFile && !outFile) { // Failed - debugC(kDebugLevelFile, " -> file_open() failed"); - return SIGNAL_REG; - } - - // Find a free file handle - uint handle = 1; // Ignore _fileHandles[0] - while ((handle < s->_fileHandles.size()) && s->_fileHandles[handle].isOpen()) - handle++; - - if (handle == s->_fileHandles.size()) { - // Hit size limit => Allocate more space - s->_fileHandles.resize(s->_fileHandles.size() + 1); - } - - s->_fileHandles[handle]._in = inFile; - s->_fileHandles[handle]._out = outFile; - s->_fileHandles[handle]._name = englishName; - - debugC(kDebugLevelFile, " -> opened file '%s' with handle %d", englishName.c_str(), handle); - return make_reg(0, handle); -} +extern reg_t file_open(EngineState *s, const Common::String &filename, int mode, bool unwrapFilename); +extern FileHandle *getFileFromHandle(EngineState *s, uint handle); +extern int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle); +extern void listSavegames(Common::Array &saves); +extern int findSavegame(Common::Array &saves, int16 savegameId); reg_t kFOpen(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); @@ -169,20 +55,6 @@ reg_t kFOpen(EngineState *s, int argc, reg_t *argv) { return file_open(s, name, mode, true); } -static FileHandle *getFileFromHandle(EngineState *s, uint handle) { - if (handle == 0 || handle == VIRTUALFILE_HANDLE) { - error("Attempt to use invalid file handle (%d)", handle); - return 0; - } - - if ((handle >= s->_fileHandles.size()) || !s->_fileHandles[handle].isOpen()) { - warning("Attempt to use invalid/unused file handle %d", handle); - return 0; - } - - return &s->_fileHandles[handle]; -} - reg_t kFClose(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelFile, "kFClose(%d)", argv[0].toUint16()); if (argv[0] != SIGNAL_REG) { @@ -204,33 +76,6 @@ reg_t kFPuts(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -static int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle) { - FileHandle *f = getFileFromHandle(s, handle); - if (!f) - return 0; - - if (!f->_in) { - error("fgets_wrapper: Trying to read from file '%s' opened for writing", f->_name.c_str()); - return 0; - } - int readBytes = 0; - if (maxsize > 1) { - memset(dest, 0, maxsize); - f->_in->readLine(dest, maxsize); - readBytes = strlen(dest); // FIXME: sierra sci returned byte count and didn't react on NUL characters - // The returned string must not have an ending LF - if (readBytes > 0) { - if (dest[readBytes - 1] == 0x0A) - dest[readBytes - 1] = 0; - } - } else { - *dest = 0; - } - - debugC(kDebugLevelFile, " -> FGets'ed \"%s\"", dest); - return readBytes; -} - reg_t kFGets(EngineState *s, int argc, reg_t *argv) { int maxsize = argv[1].toUint16(); char *buf = new char[maxsize]; @@ -257,9 +102,6 @@ reg_t kGetCWD(EngineState *s, int argc, reg_t *argv) { return argv[0]; } -static void listSavegames(Common::Array &saves); -static int findSavegame(Common::Array &saves, int16 saveId); - enum { K_DEVICE_INFO_GET_DEVICE = 0, K_DEVICE_INFO_GET_CURRENT_DEVICE = 1, @@ -393,83 +235,6 @@ reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 1); } -static bool _savegame_sort_byDate(const SavegameDesc &l, const SavegameDesc &r) { - if (l.date != r.date) - return (l.date > r.date); - return (l.time > r.time); -} - -// Create a sorted array containing all found savedgames -static void listSavegames(Common::Array &saves) { - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - - // Load all saves - Common::StringArray saveNames = saveFileMan->listSavefiles(g_sci->getSavegamePattern()); - - for (Common::StringArray::const_iterator iter = saveNames.begin(); iter != saveNames.end(); ++iter) { - Common::String filename = *iter; - Common::SeekableReadStream *in; - if ((in = saveFileMan->openForLoading(filename))) { - SavegameMetadata meta; - if (!get_savegame_metadata(in, &meta) || meta.name.empty()) { - // invalid - delete in; - continue; - } - delete in; - - SavegameDesc desc; - desc.id = strtol(filename.end() - 3, NULL, 10); - desc.date = meta.saveDate; - // We need to fix date in here, because we save DDMMYYYY instead of - // YYYYMMDD, so sorting wouldn't work - desc.date = ((desc.date & 0xFFFF) << 16) | ((desc.date & 0xFF0000) >> 8) | ((desc.date & 0xFF000000) >> 24); - desc.time = meta.saveTime; - desc.version = meta.version; - - if (meta.name.lastChar() == '\n') - meta.name.deleteLastChar(); - - Common::strlcpy(desc.name, meta.name.c_str(), SCI_MAX_SAVENAME_LENGTH); - - debug(3, "Savegame in file %s ok, id %d", filename.c_str(), desc.id); - - saves.push_back(desc); - } - } - - // Sort the list by creation date of the saves - Common::sort(saves.begin(), saves.end(), _savegame_sort_byDate); -} - -// Find a savedgame according to virtualId and return the position within our array -static int findSavegame(Common::Array &saves, int16 savegameId) { - for (uint saveNr = 0; saveNr < saves.size(); saveNr++) { - if (saves[saveNr].id == savegameId) - return saveNr; - } - return -1; -} - -// The scripts get IDs ranging from 100->199, because the scripts require us to assign unique ids THAT EVEN STAY BETWEEN -// SAVES and the scripts also use "saves-count + 1" to create a new savedgame slot. -// SCI1.1 actually recycles ids, in that case we will currently get "0". -// This behavior is required especially for LSL6. In this game, it's possible to quick save. The scripts will use -// the last-used id for that feature. If we don't assign sticky ids, the feature will overwrite different saves all the -// time. And sadly we can't just use the actual filename ids directly, because of the creation method for new slots. - -bool Console::cmdListSaves(int argc, const char **argv) { - Common::Array saves; - listSavegames(saves); - - for (uint i = 0; i < saves.size(); i++) { - Common::String filename = g_sci->getSavegameName(saves[i].id); - DebugPrintf("%s: '%s'\n", filename.c_str(), saves[i].name); - } - - return true; -} - reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) { Common::String game_id = s->_segMan->getString(argv[0]); uint16 virtualId = argv[1].toUint16(); @@ -989,104 +754,6 @@ reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { return SIGNAL_REG; } -void DirSeeker::addAsVirtualFiles(Common::String title, Common::String fileMask) { - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - Common::StringArray foundFiles = saveFileMan->listSavefiles(fileMask); - if (!foundFiles.empty()) { - _files.push_back(title); - _virtualFiles.push_back(""); - Common::StringArray::iterator it; - Common::StringArray::iterator it_end = foundFiles.end(); - - for (it = foundFiles.begin(); it != it_end; it++) { - Common::String regularFilename = *it; - Common::String wrappedFilename = Common::String(regularFilename.c_str() + fileMask.size() - 1); - - Common::SeekableReadStream *testfile = saveFileMan->openForLoading(regularFilename); - int32 testfileSize = testfile->size(); - delete testfile; - if (testfileSize > 1024) // check, if larger than 1k. in that case its a saved game. - continue; // and we dont want to have those in the list - // We need to remove the prefix for display purposes - _files.push_back(wrappedFilename); - // but remember the actual name as well - _virtualFiles.push_back(regularFilename); - } - } -} - -Common::String DirSeeker::getVirtualFilename(uint fileNumber) { - if (fileNumber >= _virtualFiles.size()) - error("invalid virtual filename access"); - return _virtualFiles[fileNumber]; -} - -reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) { - // Verify that we are given a valid buffer - if (!buffer.segment) { - error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str()); - return NULL_REG; - } - _outbuffer = buffer; - _files.clear(); - _virtualFiles.clear(); - - int QfGImport = g_sci->inQfGImportRoom(); - if (QfGImport) { - _files.clear(); - addAsVirtualFiles("-QfG1-", "qfg1-*"); - addAsVirtualFiles("-QfG1VGA-", "qfg1vga-*"); - if (QfGImport > 2) - addAsVirtualFiles("-QfG2-", "qfg2-*"); - if (QfGImport > 3) - addAsVirtualFiles("-QfG3-", "qfg3-*"); - - if (QfGImport == 3) { - // QfG3 sorts the filelisting itself, we can't let that happen otherwise our - // virtual list would go out-of-sync - reg_t savedHeros = segMan->findObjectByName("savedHeros"); - if (!savedHeros.isNull()) - writeSelectorValue(segMan, savedHeros, SELECTOR(sort), 0); - } - - } else { - // Prefix the mask - const Common::String wrappedMask = g_sci->wrapFilename(mask); - - // Obtain a list of all files matching the given mask - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - _files = saveFileMan->listSavefiles(wrappedMask); - } - - // Reset the list iterator and write the first match to the output buffer, - // if any. - _iter = _files.begin(); - return nextFile(segMan); -} - -reg_t DirSeeker::nextFile(SegManager *segMan) { - if (_iter == _files.end()) { - return NULL_REG; - } - - Common::String string; - - if (_virtualFiles.empty()) { - // Strip the prefix, if we don't got a virtual filelisting - const Common::String wrappedString = *_iter; - string = g_sci->unwrapFilename(wrappedString); - } else { - string = *_iter; - } - if (string.size() > 12) - string = Common::String(string.c_str(), 12); - segMan->strcpy(_outbuffer, string.c_str()); - - // Return the result and advance the list iterator :) - ++_iter; - return _outbuffer; -} - reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv) { Common::String mask = s->_segMan->getString(argv[0]); reg_t buf = argv[1]; diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 6f1f6a6bda..78a8a5b0a2 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -34,6 +34,7 @@ class WriteStream; } #include "sci/sci.h" +#include "sci/engine/file.h" #include "sci/engine/seg_manager.h" #include "sci/parser/vocabulary.h" @@ -42,6 +43,8 @@ class WriteStream; namespace Sci { +class FileHandle; +class DirSeeker; class EventManager; class MessageState; class SoundCommandParser; @@ -54,32 +57,6 @@ enum AbortGameState { kAbortQuitGame = 3 }; -class DirSeeker { -protected: - reg_t _outbuffer; - Common::StringArray _files; - Common::StringArray _virtualFiles; - Common::StringArray::const_iterator _iter; - -public: - DirSeeker() { - _outbuffer = NULL_REG; - _iter = _files.begin(); - } - - reg_t firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan); - reg_t nextFile(SegManager *segMan); - - Common::String getVirtualFilename(uint fileNumber); - -private: - void addAsVirtualFiles(Common::String title, Common::String fileMask); -}; - -enum { - MAX_SAVEGAME_NR = 20 /**< Maximum number of savegames */ -}; - // We assume that scripts give us savegameId 0->99 for creating a new save slot // and savegameId 100->199 for existing save slots ffs. kfile.cpp enum { @@ -93,20 +70,6 @@ enum { GAMEISRESTARTING_RESTORE = 2 }; -class FileHandle { -public: - Common::String _name; - Common::SeekableReadStream *_in; - Common::WriteStream *_out; - -public: - FileHandle(); - ~FileHandle(); - - void close(); - bool isOpen() const; -}; - enum VideoFlags { kNone = 0, kDoubled = 1 << 0, -- cgit v1.2.3 From 944a774e6a7fd604b0754569007e5e34d1be915f Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 11:56:13 +0300 Subject: SCI: Change kSave() to be a kernel function with subops --- engines/sci/engine/kernel.h | 1 + engines/sci/engine/kernel_tables.h | 14 ++++++++++++- engines/sci/engine/kfile.cpp | 42 +++++++++++++------------------------- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 25ca082a9a..d64bc42841 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -461,6 +461,7 @@ reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv); // SCI2.1 Kernel Functions reg_t kText(EngineState *s, int argc, reg_t *argv); reg_t kSave(EngineState *s, int argc, reg_t *argv); +reg_t kAutoSave(EngineState *s, int argc, reg_t *argv); reg_t kList(EngineState *s, int argc, reg_t *argv); reg_t kRobot(EngineState *s, int argc, reg_t *argv); reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 9b765283ec..cdc810eef0 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -245,6 +245,18 @@ static const SciKernelMapSubEntry kFileIO_subops[] = { SCI_SUBOPENTRY_TERMINATOR }; +static const SciKernelMapSubEntry kSave_subops[] = { + { SIG_SCI32, 0, MAP_CALL(SaveGame), "[r0]i[r0](r)", NULL }, + { SIG_SCI32, 1, MAP_CALL(RestoreGame), "[r0]i[r0]", NULL }, + { SIG_SCI32, 2, MAP_CALL(GetSaveDir), "(r*)", NULL }, + { SIG_SCI32, 3, MAP_CALL(CheckSaveGame), ".*", NULL }, + // Subop 4 hasn't been encountered yet + { SIG_SCI32, 5, MAP_CALL(GetSaveFiles), "rrr", NULL }, + { SIG_SCI32, 6, MAP_CALL(MakeSaveCatName), "rr", NULL }, + { SIG_SCI32, 7, MAP_CALL(MakeSaveFileName), "rri", NULL }, + { SIG_SCI32, 8, MAP_CALL(AutoSave), "[o0]", NULL }, +}; + #ifdef ENABLE_SCI32 // version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kList_subops[] = { @@ -555,7 +567,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL }, { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(Save), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Save), SIG_EVERYWHERE, "i(.*)", kSave_subops, NULL }, { MAP_CALL(Text), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii", NULL, NULL }, { MAP_CALL(GetWindowsOption), SIG_EVERYWHERE, "i", NULL, NULL }, diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 36e5273b06..fe54987e47 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -946,35 +946,21 @@ reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv) { return argv[0]; } +reg_t kAutoSave(EngineState *s, int argc, reg_t *argv) { + // TODO + // This is a timer callback, with 1 parameter: the timer object + // (e.g. "timers"). + // It's used for auto-saving (i.e. save every X minutes, by checking + // the elapsed time from the timer object) + + // This function has to return something other than 0 to proceed + return s->r_acc; +} + reg_t kSave(EngineState *s, int argc, reg_t *argv) { - switch (argv[0].toUint16()) { - case 0: - return kSaveGame(s, argc - 1,argv + 1); - case 1: - return kRestoreGame(s, argc - 1,argv + 1); - case 2: - return kGetSaveDir(s, argc - 1, argv + 1); - case 3: - return kCheckSaveGame(s, argc - 1, argv + 1); - case 5: - return kGetSaveFiles(s, argc - 1, argv + 1); - case 6: - return kMakeSaveCatName(s, argc - 1, argv + 1); - case 7: - return kMakeSaveFileName(s, argc - 1, argv + 1); - case 8: - // TODO - // This is a timer callback, with 1 parameter: the timer object - // (e.g. "timers"). - // It's used for auto-saving (i.e. save every X minutes, by checking - // the elapsed time from the timer object) - - // This function has to return something other than 0 to proceed - return s->r_acc; - default: - kStub(s, argc, argv); - return NULL_REG; - } + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); } #endif -- cgit v1.2.3 From 098f162ecc4951873909e9815506d4053178b6f9 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 12:19:18 +0300 Subject: SCI: Use the later SCI file functions for the SCI0 ones They are essentially the same (with the exception of the return values), so unifying them reduces code duplication --- engines/sci/engine/kernel.h | 4 --- engines/sci/engine/kernel_tables.h | 8 ++--- engines/sci/engine/kfile.cpp | 65 +++++++++++--------------------------- 3 files changed, 22 insertions(+), 55 deletions(-) diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index d64bc42841..677b790f93 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -323,10 +323,6 @@ reg_t kTimesCot(EngineState *s, int argc, reg_t *argv); reg_t kCosDiv(EngineState *s, int argc, reg_t *argv); reg_t kSinDiv(EngineState *s, int argc, reg_t *argv); reg_t kValidPath(EngineState *s, int argc, reg_t *argv); -reg_t kFOpen(EngineState *s, int argc, reg_t *argv); -reg_t kFPuts(EngineState *s, int argc, reg_t *argv); -reg_t kFGets(EngineState *s, int argc, reg_t *argv); -reg_t kFClose(EngineState *s, int argc, reg_t *argv); reg_t kMapKeyToDir(EngineState *s, int argc, reg_t *argv); reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv); reg_t kLocalToGlobal(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index cdc810eef0..d093310139 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -350,10 +350,10 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(EditControl), SIG_EVERYWHERE, "[o0][o0]", NULL, NULL }, { MAP_CALL(Empty), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(EmptyList), SIG_EVERYWHERE, "l", NULL, NULL }, - { MAP_CALL(FClose), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(FGets), SIG_EVERYWHERE, "rii", NULL, NULL }, - { MAP_CALL(FOpen), SIG_EVERYWHERE, "ri", NULL, NULL }, - { MAP_CALL(FPuts), SIG_EVERYWHERE, "ir", NULL, NULL }, + { "FClose", kFileIOClose, SIG_EVERYWHERE, "i", NULL, NULL }, + { "FGets", kFileIOReadString, SIG_EVERYWHERE, "rii", NULL, NULL }, + { "FOpen", kFileIOOpen, SIG_EVERYWHERE, "ri", NULL, NULL }, + { "FPuts", kFileIOWriteString, SIG_EVERYWHERE, "ir", NULL, NULL }, { MAP_CALL(FileIO), SIG_EVERYWHERE, "i(.*)", kFileIO_subops, NULL }, { MAP_CALL(FindKey), SIG_EVERYWHERE, "l.", NULL, kFindKey_workarounds }, { MAP_CALL(FirstNode), SIG_EVERYWHERE, "[l0]", NULL, NULL }, diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index fe54987e47..052332957b 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -47,47 +47,6 @@ extern int fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle); extern void listSavegames(Common::Array &saves); extern int findSavegame(Common::Array &saves, int16 savegameId); -reg_t kFOpen(EngineState *s, int argc, reg_t *argv) { - Common::String name = s->_segMan->getString(argv[0]); - int mode = argv[1].toUint16(); - - debugC(kDebugLevelFile, "kFOpen(%s,0x%x)", name.c_str(), mode); - return file_open(s, name, mode, true); -} - -reg_t kFClose(EngineState *s, int argc, reg_t *argv) { - debugC(kDebugLevelFile, "kFClose(%d)", argv[0].toUint16()); - if (argv[0] != SIGNAL_REG) { - FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); - if (f) - f->close(); - } - return s->r_acc; -} - -reg_t kFPuts(EngineState *s, int argc, reg_t *argv) { - int handle = argv[0].toUint16(); - Common::String data = s->_segMan->getString(argv[1]); - - FileHandle *f = getFileFromHandle(s, handle); - if (f) - f->_out->write(data.c_str(), data.size()); - - return s->r_acc; -} - -reg_t kFGets(EngineState *s, int argc, reg_t *argv) { - int maxsize = argv[1].toUint16(); - char *buf = new char[maxsize]; - int handle = argv[2].toUint16(); - - debugC(kDebugLevelFile, "kFGets(%d, %d)", handle, maxsize); - int readBytes = fgets_wrapper(s, buf, maxsize, handle); - s->_segMan->memcpy(argv[0], (const byte*)buf, maxsize); - delete[] buf; - return readBytes ? argv[0] : NULL_REG; -} - /** * Writes the cwd to the supplied address and returns the address in acc. */ @@ -559,6 +518,9 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { debugC(kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16()); + if (argv[0] == SIGNAL_REG) + return s->r_acc; + uint16 handle = argv[0].toUint16(); #ifdef ENABLE_SCI32 @@ -571,8 +533,13 @@ reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { FileHandle *f = getFileFromHandle(s, handle); if (f) { f->close(); + if (getSciVersion() <= SCI_VERSION_0_LATE) + return s->r_acc; // SCI0 semantics: no value returned return SIGNAL_REG; } + + if (getSciVersion() <= SCI_VERSION_0_LATE) + return s->r_acc; // SCI0 semantics: no value returned return NULL_REG; } @@ -635,20 +602,20 @@ reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { } reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { - uint16 size = argv[1].toUint16(); - char *buf = new char[size]; + uint16 maxsize = argv[1].toUint16(); + char *buf = new char[maxsize]; uint16 handle = argv[2].toUint16(); - debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, size); + debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, maxsize); uint32 bytesRead; #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) - bytesRead = s->_virtualIndexFile->readLine(buf, size); + bytesRead = s->_virtualIndexFile->readLine(buf, maxsize); else #endif - bytesRead = fgets_wrapper(s, buf, size, handle); + bytesRead = fgets_wrapper(s, buf, maxsize, handle); - s->_segMan->memcpy(argv[0], (const byte*)buf, size); + s->_segMan->memcpy(argv[0], (const byte*)buf, maxsize); delete[] buf; return bytesRead ? argv[0] : NULL_REG; } @@ -669,9 +636,13 @@ reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { if (f) { f->_out->write(str.c_str(), str.size()); + if (getSciVersion() <= SCI_VERSION_0_LATE) + return s->r_acc; // SCI0 semantics: no value returned return NULL_REG; } + if (getSciVersion() <= SCI_VERSION_0_LATE) + return s->r_acc; // SCI0 semantics: no value returned return make_reg(0, 6); // DOS - invalid handle } -- cgit v1.2.3 From 694f0f534a548061c3fecec3c8b0be0e0e5310dd Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 12:22:51 +0300 Subject: SCI: Only include kSave_subops if ENABLE_SCI32 is defined --- engines/sci/engine/kernel_tables.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index d093310139..6965a5da45 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -245,6 +245,8 @@ static const SciKernelMapSubEntry kFileIO_subops[] = { SCI_SUBOPENTRY_TERMINATOR }; +#ifdef ENABLE_SCI32 + static const SciKernelMapSubEntry kSave_subops[] = { { SIG_SCI32, 0, MAP_CALL(SaveGame), "[r0]i[r0](r)", NULL }, { SIG_SCI32, 1, MAP_CALL(RestoreGame), "[r0]i[r0]", NULL }, @@ -255,9 +257,9 @@ static const SciKernelMapSubEntry kSave_subops[] = { { SIG_SCI32, 6, MAP_CALL(MakeSaveCatName), "rr", NULL }, { SIG_SCI32, 7, MAP_CALL(MakeSaveFileName), "rri", NULL }, { SIG_SCI32, 8, MAP_CALL(AutoSave), "[o0]", NULL }, + SCI_SUBOPENTRY_TERMINATOR }; -#ifdef ENABLE_SCI32 // version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kList_subops[] = { { SIG_SCI21, 0, MAP_CALL(NewList), "", NULL }, -- cgit v1.2.3 From e2613d22423fe2108e13909279b2f336a8a3209d Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 12:23:43 +0300 Subject: SCI: Add a workaround for the French version of Torin's Passage Thanks to LePhilousophe for playing and providing the workaround --- engines/sci/engine/workarounds.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index c1d4a3d9f9..ecb1e4c2d5 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -167,6 +167,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_SQ6, -1, 0, 0, "SQ6", "init", -1, 2, { WORKAROUND_FAKE, 0 } }, // Demo and full version: called when the game starts (demo: room 0, full: room 100) { GID_SQ6, 100, 64950, 0, "View", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu { GID_SQ6, -1, 64964, 0, "DPath", "init", -1, 1, { WORKAROUND_FAKE, 0 } }, // during the game + { GID_TORIN, -1, 64017, 0, "oFlags", "clear", -1, 0, { WORKAROUND_FAKE, 0 } }, // entering Torin's home in the French version SCI_WORKAROUNDENTRY_TERMINATOR }; -- cgit v1.2.3 From 93024c073be6d93c9369a83e4b4468bb0aaeeadd Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 12:26:13 +0300 Subject: SCI: Handle the torindebug config setting for Torin's Passage French Thanks to LePhilousophe for testing and providing a patch --- engines/sci/engine/kmisc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 1cbaf0708d..47c891eefd 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -384,6 +384,10 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { } else if (setting == "language") { Common::String languageId = Common::String::format("%d", g_sci->getSciLanguage()); s->_segMan->strcpy(data, languageId.c_str()); + } else if (setting == "torindebug") { + // Used to enable the debug mode in Torin's Passage (French). + // If true, the debug mode is enabled. + s->_segMan->strcpy(data, ""); } else { error("GetConfig: Unknown configuration setting %s", setting.c_str()); } -- cgit v1.2.3 From 2e7b16a8bdb6ad1cf51046d57eb0f5406ee2cc13 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 11:28:25 +0200 Subject: HUGO: Apply coding convention (in progress) --- engines/hugo/console.cpp | 10 +- engines/hugo/dialogs.cpp | 82 +++++----- engines/hugo/dialogs.h | 4 +- engines/hugo/display.cpp | 36 ++--- engines/hugo/file.cpp | 168 +++++++++---------- engines/hugo/game.h | 100 ++++++------ engines/hugo/hugo.cpp | 82 +++++----- engines/hugo/hugo.h | 26 +-- engines/hugo/intro.cpp | 32 ++-- engines/hugo/inventory.cpp | 2 +- engines/hugo/mouse.cpp | 28 ++-- engines/hugo/object.cpp | 386 ++++++++++++++++++++++---------------------- engines/hugo/object.h | 10 +- engines/hugo/object_v1d.cpp | 254 ++++++++++++++--------------- engines/hugo/object_v1w.cpp | 244 ++++++++++++++-------------- engines/hugo/object_v2d.cpp | 248 ++++++++++++++-------------- engines/hugo/object_v3d.cpp | 164 +++++++++---------- engines/hugo/parser.cpp | 74 ++++----- engines/hugo/parser.h | 28 ++-- engines/hugo/parser_v1d.cpp | 130 +++++++-------- engines/hugo/parser_v1w.cpp | 32 ++-- engines/hugo/parser_v2d.cpp | 18 +-- engines/hugo/parser_v3d.cpp | 166 +++++++++---------- engines/hugo/route.cpp | 106 ++++++------ engines/hugo/schedule.cpp | 124 +++++++------- engines/hugo/sound.cpp | 4 +- 26 files changed, 1279 insertions(+), 1279 deletions(-) diff --git a/engines/hugo/console.cpp b/engines/hugo/console.cpp index 19fd91e3fa..414c86e1d4 100644 --- a/engines/hugo/console.cpp +++ b/engines/hugo/console.cpp @@ -96,8 +96,8 @@ bool HugoConsole::Cmd_listObjects(int argc, const char **argv) { DebugPrintf("Available objects for this game are:\n"); for (int i = 0; i < _vm->_object->_numObj; i++) { - if (_vm->_object->_objects[i].genericCmd & TAKE) - DebugPrintf("%2d - %s\n", i, _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)); + if (_vm->_object->_objects[i]._genericCmd & TAKE) + DebugPrintf("%2d - %s\n", i, _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)); } return true; } @@ -111,7 +111,7 @@ bool HugoConsole::Cmd_getObject(int argc, const char **argv) { return true; } - if (_vm->_object->_objects[strToInt(argv[1])].genericCmd & TAKE) + if (_vm->_object->_objects[strToInt(argv[1])]._genericCmd & TAKE) _vm->_parser->takeObject(&_vm->_object->_objects[strToInt(argv[1])]); else DebugPrintf("Object not available\n"); @@ -129,7 +129,7 @@ bool HugoConsole::Cmd_getAllObjects(int argc, const char **argv) { } for (int i = 0; i < _vm->_object->_numObj; i++) { - if (_vm->_object->_objects[i].genericCmd & TAKE) + if (_vm->_object->_objects[i]._genericCmd & TAKE) _vm->_parser->takeObject(&_vm->_object->_objects[i]); } @@ -145,7 +145,7 @@ bool HugoConsole::Cmd_boundaries(int argc, const char **argv) { return true; } - _vm->getGameStatus().showBoundariesFl = !_vm->getGameStatus().showBoundariesFl; + _vm->getGameStatus()._showBoundariesFl = !_vm->getGameStatus()._showBoundariesFl; return false; } diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp index e0b0198470..0efd47a3bd 100644 --- a/engines/hugo/dialogs.cpp +++ b/engines/hugo/dialogs.cpp @@ -34,19 +34,19 @@ namespace Hugo { -TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), arrayBmp(0), arraySize(0), +TopMenu::TopMenu(HugoEngine *vm) : Dialog(0, 0, kMenuWidth, kMenuHeight), _arrayBmp(0), _arraySize(0), _vm(vm) { init(); } TopMenu::~TopMenu() { - for (int i = 0; i < arraySize; i++) { - arrayBmp[i * 2]->free(); - delete arrayBmp[i * 2]; - arrayBmp[i * 2 + 1]->free(); - delete arrayBmp[i * 2 + 1]; + for (int i = 0; i < _arraySize; i++) { + _arrayBmp[i * 2]->free(); + delete _arrayBmp[i * 2]; + _arrayBmp[i * 2 + 1]->free(); + delete _arrayBmp[i * 2 + 1]; } - delete[] arrayBmp; + delete[] _arrayBmp; } void TopMenu::init() { @@ -108,23 +108,23 @@ void TopMenu::reflowLayout() { x += kButtonWidth + kButtonPad; // Set the graphics to the 'on' buttons, except for the variable ones - _whatButton->setGfx(arrayBmp[4 * kMenuWhat + scale - 1]); - _musicButton->setGfx(arrayBmp[4 * kMenuMusic + scale - 1 + ((_vm->_config.musicFl) ? 0 : 2)]); - _soundFXButton->setGfx(arrayBmp[4 * kMenuSoundFX + scale - 1 + ((_vm->_config.soundFl) ? 0 : 2)]); - _saveButton->setGfx(arrayBmp[4 * kMenuSave + scale - 1]); - _loadButton->setGfx(arrayBmp[4 * kMenuLoad + scale - 1]); - _recallButton->setGfx(arrayBmp[4 * kMenuRecall + scale - 1]); - _turboButton->setGfx(arrayBmp[4 * kMenuTurbo + scale - 1 + ((_vm->_config.turboFl) ? 0 : 2)]); - _lookButton->setGfx(arrayBmp[4 * kMenuLook + scale - 1]); - _inventButton->setGfx(arrayBmp[4 * kMenuInventory + scale - 1]); + _whatButton->setGfx(_arrayBmp[4 * kMenuWhat + scale - 1]); + _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + scale - 1 + ((_vm->_config.musicFl) ? 0 : 2)]); + _soundFXButton->setGfx(_arrayBmp[4 * kMenuSoundFX + scale - 1 + ((_vm->_config.soundFl) ? 0 : 2)]); + _saveButton->setGfx(_arrayBmp[4 * kMenuSave + scale - 1]); + _loadButton->setGfx(_arrayBmp[4 * kMenuLoad + scale - 1]); + _recallButton->setGfx(_arrayBmp[4 * kMenuRecall + scale - 1]); + _turboButton->setGfx(_arrayBmp[4 * kMenuTurbo + scale - 1 + ((_vm->_config.turboFl) ? 0 : 2)]); + _lookButton->setGfx(_arrayBmp[4 * kMenuLook + scale - 1]); + _inventButton->setGfx(_arrayBmp[4 * kMenuInventory + scale - 1]); } void TopMenu::loadBmpArr(Common::SeekableReadStream &in) { - arraySize = in.readUint16BE(); + _arraySize = in.readUint16BE(); - delete arrayBmp; - arrayBmp = new Graphics::Surface *[arraySize * 2]; - for (int i = 0; i < arraySize; i++) { + delete _arrayBmp; + _arrayBmp = new Graphics::Surface *[_arraySize * 2]; + for (int i = 0; i < _arraySize; i++) { uint16 bmpSize = in.readUint16BE(); uint32 filPos = in.pos(); Common::SeekableSubReadStream stream(&in, filPos, filPos + bmpSize); @@ -137,28 +137,28 @@ void TopMenu::loadBmpArr(Common::SeekableReadStream &in) { if (bitmapSrc->format.bytesPerPixel == 1) error("TopMenu::loadBmpArr(): Unhandled paletted image"); - arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat()); - arrayBmp[i * 2 + 1] = new Graphics::Surface(); - arrayBmp[i * 2 + 1]->create(arrayBmp[i * 2]->w * 2, arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat()); - byte *src = (byte *)arrayBmp[i * 2]->pixels; - byte *dst = (byte *)arrayBmp[i * 2 + 1]->pixels; - - for (int j = 0; j < arrayBmp[i * 2]->h; j++) { - src = (byte *)arrayBmp[i * 2]->getBasePtr(0, j); - dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); - for (int k = arrayBmp[i * 2]->w; k > 0; k--) { - for (int m = arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { + _arrayBmp[i * 2] = bitmapSrc->convertTo(g_system->getOverlayFormat()); + _arrayBmp[i * 2 + 1] = new Graphics::Surface(); + _arrayBmp[i * 2 + 1]->create(_arrayBmp[i * 2]->w * 2, _arrayBmp[i * 2]->h * 2, g_system->getOverlayFormat()); + byte *src = (byte *)_arrayBmp[i * 2]->pixels; + byte *dst = (byte *)_arrayBmp[i * 2 + 1]->pixels; + + for (int j = 0; j < _arrayBmp[i * 2]->h; j++) { + src = (byte *)_arrayBmp[i * 2]->getBasePtr(0, j); + dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); + for (int k = _arrayBmp[i * 2]->w; k > 0; k--) { + for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { *dst++ = *src++; } - src -= arrayBmp[i * 2]->format.bytesPerPixel; + src -= _arrayBmp[i * 2]->format.bytesPerPixel; - for (int m = arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { + for (int m = _arrayBmp[i * 2]->format.bytesPerPixel; m > 0; m--) { *dst++ = *src++; } } - src = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); - dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1); - for (int k = arrayBmp[i * 2 + 1]->pitch; k > 0; k--) { + src = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2); + dst = (byte *)_arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1); + for (int k = _arrayBmp[i * 2 + 1]->pitch; k > 0; k--) { *dst++ = *src++; } } @@ -171,12 +171,12 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d switch (command) { case kCmdWhat: close(); - _vm->getGameStatus().helpFl = true; + _vm->getGameStatus()._helpFl = true; break; case kCmdMusic: _vm->_sound->toggleMusic(); - _musicButton->setGfx(arrayBmp[4 * kMenuMusic + (g_system->getOverlayWidth() > 320 ? 2 : 1) - 1 + ((_vm->_config.musicFl) ? 0 : 2)]); + _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + (g_system->getOverlayWidth() > 320 ? 2 : 1) - 1 + ((_vm->_config.musicFl) ? 0 : 2)]); _musicButton->draw(); g_gui.theme()->updateScreen(); g_system->updateScreen(); @@ -194,8 +194,8 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d break; case kCmdSave: close(); - if (_vm->getGameStatus().viewState == kViewPlay) { - if (_vm->getGameStatus().gameOverFl) + if (_vm->getGameStatus()._viewState == kViewPlay) { + if (_vm->getGameStatus()._gameOverFl) _vm->gameOverMsg(); else _vm->_file->saveGame(-1, Common::String()); @@ -207,7 +207,7 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d break; case kCmdRecall: close(); - _vm->getGameStatus().recallFl = true; + _vm->getGameStatus()._recallFl = true; break; case kCmdTurbo: _vm->_parser->switchTurbo(); diff --git a/engines/hugo/dialogs.h b/engines/hugo/dialogs.h index 4e710ff2f8..114bcf56a9 100644 --- a/engines/hugo/dialogs.h +++ b/engines/hugo/dialogs.h @@ -94,8 +94,8 @@ protected: GUI::PicButtonWidget *_lookButton; GUI::PicButtonWidget *_inventButton; - Graphics::Surface **arrayBmp; - uint16 arraySize; + Graphics::Surface **_arrayBmp; + uint16 _arraySize; }; class EntryDialog : public GUI::Dialog { diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp index fa18d6b791..7028195dd4 100644 --- a/engines/hugo/display.cpp +++ b/engines/hugo/display.cpp @@ -239,13 +239,13 @@ void Screen::setBackgroundColor(const uint16 color) { void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool foreFl) { debugC(3, kDebugDisplay, "displayFrame(%d, %d, seq, %d)", sx, sy, (foreFl) ? 1 : 0); - image_pt image = seq->imagePtr; // Ptr to object image data + image_pt image = seq->_imagePtr; // Ptr to object image data image_pt subFrontBuffer = &_frontBuffer[sy * kXPix + sx]; // Ptr to offset in _frontBuffer - int16 frontBufferwrap = kXPix - seq->x2 - 1; // Wraps dest_p after each line - int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1; + int16 frontBufferwrap = kXPix - seq->_x2 - 1; // Wraps dest_p after each line + int16 imageWrap = seq->_bytesPerLine8 - seq->_x2 - 1; overlayState_t overlayState = (foreFl) ? kOvlForeground : kOvlUndef; // Overlay state of object - for (uint16 y = 0; y < seq->lines; y++) { // Each line in object - for (uint16 x = 0; x <= seq->x2; x++) { + for (uint16 y = 0; y < seq->_lines; y++) { // Each line in object + for (uint16 x = 0; x <= seq->_x2; x++) { if (*image) { // Non-transparent byte ovlBound = _vm->_object->getFirstOverlay((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits if (ovlBound & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set @@ -265,7 +265,7 @@ void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool for } // Add this rectangle to the display list - displayList(kDisplayAdd, sx, sy, seq->x2 + 1, seq->lines); + displayList(kDisplayAdd, sx, sy, seq->_x2 + 1, seq->_lines); } /** @@ -359,8 +359,8 @@ void Screen::displayList(dupdate_t update, ...) { // Don't blit if newscreen just loaded because _frontBuffer will // get blitted via InvalidateRect() at end of this cycle // and blitting here causes objects to appear too soon. - if (_vm->getGameStatus().newScreenFl) { - _vm->getGameStatus().newScreenFl = false; + if (_vm->getGameStatus()._newScreenFl) { + _vm->getGameStatus()._newScreenFl = false; break; } @@ -563,7 +563,7 @@ void Screen::initNewScreenDisplay() { displayBackground(); // Stop premature object display in Display_list(D_DISPLAY) - _vm->getGameStatus().newScreenFl = true; + _vm->getGameStatus()._newScreenFl = true; } /** @@ -650,19 +650,19 @@ bool Screen::isOverlapping(const rect_t *rectA, const rect_t *rectB) const { * White = Fix objects, parts of background */ void Screen::drawBoundaries() { - if (!_vm->getGameStatus().showBoundariesFl) + if (!_vm->getGameStatus()._showBoundariesFl) return; _vm->_mouse->drawHotspots(); for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; // Get pointer to object - if (obj->screenIndex == *_vm->_screen_p) { - if ((obj->currImagePtr != 0) && (obj->cycling != kCycleInvisible)) - drawRectangle(false, obj->x + obj->currImagePtr->x1, obj->y + obj->currImagePtr->y1, - obj->x + obj->currImagePtr->x2, obj->y + obj->currImagePtr->y2, _TLIGHTGREEN); - else if ((obj->currImagePtr == 0) && (obj->vxPath != 0) && !obj->carriedFl) - drawRectangle(false, obj->oldx, obj->oldy, obj->oldx + obj->vxPath, obj->oldy + obj->vyPath, _TBRIGHTWHITE); + if (obj->_screenIndex == *_vm->_screen_p) { + if ((obj->_currImagePtr != 0) && (obj->_cycling != kCycleInvisible)) + drawRectangle(false, obj->_x + obj->_currImagePtr->_x1, obj->_y + obj->_currImagePtr->_y1, + obj->_x + obj->_currImagePtr->_x2, obj->_y + obj->_currImagePtr->_y2, _TLIGHTGREEN); + else if ((obj->_currImagePtr == 0) && (obj->_vxPath != 0) && !obj->_carriedFl) + drawRectangle(false, obj->_oldx, obj->_oldy, obj->_oldx + obj->_vxPath, obj->_oldy + obj->_vyPath, _TBRIGHTWHITE); } } g_system->copyRectToScreen(_frontBuffer, 320, 0, 0, 320, 200); @@ -735,7 +735,7 @@ overlayState_t Screen_v1d::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) { uint16 index = (uint16)(dst_p - _frontBuffer) >> 3; - for (int i = 0; i < seq_p->lines-y; i++) { // Each line in object + for (int i = 0; i < seq_p->_lines-y; i++) { // Each line in object if (_vm->_object->getBaseBoundary(index)) // If any overlay base byte is non-zero then the object is foreground, else back. return kOvlForeground; index += kCompLineSize; @@ -802,7 +802,7 @@ void Screen_v1w::loadFontArr(Common::ReadStream &in) { overlayState_t Screen_v1w::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) { debugC(4, kDebugDisplay, "findOvl()"); - for (; y < seq_p->lines; y++) { // Each line in object + for (; y < seq_p->_lines; y++) { // Each line in object byte ovb = _vm->_object->getBaseBoundary((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits if (ovb & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set return kOvlForeground; // Found a bit - must be foreground diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index f94f3b0443..8b03a9a430 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -143,11 +143,11 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr // Find size of image data in 8-bit DIB format // Note save of x2 - marks end of valid data before garbage uint16 bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl - seqPtr->bytesPerLine8 = bytesPerLine4 * 2; // 8-bit bpl - seqPtr->lines = PCC_header.y2 - PCC_header.y1 + 1; - seqPtr->x2 = PCC_header.x2 - PCC_header.x1 + 1; + seqPtr->_bytesPerLine8 = bytesPerLine4 * 2; // 8-bit bpl + seqPtr->_lines = PCC_header.y2 - PCC_header.y1 + 1; + seqPtr->_x2 = PCC_header.x2 - PCC_header.x1 + 1; // Size of the image - uint16 size = seqPtr->lines * seqPtr->bytesPerLine8; + uint16 size = seqPtr->_lines * seqPtr->_bytesPerLine8; // Allocate memory for image data if NULL if (imagePtr == 0) @@ -155,13 +155,13 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr assert(imagePtr); - seqPtr->imagePtr = imagePtr; + seqPtr->_imagePtr = imagePtr; // Process the image data, converting to 8-bit DIB format uint16 y = 0; // Current line index byte pline[kXPix]; // Hold 4 planes of data byte *p = pline; // Ptr to above - while (y < seqPtr->lines) { + while (y < seqPtr->_lines) { byte c = f.readByte(); if ((c & kRepeatMask) == kRepeatMask) { byte d = f.readByte(); // Read data byte @@ -193,7 +193,7 @@ void FileManager::readImage(const int objNum, object_t *objPtr) { uint32 objLength; }; - if (!objPtr->seqNumb) // This object has no images + if (!objPtr->_seqNumb) // This object has no images return; if (_vm->isPacked()) { @@ -206,9 +206,9 @@ void FileManager::readImage(const int objNum, object_t *objPtr) { _objectsArchive.seek(objBlock.objOffset, SEEK_SET); } else { Common::String buf; - buf = _vm->_picDir + Common::String(_vm->_text->getNoun(objPtr->nounIndex, 0)) + ".PIX"; + buf = _vm->_picDir + Common::String(_vm->_text->getNoun(objPtr->_nounIndex, 0)) + ".PIX"; if (!_objectsArchive.open(buf)) { - buf = Common::String(_vm->_text->getNoun(objPtr->nounIndex, 0)) + ".PIX"; + buf = Common::String(_vm->_text->getNoun(objPtr->_nounIndex, 0)) + ".PIX"; if (!_objectsArchive.open(buf)) error("File not found: %s", buf.c_str()); } @@ -218,60 +218,60 @@ void FileManager::readImage(const int objNum, object_t *objPtr) { seq_t *seqPtr = 0; // Ptr to sequence structure // Now read the images into an images list - for (int j = 0; j < objPtr->seqNumb; j++) { // for each sequence - for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image + for (int j = 0; j < objPtr->_seqNumb; j++) { // for each sequence + for (int k = 0; k < objPtr->_seqList[j]._imageNbr; k++) { // each image if (k == 0) { // First image // Read this image - allocate both seq and image memory - seqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->nounIndex, 0)); - objPtr->seqList[j].seqPtr = seqPtr; + seqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->_nounIndex, 0)); + objPtr->_seqList[j]._seqPtr = seqPtr; firstImgFl = false; } else { // Subsequent image // Read this image - allocate both seq and image memory - seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->nounIndex, 0)); - seqPtr = seqPtr->nextSeqPtr; + seqPtr->_nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstImgFl, _vm->_text->getNoun(objPtr->_nounIndex, 0)); + seqPtr = seqPtr->_nextSeqPtr; } // Compute the bounding box - x1, x2, y1, y2 // Note use of x2 - marks end of valid data in row - uint16 x2 = seqPtr->x2; - seqPtr->x1 = seqPtr->x2; - seqPtr->x2 = 0; - seqPtr->y1 = seqPtr->lines; - seqPtr->y2 = 0; - - image_pt dibPtr = seqPtr->imagePtr; - for (int y = 0; y < seqPtr->lines; y++, dibPtr += seqPtr->bytesPerLine8 - x2) { + uint16 x2 = seqPtr->_x2; + seqPtr->_x1 = seqPtr->_x2; + seqPtr->_x2 = 0; + seqPtr->_y1 = seqPtr->_lines; + seqPtr->_y2 = 0; + + image_pt dibPtr = seqPtr->_imagePtr; + for (int y = 0; y < seqPtr->_lines; y++, dibPtr += seqPtr->_bytesPerLine8 - x2) { for (int x = 0; x < x2; x++) { if (*dibPtr++) { // Some data found - if (x < seqPtr->x1) - seqPtr->x1 = x; - if (x > seqPtr->x2) - seqPtr->x2 = x; - if (y < seqPtr->y1) - seqPtr->y1 = y; - if (y > seqPtr->y2) - seqPtr->y2 = y; + if (x < seqPtr->_x1) + seqPtr->_x1 = x; + if (x > seqPtr->_x2) + seqPtr->_x2 = x; + if (y < seqPtr->_y1) + seqPtr->_y1 = y; + if (y > seqPtr->_y2) + seqPtr->_y2 = y; } } } } assert(seqPtr); - seqPtr->nextSeqPtr = objPtr->seqList[j].seqPtr; // loop linked list to head + seqPtr->_nextSeqPtr = objPtr->_seqList[j]._seqPtr; // loop linked list to head } // Set the current image sequence to first or last - switch (objPtr->cycling) { + switch (objPtr->_cycling) { case kCycleInvisible: // (May become visible later) case kCycleAlmostInvisible: case kCycleNotCycling: case kCycleForward: - objPtr->currImagePtr = objPtr->seqList[0].seqPtr; + objPtr->_currImagePtr = objPtr->_seqList[0]._seqPtr; break; case kCycleBackward: - objPtr->currImagePtr = seqPtr; + objPtr->_currImagePtr = seqPtr; break; default: - warning("Unexpected cycling: %d", objPtr->cycling); + warning("Unexpected cycling: %d", objPtr->_cycling); } if (!_vm->isPacked()) @@ -298,25 +298,25 @@ sound_pt FileManager::getSound(const int16 sound, uint16 *size) { if (!has_read_header) { for (int i = 0; i < kMaxSounds; i++) { - s_hdr[i].size = fp.readUint16LE(); - s_hdr[i].offset = fp.readUint32LE(); + s_hdr[i]._size = fp.readUint16LE(); + s_hdr[i]._offset = fp.readUint32LE(); } if (fp.err()) error("Wrong sound file format"); has_read_header = true; } - *size = s_hdr[sound].size; + *size = s_hdr[sound]._size; if (*size == 0) error("Wrong sound file format or missing sound %d", sound); // Allocate memory for sound or music, if possible - sound_pt soundPtr = (byte *)malloc(s_hdr[sound].size); // Ptr to sound data + sound_pt soundPtr = (byte *)malloc(s_hdr[sound]._size); // Ptr to sound data assert(soundPtr); // Seek to data and read it - fp.seek(s_hdr[sound].offset, SEEK_SET); - if (fp.read(soundPtr, s_hdr[sound].size) != s_hdr[sound].size) + fp.seek(s_hdr[sound]._offset, SEEK_SET); + if (fp.read(soundPtr, s_hdr[sound]._size) != s_hdr[sound]._size) error("Wrong sound file format"); fp.close(); @@ -391,13 +391,13 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) { out->writeSint16BE(_vm->getScore()); // Save story mode - out->writeByte((gameStatus.storyModeFl) ? 1 : 0); + out->writeByte((gameStatus._storyModeFl) ? 1 : 0); // Save jumpexit mode out->writeByte((_vm->_mouse->getJumpExitFl()) ? 1 : 0); // Save gameover status - out->writeByte((gameStatus.gameOverFl) ? 1 : 0); + out->writeByte((gameStatus._gameOverFl) ? 1 : 0); // Save screen states for (int i = 0; i < _vm->_numStates; i++) @@ -408,17 +408,17 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) { _vm->_screen->savePal(out); // Save maze status - out->writeByte((_vm->_maze.enabledFl) ? 1 : 0); - out->writeByte(_vm->_maze.size); - out->writeSint16BE(_vm->_maze.x1); - out->writeSint16BE(_vm->_maze.y1); - out->writeSint16BE(_vm->_maze.x2); - out->writeSint16BE(_vm->_maze.y2); - out->writeSint16BE(_vm->_maze.x3); - out->writeSint16BE(_vm->_maze.x4); - out->writeByte(_vm->_maze.firstScreenIndex); - - out->writeByte((byte)_vm->getGameStatus().viewState); + out->writeByte((_vm->_maze._enabledFl) ? 1 : 0); + out->writeByte(_vm->_maze._size); + out->writeSint16BE(_vm->_maze._x1); + out->writeSint16BE(_vm->_maze._y1); + out->writeSint16BE(_vm->_maze._x2); + out->writeSint16BE(_vm->_maze._y2); + out->writeSint16BE(_vm->_maze._x3); + out->writeSint16BE(_vm->_maze._x4); + out->writeByte(_vm->_maze._firstScreenIndex); + + out->writeByte((byte)_vm->getGameStatus()._viewState); out->finalize(); @@ -491,9 +491,9 @@ bool FileManager::restoreGame(const int16 slot) { int score = in->readSint16BE(); _vm->setScore(score); - gameStatus.storyModeFl = (in->readByte() == 1); + gameStatus._storyModeFl = (in->readByte() == 1); _vm->_mouse->setJumpExitFl(in->readByte() == 1); - gameStatus.gameOverFl = (in->readByte() == 1); + gameStatus._gameOverFl = (in->readByte() == 1); for (int i = 0; i < _vm->_numStates; i++) _vm->_screenStates[i] = in->readByte(); @@ -503,18 +503,18 @@ bool FileManager::restoreGame(const int16 slot) { _vm->_screen->restorePal(in); // Restore maze status - _vm->_maze.enabledFl = (in->readByte() == 1); - _vm->_maze.size = in->readByte(); - _vm->_maze.x1 = in->readSint16BE(); - _vm->_maze.y1 = in->readSint16BE(); - _vm->_maze.x2 = in->readSint16BE(); - _vm->_maze.y2 = in->readSint16BE(); - _vm->_maze.x3 = in->readSint16BE(); - _vm->_maze.x4 = in->readSint16BE(); - _vm->_maze.firstScreenIndex = in->readByte(); + _vm->_maze._enabledFl = (in->readByte() == 1); + _vm->_maze._size = in->readByte(); + _vm->_maze._x1 = in->readSint16BE(); + _vm->_maze._y1 = in->readSint16BE(); + _vm->_maze._x2 = in->readSint16BE(); + _vm->_maze._y2 = in->readSint16BE(); + _vm->_maze._x3 = in->readSint16BE(); + _vm->_maze._x4 = in->readSint16BE(); + _vm->_maze._firstScreenIndex = in->readByte(); _vm->_scheduler->restoreScreen(*_vm->_screen_p); - if ((_vm->getGameStatus().viewState = (vstate_t) in->readByte()) != kViewPlay) + if ((_vm->getGameStatus()._viewState = (vstate_t) in->readByte()) != kViewPlay) _vm->_screen->hideCursor(); @@ -536,25 +536,25 @@ void FileManager::printBootText() { return; } else { Utils::notifyBox(Common::String::format("Missing startup file '%s'", getBootFilename())); - _vm->getGameStatus().doQuitFl = true; + _vm->getGameStatus()._doQuitFl = true; return; } } // Allocate space for the text and print it - char *buf = (char *)malloc(_vm->_boot.exit_len + 1); + char *buf = (char *)malloc(_vm->_boot._exitLen + 1); if (buf) { // Skip over the boot structure (already read) and read exit text ofp.seek((long)sizeof(_vm->_boot), SEEK_SET); - if (ofp.read(buf, _vm->_boot.exit_len) != (size_t)_vm->_boot.exit_len) { + if (ofp.read(buf, _vm->_boot._exitLen) != (size_t)_vm->_boot._exitLen) { Utils::notifyBox(Common::String::format("Error while reading startup file '%s'", getBootFilename())); - _vm->getGameStatus().doQuitFl = true; + _vm->getGameStatus()._doQuitFl = true; return; } // Decrypt the exit text, using CRYPT substring int i; - for (i = 0; i < _vm->_boot.exit_len; i++) + for (i = 0; i < _vm->_boot._exitLen; i++) buf[i] ^= s_bootCypher[i % s_bootCypherLen]; buf[i] = '\0'; @@ -577,32 +577,32 @@ void FileManager::readBootFile() { if (_vm->_gameVariant == kGameVariantH1Dos) { //TODO initialize properly _boot structure warning("readBootFile - Skipping as H1 Dos may be a freeware"); - memset(_vm->_boot.distrib, '\0', sizeof(_vm->_boot.distrib)); - _vm->_boot.registered = kRegFreeware; + memset(_vm->_boot._distrib, '\0', sizeof(_vm->_boot._distrib)); + _vm->_boot._registered = kRegFreeware; return; } else if (_vm->getPlatform() == Common::kPlatformPC) { warning("readBootFile - Skipping as H2 and H3 Dos may be shareware"); - memset(_vm->_boot.distrib, '\0', sizeof(_vm->_boot.distrib)); - _vm->_boot.registered = kRegShareware; + memset(_vm->_boot._distrib, '\0', sizeof(_vm->_boot._distrib)); + _vm->_boot._registered = kRegShareware; return; } else { Utils::notifyBox(Common::String::format("Missing startup file '%s'", getBootFilename())); - _vm->getGameStatus().doQuitFl = true; + _vm->getGameStatus()._doQuitFl = true; return; } } if (ofp.size() < (int32)sizeof(_vm->_boot)) { Utils::notifyBox(Common::String::format("Corrupted startup file '%s'", getBootFilename())); - _vm->getGameStatus().doQuitFl = true; + _vm->getGameStatus()._doQuitFl = true; return; } - _vm->_boot.checksum = ofp.readByte(); - _vm->_boot.registered = ofp.readByte(); - ofp.read(_vm->_boot.pbswitch, sizeof(_vm->_boot.pbswitch)); - ofp.read(_vm->_boot.distrib, sizeof(_vm->_boot.distrib)); - _vm->_boot.exit_len = ofp.readUint16LE(); + _vm->_boot._checksum = ofp.readByte(); + _vm->_boot._registered = ofp.readByte(); + ofp.read(_vm->_boot._pbswitch, sizeof(_vm->_boot._pbswitch)); + ofp.read(_vm->_boot._distrib, sizeof(_vm->_boot._distrib)); + _vm->_boot._exitLen = ofp.readUint16LE(); byte *p = (byte *)&_vm->_boot; @@ -615,7 +615,7 @@ void FileManager::readBootFile() { if (checksum) { Utils::notifyBox(Common::String::format("Corrupted startup file '%s'", getBootFilename())); - _vm->getGameStatus().doQuitFl = true; + _vm->getGameStatus()._doQuitFl = true; } } diff --git a/engines/hugo/game.h b/engines/hugo/game.h index b1c5f407b3..ab5e2dff56 100644 --- a/engines/hugo/game.h +++ b/engines/hugo/game.h @@ -84,11 +84,11 @@ enum path_t { }; struct hugo_boot_t { // Common HUGO boot file - char checksum; // Checksum for boot structure (not exit text) - char registered; // TRUE if registered version, else FALSE - char pbswitch[8]; // Playback switch string - char distrib[32]; // Distributor branding string - uint16 exit_len; // Length of exit text (next in file) + char _checksum; // Checksum for boot structure (not exit text) + char _registered; // TRUE if registered version, else FALSE + char _pbswitch[8]; // Playback switch string + char _distrib[32]; // Distributor branding string + uint16 _exitLen; // Length of exit text (next in file) } PACKED_STRUCT; /** @@ -101,11 +101,11 @@ typedef byte *sound_pt; // ptr to sound (or music) d * Structure for initializing maze processing */ struct maze_t { - bool enabledFl; // TRUE when maze processing enabled - byte size; // Size of (square) maze matrix - int x1, y1, x2, y2; // maze hotspot bounding box - int x3, x4; // north, south x entry coordinates - byte firstScreenIndex; // index of first screen in maze + bool _enabledFl; // TRUE when maze processing enabled + byte _size; // Size of (square) maze matrix + int _x1, _y1, _x2, _y2; // maze hotspot bounding box + int _x3, _x4; // north, south x entry coordinates + byte _firstScreenIndex; // index of first screen in maze }; /** @@ -113,25 +113,25 @@ struct maze_t { * The image data is in 8-bit DIB format, i.e. 1 byte = 1 pixel */ struct seq_t { // Linked list of images - byte *imagePtr; // ptr to image - uint16 bytesPerLine8; // bytes per line (8bits) - uint16 lines; // lines - uint16 x1, x2, y1, y2; // Offsets from x,y: data bounding box - seq_t *nextSeqPtr; // ptr to next record + byte *_imagePtr; // ptr to image + uint16 _bytesPerLine8; // bytes per line (8bits) + uint16 _lines; // lines + uint16 _x1, _x2, _y1, _y2; // Offsets from x,y: data bounding box + seq_t *_nextSeqPtr; // ptr to next record }; /** * The following is an array of structures of above sequences */ struct seqList_t { - uint16 imageNbr; // Number of images in sequence - seq_t *seqPtr; // Ptr to sequence structure + uint16 _imageNbr; // Number of images in sequence + seq_t *_seqPtr; // Ptr to sequence structure }; #include "common/pack-start.h" // START STRUCT PACKING struct sound_hdr_t { // Sound file lookup entry - uint16 size; // Size of sound data in bytes - uint32 offset; // Offset of sound data in file + uint16 _size; // Size of sound data in bytes + uint32 _offset; // Offset of sound data in file } PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING @@ -141,37 +141,37 @@ static const int kMaxSeqNumb = 4; // Number of sequences of im * Following is definition of object attributes */ struct object_t { - uint16 nounIndex; // String identifying object - uint16 dataIndex; // String describing the object - uint16 *stateDataIndex; // Added by Strangerke to handle the LOOK_S state-dependant descriptions - path_t pathType; // Describe path object follows - int vxPath, vyPath; // Delta velocities (e.g. for CHASE) - uint16 actIndex; // Action list to do on collision with hero - byte seqNumb; // Number of sequences in list - seq_t *currImagePtr; // Sequence image currently in use - seqList_t seqList[kMaxSeqNumb]; // Array of sequence structure ptrs and lengths - cycle_t cycling; // Whether cycling, forward or backward - byte cycleNumb; // No. of times to cycle - byte frameInterval; // Interval (in ticks) between frames - byte frameTimer; // Decrementing timer for above - int8 radius; // Defines sphere of influence by hero - byte screenIndex; // Screen in which object resides - int x, y; // Current coordinates of object - int oldx, oldy; // Previous coordinates of object - int8 vx, vy; // Velocity - byte objValue; // Value of object - int genericCmd; // Bit mask of 'generic' commands for object - uint16 cmdIndex; // ptr to list of cmd structures for verbs - bool carriedFl; // TRUE if object being carried - byte state; // state referenced in cmd list - bool verbOnlyFl; // TRUE if verb-only cmds allowed e.g. sit,look - byte priority; // Whether object fore, background or floating - int16 viewx, viewy; // Position to view object from (or 0 or -1) - int16 direction; // Direction to view object from - byte curSeqNum; // Save which seq number currently in use - byte curImageNum; // Save which image of sequence currently in use - int8 oldvx; // Previous vx (used in wandering) - int8 oldvy; // Previous vy + uint16 _nounIndex; // String identifying object + uint16 _dataIndex; // String describing the object + uint16 *_stateDataIndex; // Added by Strangerke to handle the LOOK_S state-dependant descriptions + path_t _pathType; // Describe path object follows + int _vxPath, _vyPath; // Delta velocities (e.g. for CHASE) + uint16 _actIndex; // Action list to do on collision with hero + byte _seqNumb; // Number of sequences in list + seq_t *_currImagePtr; // Sequence image currently in use + seqList_t _seqList[kMaxSeqNumb]; // Array of sequence structure ptrs and lengths + cycle_t _cycling; // Whether cycling, forward or backward + byte _cycleNumb; // No. of times to cycle + byte _frameInterval; // Interval (in ticks) between frames + byte _frameTimer; // Decrementing timer for above + int8 _radius; // Defines sphere of influence by hero + byte _screenIndex; // Screen in which object resides + int _x, _y; // Current coordinates of object + int _oldx, _oldy; // Previous coordinates of object + int8 _vx, _vy; // Velocity + byte _objValue; // Value of object + int _genericCmd; // Bit mask of 'generic' commands for object + uint16 _cmdIndex; // ptr to list of cmd structures for verbs + bool _carriedFl; // TRUE if object being carried + byte _state; // state referenced in cmd list + bool _verbOnlyFl; // TRUE if verb-only cmds allowed e.g. sit,look + byte _priority; // Whether object fore, background or floating + int16 _viewx, _viewy; // Position to view object from (or 0 or -1) + int16 _direction; // Direction to view object from + byte _curSeqNum; // Save which seq number currently in use + byte _curImageNum; // Save which image of sequence currently in use + int8 _oldvx; // Previous vx (used in wandering) + int8 _oldvy; // Previous vy }; } // End of namespace Hugo diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index df8abf32eb..450f4ff837 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -249,24 +249,24 @@ Common::Error HugoEngine::run() { initStatus(); // Initialize game status initConfig(); // Initialize user's config - if (!_status.doQuitFl) { + if (!_status._doQuitFl) { initialize(); resetConfig(); // Reset user's config initMachine(); // Start the state machine - _status.viewState = kViewIntroInit; + _status._viewState = kViewIntroInit; int16 loadSlot = Common::ConfigManager::instance().getInt("save_slot"); if (loadSlot >= 0) { - _status.skipIntroFl = true; + _status._skipIntroFl = true; _file->restoreGame(loadSlot); } else { _file->saveGame(0, "New Game"); } } - while (!_status.doQuitFl) { + while (!_status._doQuitFl) { _screen->drawBoundaries(); g_system->updateScreen(); runMachine(); @@ -289,20 +289,20 @@ Common::Error HugoEngine::run() { _mouse->setRightButton(); break; case Common::EVENT_QUIT: - _status.doQuitFl = true; + _status._doQuitFl = true; break; default: break; } } - if (_status.helpFl) { - _status.helpFl = false; + if (_status._helpFl) { + _status._helpFl = false; _file->instructions(); } _mouse->mouseHandler(); // Mouse activity - adds to display list _screen->displayList(kDisplayDisplay); // Blit the display list to screen - _status.doQuitFl |= shouldQuit(); // update game quit flag + _status._doQuitFl |= shouldQuit(); // update game quit flag } return Common::kNoError; } @@ -326,7 +326,7 @@ void HugoEngine::runMachine() { status_t &gameStatus = getGameStatus(); // Don't process if gameover - if (gameStatus.gameOverFl) + if (gameStatus._gameOverFl) return; _curTime = g_system->getMillis(); @@ -338,19 +338,19 @@ void HugoEngine::runMachine() { _lastTime = _curTime; - switch (gameStatus.viewState) { + switch (gameStatus._viewState) { case kViewIdle: // Not processing state machine _screen->hideCursor(); _intro->preNewGame(); // Any processing before New Game selected break; case kViewIntroInit: // Initialization before intro begins _intro->introInit(); - gameStatus.viewState = kViewIntro; + gameStatus._viewState = kViewIntro; break; case kViewIntro: // Do any game-dependant preamble if (_intro->introPlay()) { // Process intro screen _scheduler->newScreen(0); // Initialize first screen - gameStatus.viewState = kViewPlay; + gameStatus._viewState = kViewPlay; } break; case kViewPlay: // Playing game @@ -368,8 +368,8 @@ void HugoEngine::runMachine() { _inventory->runInventory(); // Process Inventory state machine break; case kViewExit: // Game over or user exited - gameStatus.viewState = kViewIdle; - _status.doQuitFl = true; + gameStatus._viewState = kViewIdle; + _status._doQuitFl = true; break; } } @@ -427,7 +427,7 @@ bool HugoEngine::loadHugoDat() { _scheduler->loadActListArr(in); _scheduler->loadAlNewscrIndex(in); _hero = &_object->_objects[kHeroIndex]; // This always points to hero - _screen_p = &(_object->_objects[kHeroIndex].screenIndex); // Current screen is hero's + _screen_p = &(_object->_objects[kHeroIndex]._screenIndex); // Current screen is hero's _heroImage = kHeroIndex; // Current in use hero image for (int varnt = 0; varnt < _numVariant; varnt++) { @@ -527,33 +527,33 @@ void HugoEngine::initPlaylist(bool playlist[kMaxTunes]) { */ void HugoEngine::initStatus() { debugC(1, kDebugEngine, "initStatus"); - _status.storyModeFl = false; // Not in story mode - _status.gameOverFl = false; // Hero not knobbled yet - _status.lookFl = false; // Toolbar "look" button - _status.recallFl = false; // Toolbar "recall" button - _status.newScreenFl = false; // Screen not just loaded - _status.godModeFl = false; // No special cheats allowed - _status.showBoundariesFl = false; // Boundaries hidden by default - _status.doQuitFl = false; - _status.skipIntroFl = false; - _status.helpFl = false; + _status._storyModeFl = false; // Not in story mode + _status._gameOverFl = false; // Hero not knobbled yet + _status._lookFl = false; // Toolbar "look" button + _status._recallFl = false; // Toolbar "recall" button + _status._newScreenFl = false; // Screen not just loaded + _status._godModeFl = false; // No special cheats allowed + _status._showBoundariesFl = false; // Boundaries hidden by default + _status._doQuitFl = false; + _status._skipIntroFl = false; + _status._helpFl = false; // Initialize every start of new game - _status.tick = 0; // Tick count - _status.viewState = kViewIdle; // View state + _status._tick = 0; // Tick count + _status._viewState = kViewIdle; // View state // Strangerke - Suppress as related to playback -// _status.recordFl = false; // Not record mode -// _status.playbackFl = false; // Not playback mode +// _status._recordFl = false; // Not record mode +// _status._playbackFl = false; // Not playback mode // Strangerke - Not used ? -// _status.mmtime = false; // Multimedia timer support -// _status.helpFl = false; // Not calling WinHelp() -// _status.demoFl = false; // Not demo mode -// _status.path[0] = 0; // Path to write files -// _status.screenWidth = 0; // Desktop screen width -// _status.saveTick = 0; // Time of last save -// _status.saveSlot = 0; // Slot to save/restore game -// _status.textBoxFl = false; // Not processing a text box +// _status._mmtime = false; // Multimedia timer support +// _status._helpFl = false; // Not calling WinHelp() +// _status._demoFl = false; // Not demo mode +// _status._path[0] = 0; // Path to write files +// _status._screenWidth = 0; // Desktop screen width +// _status._saveTick = 0; // Time of last save +// _status._saveSlot = 0; // Slot to save/restore game +// _status._textBoxFl = false; // Not processing a text box } /** @@ -587,7 +587,7 @@ void HugoEngine::resetConfig() { void HugoEngine::initialize() { debugC(1, kDebugEngine, "initialize"); - _maze.enabledFl = false; + _maze._enabledFl = false; _line[0] = '\0'; _sound->initSound(); @@ -679,10 +679,10 @@ void HugoEngine::calcMaxScore() { void HugoEngine::endGame() { debugC(1, kDebugEngine, "endGame"); - if (_boot.registered != kRegRegistered) + if (_boot._registered != kRegRegistered) Utils::notifyBox(_text->getTextEngine(kEsAdvertise)); Utils::notifyBox(Common::String::format("%s\n%s", _episode, getCopyrightString())); - _status.viewState = kViewExit; + _status._viewState = kViewExit; } bool HugoEngine::canLoadGameStateCurrently() { @@ -690,7 +690,7 @@ bool HugoEngine::canLoadGameStateCurrently() { } bool HugoEngine::canSaveGameStateCurrently() { - return (_status.viewState == kViewPlay); + return (_status._viewState == kViewPlay); } int8 HugoEngine::getTPS() const { diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 125819a39b..3ad6fced24 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -171,20 +171,20 @@ enum seqTextEngine { struct HugoGameDescription; struct status_t { // Game status (not saved) - bool storyModeFl; // Game is telling story - no commands - bool gameOverFl; // Game is over - hero knobbled - bool lookFl; // Toolbar "look" button pressed - bool recallFl; // Toolbar "recall" button pressed - bool newScreenFl; // New screen just loaded in dib_a - bool godModeFl; // Allow DEBUG features in live version - bool showBoundariesFl; // Flag used to show and hide boundaries, + bool _storyModeFl; // Game is telling story - no commands + bool _gameOverFl; // Game is over - hero knobbled + bool _lookFl; // Toolbar "look" button pressed + bool _recallFl; // Toolbar "recall" button pressed + bool _newScreenFl; // New screen just loaded in dib_a + bool _godModeFl; // Allow DEBUG features in live version + bool _showBoundariesFl; // Flag used to show and hide boundaries, // used by the console - bool doQuitFl; - bool skipIntroFl; - bool helpFl; - uint32 tick; // Current time in ticks - vstate_t viewState; // View state machine - int16 song; // Current song + bool _doQuitFl; + bool _skipIntroFl; + bool _helpFl; + uint32 _tick; // Current time in ticks + vstate_t _viewState; // View state machine + int16 _song; // Current song // Strangerke - Suppress as related to playback // bool playbackFl; // Game is in playback mode diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp index 72f718fe8e..599d8f21d3 100644 --- a/engines/hugo/intro.cpp +++ b/engines/hugo/intro.cpp @@ -98,7 +98,7 @@ void intro_v1d::introInit() { bool intro_v1d::introPlay() { byte introSize = getIntroSize(); - if (_vm->getGameStatus().skipIntroFl) + if (_vm->getGameStatus()._skipIntroFl) return true; if (introTicks < introSize) { @@ -117,20 +117,20 @@ bool intro_v1d::introPlay() { error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8"); char buffer[80]; - if (_vm->_boot.registered == kRegRegistered) + if (_vm->_boot._registered == kRegRegistered) strcpy(buffer, "Registered Version"); - else if (_vm->_boot.registered == kRegShareware) + else if (_vm->_boot._registered == kRegShareware) strcpy(buffer, "Shareware Version"); - else if (_vm->_boot.registered == kRegFreeware) + else if (_vm->_boot._registered == kRegFreeware) strcpy(buffer, "Freeware Version"); else - error("Unknown registration flag in hugo.bsf: %d", _vm->_boot.registered); + error("Unknown registration flag in hugo.bsf: %d", _vm->_boot._registered); font.drawString(&surf, buffer, 0, 163, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); font.drawString(&surf, _vm->getCopyrightString(), 0, 176, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); - if ((*_vm->_boot.distrib != '\0') && (scumm_stricmp(_vm->_boot.distrib, "David P. Gray"))) { - sprintf(buffer, "Distributed by %s.", _vm->_boot.distrib); + if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) { + sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib); font.drawString(&surf, buffer, 0, 75, 320, _TMAGENTA, Graphics::kTextAlignCenter); } @@ -253,16 +253,16 @@ void intro_v2d::introInit() { if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8"); - if (_vm->_boot.registered) + if (_vm->_boot._registered) sprintf(buffer, "%s Registered Version", _vm->getCopyrightString()); else sprintf(buffer, "%s Shareware Version", _vm->getCopyrightString()); font.drawString(&surf, buffer, 0, 186, 320, _TLIGHTRED, Graphics::kTextAlignCenter); - if ((*_vm->_boot.distrib != '\0') && (scumm_stricmp(_vm->_boot.distrib, "David P. Gray"))) { + if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) { // TROMAN, size 10-5 - sprintf(buffer, "Distributed by %s.", _vm->_boot.distrib); + sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib); font.drawString(&surf, buffer, 0, 1, 320, _TLIGHTRED, Graphics::kTextAlignCenter); } @@ -294,7 +294,7 @@ void intro_v3d::introInit() { surf.format = Graphics::PixelFormat::createFormatCLUT8(); char buffer[128]; - if (_vm->_boot.registered) + if (_vm->_boot._registered) sprintf(buffer, "%s Registered Version", _vm->getCopyrightString()); else sprintf(buffer,"%s Shareware Version", _vm->getCopyrightString()); @@ -305,8 +305,8 @@ void intro_v3d::introInit() { font.drawString(&surf, buffer, 0, 190, 320, _TBROWN, Graphics::kTextAlignCenter); - if ((*_vm->_boot.distrib != '\0') && (scumm_stricmp(_vm->_boot.distrib, "David P. Gray"))) { - sprintf(buffer, "Distributed by %s.", _vm->_boot.distrib); + if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) { + sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib); font.drawString(&surf, buffer, 0, 0, 320, _TBROWN, Graphics::kTextAlignCenter); } @@ -325,7 +325,7 @@ void intro_v3d::introInit() { * Called every tick. Returns TRUE when complete */ bool intro_v3d::introPlay() { - if (_vm->getGameStatus().skipIntroFl) + if (_vm->getGameStatus()._skipIntroFl) return true; if (introTicks < getIntroSize()) { @@ -356,7 +356,7 @@ intro_v1w::~intro_v1w() { } void intro_v1w::preNewGame() { - _vm->getGameStatus().viewState = kViewIntroInit; + _vm->getGameStatus()._viewState = kViewIntroInit; } void intro_v1w::introInit() { @@ -416,7 +416,7 @@ void intro_v3w::introInit() { * Called every tick. Returns TRUE when complete */ bool intro_v3w::introPlay() { - if (_vm->getGameStatus().skipIntroFl) + if (_vm->getGameStatus()._skipIntroFl) return true; if (introTicks < getIntroSize()) { diff --git a/engines/hugo/inventory.cpp b/engines/hugo/inventory.cpp index 410c4e715c..151fe0ee13 100644 --- a/engines/hugo/inventory.cpp +++ b/engines/hugo/inventory.cpp @@ -231,7 +231,7 @@ void InventoryHandler::runInventory() { _vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getFrontBuffer(), 0, 0, kXPix); _vm->_object->updateImages(); // Add objects back into display list for restore _inventoryState = kInventoryOff; - gameStatus.viewState = kViewPlay; + gameStatus._viewState = kViewPlay; } break; case kInventoryDown: // Icon bar moving down diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index d2d5b59dae..323f362b10 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -154,7 +154,7 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in status_t &gameStatus = _vm->getGameStatus(); - if (gameStatus.storyModeFl || _vm->_hero->pathType == kPathQuiet) // Make sure user has control + if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control return; int16 inventObjId = _vm->_inventory->getInventoryObjId(); @@ -170,7 +170,7 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in } else { // Clicked over viewport object object_t *obj = &_vm->_object->_objects[objId]; int16 x, y; - switch (obj->viewx) { // Where to walk to + switch (obj->_viewx) { // Where to walk to case -1: // Walk to object position if (_vm->_object->findObjectSpace(obj, &x, &y)) foundFl = _vm->_route->startRoute(kRouteGet, objId, x, y); @@ -181,8 +181,8 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in _vm->_object->useObject(objId); // Pick up or use object break; default: // Walk to view point if possible - if (!_vm->_route->startRoute(kRouteGet, objId, obj->viewx, obj->viewy)) { - if (_vm->_hero->cycling == kCycleInvisible) // If invisible do + if (!_vm->_route->startRoute(kRouteGet, objId, obj->_viewx, obj->_viewy)) { + if (_vm->_hero->_cycling == kCycleInvisible) // If invisible do _vm->_object->useObject(objId); // immediate use else Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there @@ -207,7 +207,7 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int status_t &gameStatus = _vm->getGameStatus(); - if (gameStatus.storyModeFl || _vm->_hero->pathType == kPathQuiet) // Make sure user has control + if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control return; switch (objId) { @@ -254,7 +254,7 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int _vm->_object->lookObject(obj); } else { bool foundFl = false; // TRUE if route found to object - switch (obj->viewx) { // Clicked over viewport object + switch (obj->_viewx) { // Clicked over viewport object case -1: // Walk to object position if (_vm->_object->findObjectSpace(obj, &x, &y)) foundFl = _vm->_route->startRoute(kRouteLook, objId, x, y); @@ -265,8 +265,8 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int _vm->_object->lookObject(obj); break; default: // Walk to view point if possible - if (!_vm->_route->startRoute(kRouteLook, objId, obj->viewx, obj->viewy)) { - if (_vm->_hero->cycling == kCycleInvisible) // If invisible do + if (!_vm->_route->startRoute(kRouteLook, objId, obj->_viewx, obj->_viewy)) { + if (_vm->_hero->_cycling == kCycleInvisible) // If invisible do _vm->_object->lookObject(obj); // immediate decription else Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there @@ -286,14 +286,14 @@ void MouseHandler::mouseHandler() { status_t &gameStatus = _vm->getGameStatus(); istate_t inventState = _vm->_inventory->getInventoryState(); - if ((gameStatus.viewState != kViewPlay) && (inventState != kInventoryActive)) + if ((gameStatus._viewState != kViewPlay) && (inventState != kInventoryActive)) return; int16 cx = getMouseX(); int16 cy = getMouseY(); -// gameStatus.cx = cx; // Save cursor coords -// gameStatus.cy = cy; +// gameStatus._cx = cx; // Save cursor coords +// gameStatus._cy = cy; // Don't process if outside client area if ((cx < 0) || (cx > kXPix) || (cy < kDibOffY) || (cy > kViewSizeY + kDibOffY)) @@ -309,14 +309,14 @@ void MouseHandler::mouseHandler() { } } - if (!gameStatus.gameOverFl) { + if (!gameStatus._gameOverFl) { if (objId == -1) // No match, check rest of view objId = _vm->_object->findObject(cx, cy); if (objId >= 0) { // Got a match // Display object name next to cursor (unless CURSOR_NOCHAR) // Note test for swapped hero name - const char *name = _vm->_text->getNoun(_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId].nounIndex, kCursorNameIndex); + const char *name = _vm->_text->getNoun(_vm->_object->_objects[(objId == kHeroIndex) ? _vm->_heroImage : objId]._nounIndex, kCursorNameIndex); if (name[0] != kCursorNochar) cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE); @@ -378,7 +378,7 @@ void MouseHandler::loadHotspots(Common::ReadStream &in) { void MouseHandler::drawHotspots() const { for (int i = 0; _hotspots[i].screenIndex >= 0; i++) { hotspot_t *hotspot = &_hotspots[i]; - if (hotspot->screenIndex == _vm->_hero->screenIndex) + if (hotspot->screenIndex == _vm->_hero->_screenIndex) _vm->_screen->drawRectangle(false, hotspot->x1, hotspot->y1, hotspot->x2, hotspot->y2, _TLIGHTRED); } } diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp index bc99abf410..92a04227d6 100644 --- a/engines/hugo/object.cpp +++ b/engines/hugo/object.cpp @@ -74,22 +74,22 @@ byte ObjectHandler::getFirstOverlay(uint16 index) const { } bool ObjectHandler::isCarried(int objIndex) const { - return _objects[objIndex].carriedFl; + return _objects[objIndex]._carriedFl; } void ObjectHandler::setCarry(int objIndex, bool val) { - _objects[objIndex].carriedFl = val; + _objects[objIndex]._carriedFl = val; } void ObjectHandler::setVelocity(int objIndex, int8 vx, int8 vy) { - _objects[objIndex].vx = vx; - _objects[objIndex].vy = vy; + _objects[objIndex]._vx = vx; + _objects[objIndex]._vy = vy; } void ObjectHandler::setPath(int objIndex, path_t pathType, int16 vxPath, int16 vyPath) { - _objects[objIndex].pathType = pathType; - _objects[objIndex].vxPath = vxPath; - _objects[objIndex].vyPath = vyPath; + _objects[objIndex]._pathType = pathType; + _objects[objIndex]._vxPath = vxPath; + _objects[objIndex]._vyPath = vyPath; } /** @@ -99,15 +99,15 @@ void ObjectHandler::saveSeq(object_t *obj) { debugC(1, kDebugObject, "saveSeq"); bool found = false; - for (int i = 0; !found && (i < obj->seqNumb); i++) { - seq_t *q = obj->seqList[i].seqPtr; - for (int j = 0; !found && (j < obj->seqList[i].imageNbr); j++) { - if (obj->currImagePtr == q) { + for (int i = 0; !found && (i < obj->_seqNumb); i++) { + seq_t *q = obj->_seqList[i]._seqPtr; + for (int j = 0; !found && (j < obj->_seqList[i]._imageNbr); j++) { + if (obj->_currImagePtr == q) { found = true; - obj->curSeqNum = i; - obj->curImageNum = j; + obj->_curSeqNum = i; + obj->_curImageNum = j; } else { - q = q->nextSeqPtr; + q = q->_nextSeqPtr; } } } @@ -119,10 +119,10 @@ void ObjectHandler::saveSeq(object_t *obj) { void ObjectHandler::restoreSeq(object_t *obj) { debugC(1, kDebugObject, "restoreSeq"); - seq_t *q = obj->seqList[obj->curSeqNum].seqPtr; - for (int j = 0; j < obj->curImageNum; j++) - q = q->nextSeqPtr; - obj->currImagePtr = q; + seq_t *q = obj->_seqList[obj->_curSeqNum]._seqPtr; + for (int j = 0; j < obj->_curImageNum; j++) + q = q->_nextSeqPtr; + obj->_currImagePtr = q; } /** @@ -137,33 +137,33 @@ void ObjectHandler::useObject(int16 objId) { object_t *obj = &_objects[objId]; // Ptr to object if (inventObjId == -1) { // Get or use objid directly - if ((obj->genericCmd & TAKE) || obj->objValue) // Get collectible item - sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->nounIndex, 0)); - else if (obj->cmdIndex != 0) // Use non-collectible item if able - sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->cmdIndex), 0), _vm->_text->getNoun(obj->nounIndex, 0)); - else if ((verb = _vm->_parser->useBG(_vm->_text->getNoun(obj->nounIndex, 0))) != 0) - sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->nounIndex, 0)); + if ((obj->_genericCmd & TAKE) || obj->_objValue) // Get collectible item + sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->_nounIndex, 0)); + else if (obj->_cmdIndex != 0) // Use non-collectible item if able + sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->_cmdIndex), 0), _vm->_text->getNoun(obj->_nounIndex, 0)); + else if ((verb = _vm->_parser->useBG(_vm->_text->getNoun(obj->_nounIndex, 0))) != 0) + sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->_nounIndex, 0)); else return; // Can't use object directly } else { // Use status.objid on objid // Default to first cmd verb - sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId].cmdIndex), 0), - _vm->_text->getNoun(_objects[inventObjId].nounIndex, 0), - _vm->_text->getNoun(obj->nounIndex, 0)); + sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId]._cmdIndex), 0), + _vm->_text->getNoun(_objects[inventObjId]._nounIndex, 0), + _vm->_text->getNoun(obj->_nounIndex, 0)); // Check valid use of objects and override verb if necessary - for (uses_t *use = _uses; use->objId != _numObj; use++) { - if (inventObjId == use->objId) { + for (uses_t *use = _uses; use->_objId != _numObj; use++) { + if (inventObjId == use->_objId) { // Look for secondary object, if found use matching verb bool foundFl = false; - for (target_t *target = use->targets; target->nounIndex != 0; target++) - if (target->nounIndex == obj->nounIndex) { + for (target_t *target = use->_targets; target->_nounIndex != 0; target++) + if (target->_nounIndex == obj->_nounIndex) { foundFl = true; - sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->verbIndex, 0), - _vm->_text->getNoun(_objects[inventObjId].nounIndex, 0), - _vm->_text->getNoun(obj->nounIndex, 0)); + sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->_verbIndex, 0), + _vm->_text->getNoun(_objects[inventObjId]._nounIndex, 0), + _vm->_text->getNoun(obj->_nounIndex, 0)); } // No valid use of objects found, print failure string @@ -171,7 +171,7 @@ void ObjectHandler::useObject(int16 objId) { // Deselect dragged icon if inventory not active if (_vm->_inventory->getInventoryState() != kInventoryActive) _vm->_screen->resetInventoryObjId(); - Utils::notifyBox(_vm->_text->getTextData(use->dataIndex)); + Utils::notifyBox(_vm->_text->getTextData(use->_dataIndex)); return; } } @@ -199,26 +199,26 @@ int16 ObjectHandler::findObject(uint16 x, uint16 y) { // Check objects on screen for (int i = 0; i < _numObj; i++, obj++) { // Object must be in current screen and "useful" - if (obj->screenIndex == *_vm->_screen_p && (obj->genericCmd || obj->objValue || obj->cmdIndex)) { - seq_t *curImage = obj->currImagePtr; + if (obj->_screenIndex == *_vm->_screen_p && (obj->_genericCmd || obj->_objValue || obj->_cmdIndex)) { + seq_t *curImage = obj->_currImagePtr; // Object must have a visible image... - if (curImage != 0 && obj->cycling != kCycleInvisible) { + if (curImage != 0 && obj->_cycling != kCycleInvisible) { // If cursor inside object - if (x >= (uint16)obj->x && x <= obj->x + curImage->x2 && y >= (uint16)obj->y && y <= obj->y + curImage->y2) { + if (x >= (uint16)obj->_x && x <= obj->_x + curImage->_x2 && y >= (uint16)obj->_y && y <= obj->_y + curImage->_y2) { // If object is closest so far - if (obj->y + curImage->y2 > y2Max) { - y2Max = obj->y + curImage->y2; + if (obj->_y + curImage->_y2 > y2Max) { + y2Max = obj->_y + curImage->_y2; objIndex = i; // Found an object! } } } else { // ...or a dummy object that has a hotspot rectangle - if (curImage == 0 && obj->vxPath != 0 && !obj->carriedFl) { + if (curImage == 0 && obj->_vxPath != 0 && !obj->_carriedFl) { // If cursor inside special rectangle - if ((int16)x >= obj->oldx && (int16)x < obj->oldx + obj->vxPath && (int16)y >= obj->oldy && (int16)y < obj->oldy + obj->vyPath) { + if ((int16)x >= obj->_oldx && (int16)x < obj->_oldx + obj->_vxPath && (int16)y >= obj->_oldy && (int16)y < obj->_oldy + obj->_vyPath) { // If object is closest so far - if (obj->oldy + obj->vyPath - 1 > (int16)y2Max) { - y2Max = obj->oldy + obj->vyPath - 1; + if (obj->_oldy + obj->_vyPath - 1 > (int16)y2Max) { + y2Max = obj->_oldy + obj->_vyPath - 1; objIndex = i; // Found an object! } } @@ -240,7 +240,7 @@ void ObjectHandler::lookObject(object_t *obj) { // Hero swapped - look at other obj = &_objects[_vm->_heroImage]; - _vm->_parser->command("%s %s", _vm->_text->getVerb(_vm->_look, 0), _vm->_text->getNoun(obj->nounIndex, 0)); + _vm->_parser->command("%s %s", _vm->_text->getVerb(_vm->_look, 0), _vm->_text->getNoun(obj->_nounIndex, 0)); } /** @@ -249,26 +249,26 @@ void ObjectHandler::lookObject(object_t *obj) { void ObjectHandler::freeObjects() { debugC(1, kDebugObject, "freeObjects"); - if (_vm->_hero != 0 && _vm->_hero->seqList[0].seqPtr != 0) { + if (_vm->_hero != 0 && _vm->_hero->_seqList[0]._seqPtr != 0) { // Free all sequence lists and image data for (int16 i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; - for (int16 j = 0; j < obj->seqNumb; j++) { - seq_t *seq = obj->seqList[j].seqPtr; + for (int16 j = 0; j < obj->_seqNumb; j++) { + seq_t *seq = obj->_seqList[j]._seqPtr; seq_t *next; if (seq == 0) // Failure during database load break; - if (seq->imagePtr != 0) { - free(seq->imagePtr); - seq->imagePtr = 0; + if (seq->_imagePtr != 0) { + free(seq->_imagePtr); + seq->_imagePtr = 0; } - seq = seq->nextSeqPtr; - while (seq != obj->seqList[j].seqPtr) { - if (seq->imagePtr != 0) { - free(seq->imagePtr); - seq->imagePtr = 0; + seq = seq->_nextSeqPtr; + while (seq != obj->_seqList[j]._seqPtr) { + if (seq->_imagePtr != 0) { + free(seq->_imagePtr); + seq->_imagePtr = 0; } - next = seq->nextSeqPtr; + next = seq->_nextSeqPtr; free(seq); seq = next; } @@ -279,13 +279,13 @@ void ObjectHandler::freeObjects() { if (_uses) { for (int16 i = 0; i < _usesSize; i++) - free(_uses[i].targets); + free(_uses[i]._targets); free(_uses); } for (int16 i = 0; i < _objCount; i++) { - free(_objects[i].stateDataIndex); - _objects[i].stateDataIndex = 0; + free(_objects[i]._stateDataIndex); + _objects[i]._stateDataIndex = 0; } free(_objects); @@ -307,20 +307,20 @@ int ObjectHandler::y2comp(const void *a, const void *b) { // Why does qsort try the same indexes? return 0; - if (p1->priority == kPriorityBackground) + if (p1->_priority == kPriorityBackground) return -1; - if (p2->priority == kPriorityBackground) + if (p2->_priority == kPriorityBackground) return 1; - if (p1->priority == kPriorityForeground) + if (p1->_priority == kPriorityForeground) return 1; - if (p2->priority == kPriorityForeground) + if (p2->_priority == kPriorityForeground) return -1; - int ay2 = p1->y + p1->currImagePtr->y2; - int by2 = p2->y + p2->currImagePtr->y2; + int ay2 = p1->_y + p1->_currImagePtr->_y2; + int by2 = p2->_y + p2->_currImagePtr->_y2; return ay2 - by2; } @@ -332,7 +332,7 @@ bool ObjectHandler::isCarrying(uint16 wordIndex) { debugC(1, kDebugObject, "isCarrying(%d)", wordIndex); for (int i = 0; i < _numObj; i++) { - if ((wordIndex == _objects[i].nounIndex) && _objects[i].carriedFl) + if ((wordIndex == _objects[i]._nounIndex) && _objects[i]._carriedFl) return true; } return false; @@ -346,10 +346,10 @@ void ObjectHandler::showTakeables() { for (int j = 0; j < _numObj; j++) { object_t *obj = &_objects[j]; - if ((obj->cycling != kCycleInvisible) && - (obj->screenIndex == *_vm->_screen_p) && - (((TAKE & obj->genericCmd) == TAKE) || obj->objValue)) { - Utils::notifyBox(Common::String::format("You can also see:\n%s.", _vm->_text->getNoun(obj->nounIndex, LOOK_NAME))); + if ((obj->_cycling != kCycleInvisible) && + (obj->_screenIndex == *_vm->_screen_p) && + (((TAKE & obj->_genericCmd) == TAKE) || obj->_objValue)) { + Utils::notifyBox(Common::String::format("You can also see:\n%s.", _vm->_text->getNoun(obj->_nounIndex, LOOK_NAME))); } } } @@ -360,19 +360,19 @@ void ObjectHandler::showTakeables() { bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { debugC(1, kDebugObject, "findObjectSpace(obj, %d, %d)", *destx, *desty); - seq_t *curImage = obj->currImagePtr; - int16 y = obj->y + curImage->y2 - 1; + seq_t *curImage = obj->_currImagePtr; + int16 y = obj->_y + curImage->_y2 - 1; bool foundFl = true; // Try left rear corner - for (int16 x = *destx = obj->x + curImage->x1; x < *destx + kHeroMaxWidth; x++) { + for (int16 x = *destx = obj->_x + curImage->_x1; x < *destx + kHeroMaxWidth; x++) { if (checkBoundary(x, y)) foundFl = false; } if (!foundFl) { // Try right rear corner foundFl = true; - for (int16 x = *destx = obj->x + curImage->x2 - kHeroMaxWidth + 1; x <= obj->x + (int16)curImage->x2; x++) { + for (int16 x = *destx = obj->_x + curImage->_x2 - kHeroMaxWidth + 1; x <= obj->_x + (int16)curImage->_x2; x++) { if (checkBoundary(x, y)) foundFl = false; } @@ -381,7 +381,7 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { if (!foundFl) { // Try left front corner foundFl = true; y += 2; - for (int16 x = *destx = obj->x + curImage->x1; x < *destx + kHeroMaxWidth; x++) { + for (int16 x = *destx = obj->_x + curImage->_x1; x < *destx + kHeroMaxWidth; x++) { if (checkBoundary(x, y)) foundFl = false; } @@ -389,7 +389,7 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { if (!foundFl) { // Try right rear corner foundFl = true; - for (int16 x = *destx = obj->x + curImage->x2 - kHeroMaxWidth + 1; x <= obj->x + (int16)curImage->x2; x++) { + for (int16 x = *destx = obj->_x + curImage->_x2 - kHeroMaxWidth + 1; x <= obj->_x + (int16)curImage->_x2; x++) { if (checkBoundary(x, y)) foundFl = false; } @@ -400,13 +400,13 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { } void ObjectHandler::readUse(Common::ReadStream &in, uses_t &curUse) { - curUse.objId = in.readSint16BE(); - curUse.dataIndex = in.readUint16BE(); + curUse._objId = in.readSint16BE(); + curUse._dataIndex = in.readUint16BE(); uint16 numSubElem = in.readUint16BE(); - curUse.targets = (target_t *)malloc(sizeof(target_t) * numSubElem); + curUse._targets = (target_t *)malloc(sizeof(target_t) * numSubElem); for (int j = 0; j < numSubElem; j++) { - curUse.targets[j].nounIndex = in.readUint16BE(); - curUse.targets[j].verbIndex = in.readUint16BE(); + curUse._targets[j]._nounIndex = in.readUint16BE(); + curUse._targets[j]._verbIndex = in.readUint16BE(); } } /** @@ -414,7 +414,7 @@ void ObjectHandler::readUse(Common::ReadStream &in, uses_t &curUse) { */ void ObjectHandler::loadObjectUses(Common::ReadStream &in) { uses_t tmpUse; - tmpUse.targets = 0; + tmpUse._targets = 0; //Read _uses for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { @@ -429,68 +429,68 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) { readUse(in, _uses[i]); else { readUse(in, tmpUse); - free(tmpUse.targets); - tmpUse.targets = 0; + free(tmpUse._targets); + tmpUse._targets = 0; } } } } void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) { - curObject.nounIndex = in.readUint16BE(); - curObject.dataIndex = in.readUint16BE(); + curObject._nounIndex = in.readUint16BE(); + curObject._dataIndex = in.readUint16BE(); uint16 numSubElem = in.readUint16BE(); if (numSubElem == 0) - curObject.stateDataIndex = 0; + curObject._stateDataIndex = 0; else - curObject.stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem); + curObject._stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem); for (int j = 0; j < numSubElem; j++) - curObject.stateDataIndex[j] = in.readUint16BE(); - - curObject.pathType = (path_t) in.readSint16BE(); - curObject.vxPath = in.readSint16BE(); - curObject.vyPath = in.readSint16BE(); - curObject.actIndex = in.readUint16BE(); - curObject.seqNumb = in.readByte(); - curObject.currImagePtr = 0; - - if (curObject.seqNumb == 0) { - curObject.seqList[0].imageNbr = 0; - curObject.seqList[0].seqPtr = 0; + curObject._stateDataIndex[j] = in.readUint16BE(); + + curObject._pathType = (path_t) in.readSint16BE(); + curObject._vxPath = in.readSint16BE(); + curObject._vyPath = in.readSint16BE(); + curObject._actIndex = in.readUint16BE(); + curObject._seqNumb = in.readByte(); + curObject._currImagePtr = 0; + + if (curObject._seqNumb == 0) { + curObject._seqList[0]._imageNbr = 0; + curObject._seqList[0]._seqPtr = 0; } - for (int j = 0; j < curObject.seqNumb; j++) { - curObject.seqList[j].imageNbr = in.readUint16BE(); - curObject.seqList[j].seqPtr = 0; + for (int j = 0; j < curObject._seqNumb; j++) { + curObject._seqList[j]._imageNbr = in.readUint16BE(); + curObject._seqList[j]._seqPtr = 0; } - curObject.cycling = (cycle_t)in.readByte(); - curObject.cycleNumb = in.readByte(); - curObject.frameInterval = in.readByte(); - curObject.frameTimer = in.readByte(); - curObject.radius = in.readByte(); - curObject.screenIndex = in.readByte(); - curObject.x = in.readSint16BE(); - curObject.y = in.readSint16BE(); - curObject.oldx = in.readSint16BE(); - curObject.oldy = in.readSint16BE(); - curObject.vx = in.readByte(); - curObject.vy = in.readByte(); - curObject.objValue = in.readByte(); - curObject.genericCmd = in.readSint16BE(); - curObject.cmdIndex = in.readUint16BE(); - curObject.carriedFl = (in.readByte() != 0); - curObject.state = in.readByte(); - curObject.verbOnlyFl = (in.readByte() != 0); - curObject.priority = in.readByte(); - curObject.viewx = in.readSint16BE(); - curObject.viewy = in.readSint16BE(); - curObject.direction = in.readSint16BE(); - curObject.curSeqNum = in.readByte(); - curObject.curImageNum = in.readByte(); - curObject.oldvx = in.readByte(); - curObject.oldvy = in.readByte(); + curObject._cycling = (cycle_t)in.readByte(); + curObject._cycleNumb = in.readByte(); + curObject._frameInterval = in.readByte(); + curObject._frameTimer = in.readByte(); + curObject._radius = in.readByte(); + curObject._screenIndex = in.readByte(); + curObject._x = in.readSint16BE(); + curObject._y = in.readSint16BE(); + curObject._oldx = in.readSint16BE(); + curObject._oldy = in.readSint16BE(); + curObject._vx = in.readByte(); + curObject._vy = in.readByte(); + curObject._objValue = in.readByte(); + curObject._genericCmd = in.readSint16BE(); + curObject._cmdIndex = in.readUint16BE(); + curObject._carriedFl = (in.readByte() != 0); + curObject._state = in.readByte(); + curObject._verbOnlyFl = (in.readByte() != 0); + curObject._priority = in.readByte(); + curObject._viewx = in.readSint16BE(); + curObject._viewy = in.readSint16BE(); + curObject._direction = in.readSint16BE(); + curObject._curSeqNum = in.readByte(); + curObject._curImageNum = in.readByte(); + curObject._oldvx = in.readByte(); + curObject._oldvy = in.readByte(); } /** * Load ObjectArr from Hugo.dat @@ -498,7 +498,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) { void ObjectHandler::loadObjectArr(Common::ReadStream &in) { debugC(6, kDebugObject, "loadObject(&in)"); object_t tmpObject; - tmpObject.stateDataIndex = 0; + tmpObject._stateDataIndex = 0; for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { uint16 numElem = in.readUint16BE(); @@ -514,8 +514,8 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) { else { // Skip over uneeded objects. readObject(in, tmpObject); - free(tmpObject.stateDataIndex); - tmpObject.stateDataIndex = 0; + free(tmpObject._stateDataIndex); + tmpObject._stateDataIndex = 0; } } } @@ -528,7 +528,7 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) { void ObjectHandler::setCarriedScreen(int screenNum) { for (int i = kHeroIndex + 1; i < _numObj; i++) {// Any others if (isCarried(i)) // being carried - _objects[i].screenIndex = screenNum; + _objects[i]._screenIndex = screenNum; } } @@ -562,30 +562,30 @@ void ObjectHandler::saveObjects(Common::WriteStream *out) { // Save where curr_seq_p is pointing to saveSeq(&_objects[i]); - out->writeByte(_objects[i].pathType); - out->writeSint16BE(_objects[i].vxPath); - out->writeSint16BE(_objects[i].vyPath); - out->writeByte(_objects[i].cycling); - out->writeByte(_objects[i].cycleNumb); - out->writeByte(_objects[i].frameTimer); - out->writeByte(_objects[i].screenIndex); - out->writeSint16BE(_objects[i].x); - out->writeSint16BE(_objects[i].y); - out->writeSint16BE(_objects[i].oldx); - out->writeSint16BE(_objects[i].oldy); - out->writeSByte(_objects[i].vx); - out->writeSByte(_objects[i].vy); - out->writeByte(_objects[i].objValue); - out->writeByte((_objects[i].carriedFl) ? 1 : 0); - out->writeByte(_objects[i].state); - out->writeByte(_objects[i].priority); - out->writeSint16BE(_objects[i].viewx); - out->writeSint16BE(_objects[i].viewy); - out->writeSint16BE(_objects[i].direction); - out->writeByte(_objects[i].curSeqNum); - out->writeByte(_objects[i].curImageNum); - out->writeSByte(_objects[i].oldvx); - out->writeSByte(_objects[i].oldvy); + out->writeByte(_objects[i]._pathType); + out->writeSint16BE(_objects[i]._vxPath); + out->writeSint16BE(_objects[i]._vyPath); + out->writeByte(_objects[i]._cycling); + out->writeByte(_objects[i]._cycleNumb); + out->writeByte(_objects[i]._frameTimer); + out->writeByte(_objects[i]._screenIndex); + out->writeSint16BE(_objects[i]._x); + out->writeSint16BE(_objects[i]._y); + out->writeSint16BE(_objects[i]._oldx); + out->writeSint16BE(_objects[i]._oldy); + out->writeSByte(_objects[i]._vx); + out->writeSByte(_objects[i]._vy); + out->writeByte(_objects[i]._objValue); + out->writeByte((_objects[i]._carriedFl) ? 1 : 0); + out->writeByte(_objects[i]._state); + out->writeByte(_objects[i]._priority); + out->writeSint16BE(_objects[i]._viewx); + out->writeSint16BE(_objects[i]._viewy); + out->writeSint16BE(_objects[i]._direction); + out->writeByte(_objects[i]._curSeqNum); + out->writeByte(_objects[i]._curImageNum); + out->writeSByte(_objects[i]._oldvx); + out->writeSByte(_objects[i]._oldvy); } } @@ -594,30 +594,30 @@ void ObjectHandler::saveObjects(Common::WriteStream *out) { */ void ObjectHandler::restoreObjects(Common::SeekableReadStream *in) { for (int i = 0; i < _numObj; i++) { - _objects[i].pathType = (path_t) in->readByte(); - _objects[i].vxPath = in->readSint16BE(); - _objects[i].vyPath = in->readSint16BE(); - _objects[i].cycling = (cycle_t) in->readByte(); - _objects[i].cycleNumb = in->readByte(); - _objects[i].frameTimer = in->readByte(); - _objects[i].screenIndex = in->readByte(); - _objects[i].x = in->readSint16BE(); - _objects[i].y = in->readSint16BE(); - _objects[i].oldx = in->readSint16BE(); - _objects[i].oldy = in->readSint16BE(); - _objects[i].vx = in->readSByte(); - _objects[i].vy = in->readSByte(); - _objects[i].objValue = in->readByte(); - _objects[i].carriedFl = (in->readByte() == 1); - _objects[i].state = in->readByte(); - _objects[i].priority = in->readByte(); - _objects[i].viewx = in->readSint16BE(); - _objects[i].viewy = in->readSint16BE(); - _objects[i].direction = in->readSint16BE(); - _objects[i].curSeqNum = in->readByte(); - _objects[i].curImageNum = in->readByte(); - _objects[i].oldvx = in->readSByte(); - _objects[i].oldvy = in->readSByte(); + _objects[i]._pathType = (path_t) in->readByte(); + _objects[i]._vxPath = in->readSint16BE(); + _objects[i]._vyPath = in->readSint16BE(); + _objects[i]._cycling = (cycle_t) in->readByte(); + _objects[i]._cycleNumb = in->readByte(); + _objects[i]._frameTimer = in->readByte(); + _objects[i]._screenIndex = in->readByte(); + _objects[i]._x = in->readSint16BE(); + _objects[i]._y = in->readSint16BE(); + _objects[i]._oldx = in->readSint16BE(); + _objects[i]._oldy = in->readSint16BE(); + _objects[i]._vx = in->readSByte(); + _objects[i]._vy = in->readSByte(); + _objects[i]._objValue = in->readByte(); + _objects[i]._carriedFl = (in->readByte() == 1); + _objects[i]._state = in->readByte(); + _objects[i]._priority = in->readByte(); + _objects[i]._viewx = in->readSint16BE(); + _objects[i]._viewy = in->readSint16BE(); + _objects[i]._direction = in->readSint16BE(); + _objects[i]._curSeqNum = in->readByte(); + _objects[i]._curImageNum = in->readByte(); + _objects[i]._oldvx = in->readSByte(); + _objects[i]._oldvy = in->readSByte(); } } @@ -627,7 +627,7 @@ void ObjectHandler::restoreObjects(Common::SeekableReadStream *in) { int ObjectHandler::calcMaxScore() { int score = 0; for (int i = 0; i < _numObj; i++) - score += _objects[i].objValue; + score += _objects[i]._objValue; return score; } @@ -788,26 +788,26 @@ void ObjectHandler::boundaryCollision(object_t *obj) { if (obj == _vm->_hero) { // Hotspots only relevant to HERO int x; - if (obj->vx > 0) - x = obj->x + obj->currImagePtr->x2; + if (obj->_vx > 0) + x = obj->_x + obj->_currImagePtr->_x2; else - x = obj->x + obj->currImagePtr->x1; - int y = obj->y + obj->currImagePtr->y2; + x = obj->_x + obj->_currImagePtr->_x1; + int y = obj->_y + obj->_currImagePtr->_y2; - int16 index = _vm->_mouse->findExit(x, y, obj->screenIndex); + int16 index = _vm->_mouse->findExit(x, y, obj->_screenIndex); if (index >= 0) _vm->_scheduler->insertActionList(_vm->_mouse->getHotspotActIndex(index)); } else { // Check whether an object collided with HERO - int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1; - int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - obj->currImagePtr->y2; + int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - obj->_currImagePtr->_x1; + int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - obj->_currImagePtr->_y2; // If object's radius is infinity, use a closer value - int8 radius = obj->radius; + int8 radius = obj->_radius; if (radius < 0) radius = kStepDx * 2; if ((abs(dx) <= radius) && (abs(dy) <= radius)) - _vm->_scheduler->insertActionList(obj->actIndex); + _vm->_scheduler->insertActionList(obj->_actIndex); } } diff --git a/engines/hugo/object.h b/engines/hugo/object.h index 84c20db041..8f8043dbbc 100644 --- a/engines/hugo/object.h +++ b/engines/hugo/object.h @@ -35,14 +35,14 @@ namespace Hugo { struct target_t { // Secondary target for action - uint16 nounIndex; // Secondary object - uint16 verbIndex; // Action on secondary object + uint16 _nounIndex; // Secondary object + uint16 _verbIndex; // Action on secondary object }; struct uses_t { // Define uses of certain objects - int16 objId; // Primary object - uint16 dataIndex; // String if no secondary object matches - target_t *targets; // List of secondary targets + int16 _objId; // Primary object + uint16 _dataIndex; // String if no secondary object matches + target_t *_targets; // List of secondary targets }; class ObjectHandler { diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp index 831dc88dea..7b8f90e189 100644 --- a/engines/hugo/object_v1d.cpp +++ b/engines/hugo/object_v1d.cpp @@ -64,7 +64,7 @@ void ObjectHandler_v1d::updateImages() { for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= kCycleAlmostInvisible)) + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) objindex[num_objs++] = i; } @@ -75,27 +75,27 @@ void ObjectHandler_v1d::updateImages() { for (int i = 0; i < num_objs; i++) { object_t *obj = &_objects[objindex[i]]; // Count down inter-frame timer - if (obj->frameTimer) - obj->frameTimer--; + if (obj->_frameTimer) + obj->_frameTimer--; - if (obj->cycling > kCycleAlmostInvisible) { // Only if visible - switch (obj->cycling) { + if (obj->_cycling > kCycleAlmostInvisible) { // Only if visible + switch (obj->_cycling) { case kCycleNotCycling: - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, false); + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, false); break; case kCycleForward: - if (obj->frameTimer) // Not time to see next frame yet - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, false); + if (obj->_frameTimer) // Not time to see next frame yet + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, false); else - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, false); + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, false); break; case kCycleBackward: { - seq_t *seqPtr = obj->currImagePtr; - if (!obj->frameTimer) { // Show next frame - while (seqPtr->nextSeqPtr != obj->currImagePtr) - seqPtr = seqPtr->nextSeqPtr; + seq_t *seqPtr = obj->_currImagePtr; + if (!obj->_frameTimer) { // Show next frame + while (seqPtr->_nextSeqPtr != obj->_currImagePtr) + seqPtr = seqPtr->_nextSeqPtr; } - _vm->_screen->displayFrame(obj->x, obj->y, seqPtr, false); + _vm->_screen->displayFrame(obj->_x, obj->_y, seqPtr, false); break; } default: @@ -109,28 +109,28 @@ void ObjectHandler_v1d::updateImages() { // Cycle any animating objects for (int i = 0; i < num_objs; i++) { object_t *obj = &_objects[objindex[i]]; - if (obj->cycling != kCycleInvisible) { + if (obj->_cycling != kCycleInvisible) { // Only if it's visible - if (obj->cycling == kCycleAlmostInvisible) - obj->cycling = kCycleInvisible; + if (obj->_cycling == kCycleAlmostInvisible) + obj->_cycling = kCycleInvisible; // Now Rotate to next picture in sequence - switch (obj->cycling) { + switch (obj->_cycling) { case kCycleNotCycling: break; case kCycleForward: - if (!obj->frameTimer) { + if (!obj->_frameTimer) { // Time to step to next frame - obj->currImagePtr = obj->currImagePtr->nextSeqPtr; + obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is last frame of sequence // If so, reset frame_timer and decrement n_cycle - if (obj->frameInterval || obj->cycleNumb) { - obj->frameTimer = obj->frameInterval; - for (int j = 0; j < obj->seqNumb; j++) { - if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) { - if (obj->cycleNumb) { // Decr cycleNumb if Non-continous - if (!--obj->cycleNumb) - obj->cycling = kCycleNotCycling; + if (obj->_frameInterval || obj->_cycleNumb) { + obj->_frameTimer = obj->_frameInterval; + for (int j = 0; j < obj->_seqNumb; j++) { + if (obj->_currImagePtr->_nextSeqPtr == obj->_seqList[j]._seqPtr) { + if (obj->_cycleNumb) { // Decr cycleNumb if Non-continous + if (!--obj->_cycleNumb) + obj->_cycling = kCycleNotCycling; } } } @@ -138,20 +138,20 @@ void ObjectHandler_v1d::updateImages() { } break; case kCycleBackward: { - if (!obj->frameTimer) { + if (!obj->_frameTimer) { // Time to step to prev frame - seq_t *seqPtr = obj->currImagePtr; - while (obj->currImagePtr->nextSeqPtr != seqPtr) - obj->currImagePtr = obj->currImagePtr->nextSeqPtr; + seq_t *seqPtr = obj->_currImagePtr; + while (obj->_currImagePtr->_nextSeqPtr != seqPtr) + obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is first frame of sequence // If so, reset frame_timer and decrement n_cycle - if (obj->frameInterval || obj->cycleNumb) { - obj->frameTimer = obj->frameInterval; - for (int j = 0; j < obj->seqNumb; j++) { - if (obj->currImagePtr == obj->seqList[j].seqPtr) { - if (obj->cycleNumb){ // Decr cycleNumb if Non-continous - if (!--obj->cycleNumb) - obj->cycling = kCycleNotCycling; + if (obj->_frameInterval || obj->_cycleNumb) { + obj->_frameTimer = obj->_frameInterval; + for (int j = 0; j < obj->_seqNumb; j++) { + if (obj->_currImagePtr == obj->_seqList[j]._seqPtr) { + if (obj->_cycleNumb){ // Decr cycleNumb if Non-continous + if (!--obj->_cycleNumb) + obj->_cycling = kCycleNotCycling; } } } @@ -162,8 +162,8 @@ void ObjectHandler_v1d::updateImages() { default: break; } - obj->oldx = obj->x; - obj->oldy = obj->y; + obj->_oldx = obj->_x; + obj->_oldy = obj->_y; } } } @@ -184,161 +184,161 @@ void ObjectHandler_v1d::moveObjects() { // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if (obj->screenIndex == *_vm->_screen_p) { - switch (obj->pathType) { + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if (obj->_screenIndex == *_vm->_screen_p) { + switch (obj->_pathType) { case kPathChase: { // Allowable motion wrt boundary - int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1; - int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1; + int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1; + int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1; if (abs(dx) <= 1) - obj->vx = 0; + obj->_vx = 0; else - obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath); + obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath); if (abs(dy) <= 1) - obj->vy = 0; + obj->_vy = 0; else - obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath); + obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath); // Set first image in sequence (if multi-seq object) - if (obj->seqNumb == 4) { - if (!obj->vx) { // Got 4 directions - if (obj->vx != obj->oldvx) {// vx just stopped + if (obj->_seqNumb == 4) { + if (!obj->_vx) { // Got 4 directions + if (obj->_vx != obj->_oldvx) {// vx just stopped if (dy > 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { + } else if (obj->_vx != obj->_oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } } - if (obj->vx || obj->vy) { - if (obj->seqNumb > 1) - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) { + if (obj->_seqNumb > 1) + obj->_cycling = kCycleForward; } else { - obj->cycling = kCycleNotCycling; + obj->_cycling = kCycleNotCycling; boundaryCollision(obj); // Must have got hero! } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image break; } case kPathWander: if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval - obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath; - obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath; + obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath; + obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath; // Set first image in sequence (if multi-seq object) - if (obj->seqNumb > 1) { - if (!obj->vx && (obj->seqNumb > 2)) { - if (obj->vx != obj->oldvx) { // vx just stopped - if (obj->vy > 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + if (obj->_seqNumb > 1) { + if (!obj->_vx && (obj->_seqNumb > 2)) { + if (obj->_vx != obj->_oldvx) { // vx just stopped + if (obj->_vy > 0) + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { - if (obj->vx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + } else if (obj->_vx != obj->_oldvx) { + if (obj->_vx > 0) + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } - if (obj->vx || obj->vy) - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) + obj->_cycling = kCycleForward; else - obj->cycling = kCycleNotCycling; + obj->_cycling = kCycleNotCycling; } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image } break; default: ; // Really, nothing } // Store boundaries - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2); + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2); } } // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) { + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->currImagePtr; // Get ptr to current image + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates - int x1 = obj->x + currImage->x1; // Left edge of object - int x2 = obj->x + currImage->x2; // Right edge - int y1 = obj->y + currImage->y1; // Top edge - int y2 = obj->y + currImage->y2; // Bottom edge + int x1 = obj->_x + currImage->_x1; // Left edge of object + int x2 = obj->_x + currImage->_x2; // Right edge + int y1 = obj->_y + currImage->_y1; // Top edge + int y2 = obj->_y + currImage->_y2; // Bottom edge - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(x1, x2, y2); // Clear our own boundary // Allowable motion wrt boundary - int dx = deltaX(x1, x2, obj->vx, y2); - if (dx != obj->vx) { + int dx = deltaX(x1, x2, obj->_vx, y2); + if (dx != obj->_vx) { // An object boundary collision! boundaryCollision(obj); - obj->vx = 0; + obj->_vx = 0; } - int dy = deltaY(x1, x2, obj->vy, y2); - if (dy != obj->vy) { + int dy = deltaY(x1, x2, obj->_vy, y2); + if (dy != obj->_vy) { // An object boundary collision! boundaryCollision(obj); - obj->vy = 0; + obj->_vy = 0; } - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) storeBoundary(x1, x2, y2); // Re-store our own boundary - obj->x += dx; // Update object position - obj->y += dy; + obj->_x += dx; // Update object position + obj->_y += dy; // Don't let object go outside screen if (x1 < kEdge) - obj->x = kEdge2; + obj->_x = kEdge2; if (x2 > (kXPix - kEdge)) - obj->x = kXPix - kEdge2 - (x2 - x1); + obj->_x = kXPix - kEdge2 - (x2 - x1); if (y1 < kEdge) - obj->y = kEdge2; + obj->_y = kEdge2; if (y2 > (kYPix - kEdge)) - obj->y = kYPix - kEdge2 - (y2 - y1); + obj->_y = kYPix - kEdge2 - (y2 - y1); - if ((obj->vx == 0) && (obj->vy == 0)) - obj->cycling = kCycleNotCycling; + if ((obj->_vx == 0) && (obj->_vy == 0)) + obj->_cycling = kCycleNotCycling; } } // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2); + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing - if (_vm->_maze.enabledFl) { - seq_t *currImage = _vm->_hero->currImagePtr;// Get ptr to current image + if (_vm->_maze._enabledFl) { + seq_t *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image // hero coordinates - int x1 = _vm->_hero->x + currImage->x1; // Left edge of object - int x2 = _vm->_hero->x + currImage->x2; // Right edge - int y1 = _vm->_hero->y + currImage->y1; // Top edge - int y2 = _vm->_hero->y + currImage->y2; // Bottom edge + int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object + int x2 = _vm->_hero->_x + currImage->_x2; // Right edge + int y1 = _vm->_hero->_y + currImage->_y1; // Top edge + int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge _vm->_scheduler->processMaze(x1, x2, y1, y2); } @@ -355,11 +355,11 @@ void ObjectHandler_v1d::swapImages(int objIndex1, int objIndex2) { seqList_t tmpSeqList[kMaxSeqNumb]; int seqListSize = sizeof(seqList_t) * kMaxSeqNumb; - memmove(tmpSeqList, _objects[objIndex1].seqList, seqListSize); - memmove(_objects[objIndex1].seqList, _objects[objIndex2].seqList, seqListSize); - memmove(_objects[objIndex2].seqList, tmpSeqList, seqListSize); - _objects[objIndex1].currImagePtr = _objects[objIndex1].seqList[0].seqPtr; - _objects[objIndex2].currImagePtr = _objects[objIndex2].seqList[0].seqPtr; + memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize); + memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize); + memmove(_objects[objIndex2]._seqList, tmpSeqList, seqListSize); + _objects[objIndex1]._currImagePtr = _objects[objIndex1]._seqList[0]._seqPtr; + _objects[objIndex2]._currImagePtr = _objects[objIndex2]._seqList[0]._seqPtr; _vm->_heroImage = (_vm->_heroImage == kHeroIndex) ? objIndex2 : kHeroIndex; } @@ -367,9 +367,9 @@ void ObjectHandler_v1d::homeIn(int objIndex1, const int objIndex2, const int8 ob // object obj1 will home in on object obj2 object_t *obj1 = &_objects[objIndex1]; object_t *obj2 = &_objects[objIndex2]; - obj1->pathType = kPathAuto; - int dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1; - int dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1; + obj1->_pathType = kPathAuto; + int dx = obj1->_x + obj1->_currImagePtr->_x1 - obj2->_x - obj2->_currImagePtr->_x1; + int dy = obj1->_y + obj1->_currImagePtr->_y1 - obj2->_y - obj2->_currImagePtr->_y1; if (dx == 0) // Don't EVER divide by zero! dx = 1; @@ -377,11 +377,11 @@ void ObjectHandler_v1d::homeIn(int objIndex1, const int objIndex2, const int8 ob dy = 1; if (abs(dx) > abs(dy)) { - obj1->vx = objDx * -sign(dx); - obj1->vy = abs((objDy * dy) / dx) * -sign(dy); + obj1->_vx = objDx * -sign(dx); + obj1->_vy = abs((objDy * dy) / dx) * -sign(dy); } else { - obj1->vy = objDy * sign(dy); - obj1->vx = abs((objDx * dx) / dy) * sign(dx); + obj1->_vy = objDy * sign(dy); + obj1->_vx = abs((objDx * dx) / dy) * sign(dx); } } } // End of namespace Hugo diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp index 4388ef5520..dd3de5fe40 100644 --- a/engines/hugo/object_v1w.cpp +++ b/engines/hugo/object_v1w.cpp @@ -64,7 +64,7 @@ void ObjectHandler_v1w::updateImages() { for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= kCycleAlmostInvisible)) + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) objindex[num_objs++] = i; } @@ -75,27 +75,27 @@ void ObjectHandler_v1w::updateImages() { for (int i = 0; i < num_objs; i++) { object_t *obj = &_objects[objindex[i]]; // Count down inter-frame timer - if (obj->frameTimer) - obj->frameTimer--; + if (obj->_frameTimer) + obj->_frameTimer--; - if (obj->cycling > kCycleAlmostInvisible) { // Only if visible - switch (obj->cycling) { + if (obj->_cycling > kCycleAlmostInvisible) { // Only if visible + switch (obj->_cycling) { case kCycleNotCycling: - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay); + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay); break; case kCycleForward: - if (obj->frameTimer) // Not time to see next frame yet - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay); + if (obj->_frameTimer) // Not time to see next frame yet + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay); else - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == kPriorityOverOverlay); + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, obj->_priority == kPriorityOverOverlay); break; case kCycleBackward: { - seq_t *seqPtr = obj->currImagePtr; - if (!obj->frameTimer) { // Show next frame - while (seqPtr->nextSeqPtr != obj->currImagePtr) - seqPtr = seqPtr->nextSeqPtr; + seq_t *seqPtr = obj->_currImagePtr; + if (!obj->_frameTimer) { // Show next frame + while (seqPtr->_nextSeqPtr != obj->_currImagePtr) + seqPtr = seqPtr->_nextSeqPtr; } - _vm->_screen->displayFrame(obj->x, obj->y, seqPtr, obj->priority == kPriorityOverOverlay); + _vm->_screen->displayFrame(obj->_x, obj->_y, seqPtr, obj->_priority == kPriorityOverOverlay); break; } default: @@ -107,28 +107,28 @@ void ObjectHandler_v1w::updateImages() { // Cycle any animating objects for (int i = 0; i < num_objs; i++) { object_t *obj = &_objects[objindex[i]]; - if (obj->cycling != kCycleInvisible) { + if (obj->_cycling != kCycleInvisible) { // Only if it's visible - if (obj->cycling == kCycleAlmostInvisible) - obj->cycling = kCycleInvisible; + if (obj->_cycling == kCycleAlmostInvisible) + obj->_cycling = kCycleInvisible; // Now Rotate to next picture in sequence - switch (obj->cycling) { + switch (obj->_cycling) { case kCycleNotCycling: break; case kCycleForward: - if (!obj->frameTimer) { + if (!obj->_frameTimer) { // Time to step to next frame - obj->currImagePtr = obj->currImagePtr->nextSeqPtr; + obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is last frame of sequence // If so, reset frame_timer and decrement n_cycle - if (obj->frameInterval || obj->cycleNumb) { - obj->frameTimer = obj->frameInterval; - for (int j = 0; j < obj->seqNumb; j++) { - if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) { - if (obj->cycleNumb) { // Decr cycleNumb if Non-continous - if (!--obj->cycleNumb) - obj->cycling = kCycleNotCycling; + if (obj->_frameInterval || obj->_cycleNumb) { + obj->_frameTimer = obj->_frameInterval; + for (int j = 0; j < obj->_seqNumb; j++) { + if (obj->_currImagePtr->_nextSeqPtr == obj->_seqList[j]._seqPtr) { + if (obj->_cycleNumb) { // Decr cycleNumb if Non-continous + if (!--obj->_cycleNumb) + obj->_cycling = kCycleNotCycling; } } } @@ -136,20 +136,20 @@ void ObjectHandler_v1w::updateImages() { } break; case kCycleBackward: { - if (!obj->frameTimer) { + if (!obj->_frameTimer) { // Time to step to prev frame - seq_t *seqPtr = obj->currImagePtr; - while (obj->currImagePtr->nextSeqPtr != seqPtr) - obj->currImagePtr = obj->currImagePtr->nextSeqPtr; + seq_t *seqPtr = obj->_currImagePtr; + while (obj->_currImagePtr->_nextSeqPtr != seqPtr) + obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is first frame of sequence // If so, reset frame_timer and decrement n_cycle - if (obj->frameInterval || obj->cycleNumb) { - obj->frameTimer = obj->frameInterval; - for (int j = 0; j < obj->seqNumb; j++) { - if (obj->currImagePtr == obj->seqList[j].seqPtr) { - if (obj->cycleNumb){ // Decr cycleNumb if Non-continous - if (!--obj->cycleNumb) - obj->cycling = kCycleNotCycling; + if (obj->_frameInterval || obj->_cycleNumb) { + obj->_frameTimer = obj->_frameInterval; + for (int j = 0; j < obj->_seqNumb; j++) { + if (obj->_currImagePtr == obj->_seqList[j]._seqPtr) { + if (obj->_cycleNumb){ // Decr cycleNumb if Non-continous + if (!--obj->_cycleNumb) + obj->_cycling = kCycleNotCycling; } } } @@ -160,8 +160,8 @@ void ObjectHandler_v1w::updateImages() { default: break; } - obj->oldx = obj->x; - obj->oldy = obj->y; + obj->_oldx = obj->_x; + obj->_oldy = obj->_y; } } } @@ -181,174 +181,174 @@ void ObjectHandler_v1w::moveObjects() { // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if (obj->screenIndex == *_vm->_screen_p) { - switch (obj->pathType) { + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if (obj->_screenIndex == *_vm->_screen_p) { + switch (obj->_pathType) { case kPathChase: case kPathChase2: { - int8 radius = obj->radius; // Default to object's radius + int8 radius = obj->_radius; // Default to object's radius if (radius < 0) // If radius infinity, use closer value radius = kStepDx; // Allowable motion wrt boundary - int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1; - int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1; + int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1; + int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1; if (abs(dx) <= radius) - obj->vx = 0; + obj->_vx = 0; else - obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath); + obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath); if (abs(dy) <= radius) - obj->vy = 0; + obj->_vy = 0; else - obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath); + obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath); // Set first image in sequence (if multi-seq object) - switch (obj->seqNumb) { + switch (obj->_seqNumb) { case 4: - if (!obj->vx) { // Got 4 directions - if (obj->vx != obj->oldvx) { // vx just stopped + if (!obj->_vx) { // Got 4 directions + if (obj->_vx != obj->_oldvx) { // vx just stopped if (dy >= 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { + } else if (obj->_vx != obj->_oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } break; case 3: case 2: - if (obj->vx != obj->oldvx) { // vx just stopped + if (obj->_vx != obj->_oldvx) { // vx just stopped if (dx > 0) // Left & right only - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } break; } - if (obj->vx || obj->vy) { - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) { + obj->_cycling = kCycleForward; } else { - obj->cycling = kCycleNotCycling; + obj->_cycling = kCycleNotCycling; boundaryCollision(obj); // Must have got hero! } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image break; } case kPathWander2: case kPathWander: if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval - obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath; - obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath; + obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath; + obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath; // Set first image in sequence (if multi-seq object) - if (obj->seqNumb > 1) { - if (!obj->vx && (obj->seqNumb >= 4)) { - if (obj->vx != obj->oldvx) { // vx just stopped - if (obj->vy > 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + if (obj->_seqNumb > 1) { + if (!obj->_vx && (obj->_seqNumb >= 4)) { + if (obj->_vx != obj->_oldvx) { // vx just stopped + if (obj->_vy > 0) + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { - if (obj->vx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + } else if (obj->_vx != obj->_oldvx) { + if (obj->_vx > 0) + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image } - if (obj->vx || obj->vy) - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) + obj->_cycling = kCycleForward; break; default: ; // Really, nothing } // Store boundaries - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2); + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2); } } // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) { + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->currImagePtr; // Get ptr to current image + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates - int x1 = obj->x + currImage->x1; // Left edge of object - int x2 = obj->x + currImage->x2; // Right edge - int y1 = obj->y + currImage->y1; // Top edge - int y2 = obj->y + currImage->y2; // Bottom edge + int x1 = obj->_x + currImage->_x1; // Left edge of object + int x2 = obj->_x + currImage->_x2; // Right edge + int y1 = obj->_y + currImage->_y1; // Top edge + int y2 = obj->_y + currImage->_y2; // Bottom edge - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(x1, x2, y2); // Clear our own boundary // Allowable motion wrt boundary - int dx = deltaX(x1, x2, obj->vx, y2); - if (dx != obj->vx) { + int dx = deltaX(x1, x2, obj->_vx, y2); + if (dx != obj->_vx) { // An object boundary collision! boundaryCollision(obj); - obj->vx = 0; + obj->_vx = 0; } - int dy = deltaY(x1, x2, obj->vy, y2); - if (dy != obj->vy) { + int dy = deltaY(x1, x2, obj->_vy, y2); + if (dy != obj->_vy) { // An object boundary collision! boundaryCollision(obj); - obj->vy = 0; + obj->_vy = 0; } - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) storeBoundary(x1, x2, y2); // Re-store our own boundary - obj->x += dx; // Update object position - obj->y += dy; + obj->_x += dx; // Update object position + obj->_y += dy; // Don't let object go outside screen if (x1 < kEdge) - obj->x = kEdge2; + obj->_x = kEdge2; if (x2 > (kXPix - kEdge)) - obj->x = kXPix - kEdge2 - (x2 - x1); + obj->_x = kXPix - kEdge2 - (x2 - x1); if (y1 < kEdge) - obj->y = kEdge2; + obj->_y = kEdge2; if (y2 > (kYPix - kEdge)) - obj->y = kYPix - kEdge2 - (y2 - y1); + obj->_y = kYPix - kEdge2 - (y2 - y1); - if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != kPathWander2) && (obj->pathType != kPathChase2)) - obj->cycling = kCycleNotCycling; + if ((obj->_vx == 0) && (obj->_vy == 0) && (obj->_pathType != kPathWander2) && (obj->_pathType != kPathChase2)) + obj->_cycling = kCycleNotCycling; } } // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2); + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing - if (_vm->_maze.enabledFl) { - seq_t *currImage = _vm->_hero->currImagePtr; // Get ptr to current image + if (_vm->_maze._enabledFl) { + seq_t *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image // hero coordinates - int x1 = _vm->_hero->x + currImage->x1; // Left edge of object - int x2 = _vm->_hero->x + currImage->x2; // Right edge - int y1 = _vm->_hero->y + currImage->y1; // Top edge - int y2 = _vm->_hero->y + currImage->y2; // Bottom edge + int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object + int x2 = _vm->_hero->_x + currImage->_x2; // Right edge + int y1 = _vm->_hero->_y + currImage->_y1; // Top edge + int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge _vm->_scheduler->processMaze(x1, x2, y1, y2); } @@ -367,15 +367,15 @@ void ObjectHandler_v1w::swapImages(int objIndex1, int objIndex2) { seqList_t tmpSeqList[kMaxSeqNumb]; int seqListSize = sizeof(seqList_t) * kMaxSeqNumb; - memmove(tmpSeqList, _objects[objIndex1].seqList, seqListSize); - memmove(_objects[objIndex1].seqList, _objects[objIndex2].seqList, seqListSize); - memmove(_objects[objIndex2].seqList, tmpSeqList, seqListSize); + memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize); + memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize); + memmove(_objects[objIndex2]._seqList, tmpSeqList, seqListSize); restoreSeq(&_objects[objIndex1]); - _objects[objIndex2].currImagePtr = _objects[objIndex2].seqList[0].seqPtr; + _objects[objIndex2]._currImagePtr = _objects[objIndex2]._seqList[0]._seqPtr; _vm->_heroImage = (_vm->_heroImage == kHeroIndex) ? objIndex2 : kHeroIndex; // Make sure baseline stays constant - _objects[objIndex1].y += _objects[objIndex2].currImagePtr->y2 - _objects[objIndex1].currImagePtr->y2; + _objects[objIndex1]._y += _objects[objIndex2]._currImagePtr->_y2 - _objects[objIndex1]._currImagePtr->_y2; } } // End of namespace Hugo diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp index 4a22fab2c0..025374521c 100644 --- a/engines/hugo/object_v2d.cpp +++ b/engines/hugo/object_v2d.cpp @@ -64,7 +64,7 @@ void ObjectHandler_v2d::updateImages() { for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= kCycleAlmostInvisible)) + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) objindex[num_objs++] = i; } @@ -75,27 +75,27 @@ void ObjectHandler_v2d::updateImages() { for (int i = 0; i < num_objs; i++) { object_t *obj = &_objects[objindex[i]]; // Count down inter-frame timer - if (obj->frameTimer) - obj->frameTimer--; + if (obj->_frameTimer) + obj->_frameTimer--; - if (obj->cycling > kCycleAlmostInvisible) { // Only if visible - switch (obj->cycling) { + if (obj->_cycling > kCycleAlmostInvisible) { // Only if visible + switch (obj->_cycling) { case kCycleNotCycling: - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay); + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay); break; case kCycleForward: - if (obj->frameTimer) // Not time to see next frame yet - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == kPriorityOverOverlay); + if (obj->_frameTimer) // Not time to see next frame yet + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr, obj->_priority == kPriorityOverOverlay); else - _vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == kPriorityOverOverlay); + _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, obj->_priority == kPriorityOverOverlay); break; case kCycleBackward: { - seq_t *seqPtr = obj->currImagePtr; - if (!obj->frameTimer) { // Show next frame - while (seqPtr->nextSeqPtr != obj->currImagePtr) - seqPtr = seqPtr->nextSeqPtr; + seq_t *seqPtr = obj->_currImagePtr; + if (!obj->_frameTimer) { // Show next frame + while (seqPtr->_nextSeqPtr != obj->_currImagePtr) + seqPtr = seqPtr->_nextSeqPtr; } - _vm->_screen->displayFrame(obj->x, obj->y, seqPtr, obj->priority == kPriorityOverOverlay); + _vm->_screen->displayFrame(obj->_x, obj->_y, seqPtr, obj->_priority == kPriorityOverOverlay); break; } default: @@ -109,28 +109,28 @@ void ObjectHandler_v2d::updateImages() { // Cycle any animating objects for (int i = 0; i < num_objs; i++) { object_t *obj = &_objects[objindex[i]]; - if (obj->cycling != kCycleInvisible) { + if (obj->_cycling != kCycleInvisible) { // Only if it's visible - if (obj->cycling == kCycleAlmostInvisible) - obj->cycling = kCycleInvisible; + if (obj->_cycling == kCycleAlmostInvisible) + obj->_cycling = kCycleInvisible; // Now Rotate to next picture in sequence - switch (obj->cycling) { + switch (obj->_cycling) { case kCycleNotCycling: break; case kCycleForward: - if (!obj->frameTimer) { + if (!obj->_frameTimer) { // Time to step to next frame - obj->currImagePtr = obj->currImagePtr->nextSeqPtr; + obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is last frame of sequence // If so, reset frame_timer and decrement n_cycle - if (obj->frameInterval || obj->cycleNumb) { - obj->frameTimer = obj->frameInterval; - for (int j = 0; j < obj->seqNumb; j++) { - if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) { - if (obj->cycleNumb) { // Decr cycleNumb if Non-continous - if (!--obj->cycleNumb) - obj->cycling = kCycleNotCycling; + if (obj->_frameInterval || obj->_cycleNumb) { + obj->_frameTimer = obj->_frameInterval; + for (int j = 0; j < obj->_seqNumb; j++) { + if (obj->_currImagePtr->_nextSeqPtr == obj->_seqList[j]._seqPtr) { + if (obj->_cycleNumb) { // Decr cycleNumb if Non-continous + if (!--obj->_cycleNumb) + obj->_cycling = kCycleNotCycling; } } } @@ -138,20 +138,20 @@ void ObjectHandler_v2d::updateImages() { } break; case kCycleBackward: { - if (!obj->frameTimer) { + if (!obj->_frameTimer) { // Time to step to prev frame - seq_t *seqPtr = obj->currImagePtr; - while (obj->currImagePtr->nextSeqPtr != seqPtr) - obj->currImagePtr = obj->currImagePtr->nextSeqPtr; + seq_t *seqPtr = obj->_currImagePtr; + while (obj->_currImagePtr->_nextSeqPtr != seqPtr) + obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is first frame of sequence // If so, reset frame_timer and decrement n_cycle - if (obj->frameInterval || obj->cycleNumb) { - obj->frameTimer = obj->frameInterval; - for (int j = 0; j < obj->seqNumb; j++) { - if (obj->currImagePtr == obj->seqList[j].seqPtr) { - if (obj->cycleNumb){ // Decr cycleNumb if Non-continous - if (!--obj->cycleNumb) - obj->cycling = kCycleNotCycling; + if (obj->_frameInterval || obj->_cycleNumb) { + obj->_frameTimer = obj->_frameInterval; + for (int j = 0; j < obj->_seqNumb; j++) { + if (obj->_currImagePtr == obj->_seqList[j]._seqPtr) { + if (obj->_cycleNumb){ // Decr cycleNumb if Non-continous + if (!--obj->_cycleNumb) + obj->_cycling = kCycleNotCycling; } } } @@ -162,8 +162,8 @@ void ObjectHandler_v2d::updateImages() { default: break; } - obj->oldx = obj->x; - obj->oldy = obj->y; + obj->_oldx = obj->_x; + obj->_oldy = obj->_y; } } } @@ -184,174 +184,174 @@ void ObjectHandler_v2d::moveObjects() { // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if (obj->screenIndex == *_vm->_screen_p) { - switch (obj->pathType) { + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if (obj->_screenIndex == *_vm->_screen_p) { + switch (obj->_pathType) { case kPathChase: case kPathChase2: { - int8 radius = obj->radius; // Default to object's radius + int8 radius = obj->_radius; // Default to object's radius if (radius < 0) // If radius infinity, use closer value radius = kStepDx; // Allowable motion wrt boundary - int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1; - int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1; + int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1; + int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1; if (abs(dx) <= radius) - obj->vx = 0; + obj->_vx = 0; else - obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath); + obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath); if (abs(dy) <= radius) - obj->vy = 0; + obj->_vy = 0; else - obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath); + obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath); // Set first image in sequence (if multi-seq object) - switch (obj->seqNumb) { + switch (obj->_seqNumb) { case 4: - if (!obj->vx) { // Got 4 directions - if (obj->vx != obj->oldvx) { // vx just stopped + if (!obj->_vx) { // Got 4 directions + if (obj->_vx != obj->_oldvx) { // vx just stopped if (dy > 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { + } else if (obj->_vx != obj->_oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } break; case 3: case 2: - if (obj->vx != obj->oldvx) { // vx just stopped + if (obj->_vx != obj->_oldvx) { // vx just stopped if (dx > 0) // Left & right only - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } break; } - if (obj->vx || obj->vy) { - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) { + obj->_cycling = kCycleForward; } else { - obj->cycling = kCycleNotCycling; + obj->_cycling = kCycleNotCycling; boundaryCollision(obj); // Must have got hero! } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image break; } case kPathWander2: case kPathWander: if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval - obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath; - obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath; + obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath; + obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath; // Set first image in sequence (if multi-seq object) - if (obj->seqNumb > 1) { - if (!obj->vx && (obj->seqNumb >= 4)) { - if (obj->vx != obj->oldvx) { // vx just stopped - if (obj->vy > 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + if (obj->_seqNumb > 1) { + if (!obj->_vx && (obj->_seqNumb >= 4)) { + if (obj->_vx != obj->_oldvx) { // vx just stopped + if (obj->_vy > 0) + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { - if (obj->vx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + } else if (obj->_vx != obj->_oldvx) { + if (obj->_vx > 0) + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image } - if (obj->vx || obj->vy) - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) + obj->_cycling = kCycleForward; break; default: ; // Really, nothing } // Store boundaries - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2); + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2); } } // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) { + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->currImagePtr; // Get ptr to current image + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates - int x1 = obj->x + currImage->x1; // Left edge of object - int x2 = obj->x + currImage->x2; // Right edge - int y1 = obj->y + currImage->y1; // Top edge - int y2 = obj->y + currImage->y2; // Bottom edge + int x1 = obj->_x + currImage->_x1; // Left edge of object + int x2 = obj->_x + currImage->_x2; // Right edge + int y1 = obj->_y + currImage->_y1; // Top edge + int y2 = obj->_y + currImage->_y2; // Bottom edge - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(x1, x2, y2); // Clear our own boundary // Allowable motion wrt boundary - int dx = deltaX(x1, x2, obj->vx, y2); - if (dx != obj->vx) { + int dx = deltaX(x1, x2, obj->_vx, y2); + if (dx != obj->_vx) { // An object boundary collision! boundaryCollision(obj); - obj->vx = 0; + obj->_vx = 0; } - int dy = deltaY(x1, x2, obj->vy, y2); - if (dy != obj->vy) { + int dy = deltaY(x1, x2, obj->_vy, y2); + if (dy != obj->_vy) { // An object boundary collision! boundaryCollision(obj); - obj->vy = 0; + obj->_vy = 0; } - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) storeBoundary(x1, x2, y2); // Re-store our own boundary - obj->x += dx; // Update object position - obj->y += dy; + obj->_x += dx; // Update object position + obj->_y += dy; // Don't let object go outside screen if (x1 < kEdge) - obj->x = kEdge2; + obj->_x = kEdge2; if (x2 > (kXPix - kEdge)) - obj->x = kXPix - kEdge2 - (x2 - x1); + obj->_x = kXPix - kEdge2 - (x2 - x1); if (y1 < kEdge) - obj->y = kEdge2; + obj->_y = kEdge2; if (y2 > (kYPix - kEdge)) - obj->y = kYPix - kEdge2 - (y2 - y1); + obj->_y = kYPix - kEdge2 - (y2 - y1); - if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != kPathWander2) && (obj->pathType != kPathChase2)) - obj->cycling = kCycleNotCycling; + if ((obj->_vx == 0) && (obj->_vy == 0) && (obj->_pathType != kPathWander2) && (obj->_pathType != kPathChase2)) + obj->_cycling = kCycleNotCycling; } } // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2); + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing - if (_vm->_maze.enabledFl) { - seq_t *currImage = _vm->_hero->currImagePtr; // Get ptr to current image + if (_vm->_maze._enabledFl) { + seq_t *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image // hero coordinates - int x1 = _vm->_hero->x + currImage->x1; // Left edge of object - int x2 = _vm->_hero->x + currImage->x2; // Right edge - int y1 = _vm->_hero->y + currImage->y1; // Top edge - int y2 = _vm->_hero->y + currImage->y2; // Bottom edge + int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object + int x2 = _vm->_hero->_x + currImage->_x2; // Right edge + int y1 = _vm->_hero->_y + currImage->_y1; // Top edge + int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge _vm->_scheduler->processMaze(x1, x2, y1, y2); } @@ -361,9 +361,9 @@ void ObjectHandler_v2d::homeIn(const int objIndex1, const int objIndex2, const i // object obj1 will home in on object obj2 object_t *obj1 = &_objects[objIndex1]; object_t *obj2 = &_objects[objIndex2]; - obj1->pathType = kPathAuto; - int dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1; - int dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1; + obj1->_pathType = kPathAuto; + int dx = obj1->_x + obj1->_currImagePtr->_x1 - obj2->_x - obj2->_currImagePtr->_x1; + int dy = obj1->_y + obj1->_currImagePtr->_y1 - obj2->_y - obj2->_currImagePtr->_y1; if (dx == 0) // Don't EVER divide by zero! dx = 1; @@ -371,11 +371,11 @@ void ObjectHandler_v2d::homeIn(const int objIndex1, const int objIndex2, const i dy = 1; if (abs(dx) > abs(dy)) { - obj1->vx = objDx * -sign(dx); - obj1->vy = abs((objDy * dy) / dx) * -sign(dy); + obj1->_vx = objDx * -sign(dx); + obj1->_vy = abs((objDy * dy) / dx) * -sign(dy); } else { - obj1->vy = objDy * -sign(dy); - obj1->vx = abs((objDx * dx) / dy) * -sign(dx); + obj1->_vy = objDy * -sign(dy); + obj1->_vx = abs((objDx * dx) / dy) * -sign(dx); } } } // End of namespace Hugo diff --git a/engines/hugo/object_v3d.cpp b/engines/hugo/object_v3d.cpp index cde7f5fd62..15d5fcd936 100644 --- a/engines/hugo/object_v3d.cpp +++ b/engines/hugo/object_v3d.cpp @@ -65,175 +65,175 @@ void ObjectHandler_v3d::moveObjects() { // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if (obj->screenIndex == *_vm->_screen_p) { - switch (obj->pathType) { + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if (obj->_screenIndex == *_vm->_screen_p) { + switch (obj->_pathType) { case kPathChase: case kPathChase2: { - int8 radius = obj->radius; // Default to object's radius + int8 radius = obj->_radius; // Default to object's radius if (radius < 0) // If radius infinity, use closer value radius = kStepDx; // Allowable motion wrt boundary - int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1; - int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1; + int dx = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1 - obj->_x - currImage->_x1; + int dy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - obj->_y - currImage->_y2 - 1; if (abs(dx) <= radius) - obj->vx = 0; + obj->_vx = 0; else - obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath); + obj->_vx = (dx > 0) ? MIN(dx, obj->_vxPath) : MAX(dx, -obj->_vxPath); if (abs(dy) <= radius) - obj->vy = 0; + obj->_vy = 0; else - obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath); + obj->_vy = (dy > 0) ? MIN(dy, obj->_vyPath) : MAX(dy, -obj->_vyPath); // Set first image in sequence (if multi-seq object) - switch (obj->seqNumb) { + switch (obj->_seqNumb) { case 4: - if (!obj->vx) { // Got 4 directions - if (obj->vx != obj->oldvx) { // vx just stopped + if (!obj->_vx) { // Got 4 directions + if (obj->_vx != obj->_oldvx) { // vx just stopped if (dy >= 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { + } else if (obj->_vx != obj->_oldvx) { if (dx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } break; case 3: case 2: - if (obj->vx != obj->oldvx) { // vx just stopped + if (obj->_vx != obj->_oldvx) { // vx just stopped if (dx > 0) // Left & right only - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } break; } - if (obj->vx || obj->vy) { - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) { + obj->_cycling = kCycleForward; } else { - obj->cycling = kCycleNotCycling; + obj->_cycling = kCycleNotCycling; boundaryCollision(obj); // Must have got hero! } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image break; } case kPathWander2: case kPathWander: if (!_vm->_rnd->getRandomNumber(3 * _vm->_normalTPS)) { // Kick on random interval - obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath; - obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath; + obj->_vx = _vm->_rnd->getRandomNumber(obj->_vxPath << 1) - obj->_vxPath; + obj->_vy = _vm->_rnd->getRandomNumber(obj->_vyPath << 1) - obj->_vyPath; // Set first image in sequence (if multi-seq object) - if (obj->seqNumb > 1) { - if (!obj->vx && (obj->seqNumb >= 4)) { - if (obj->vx != obj->oldvx) { // vx just stopped - if (obj->vy > 0) - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + if (obj->_seqNumb > 1) { + if (!obj->_vx && (obj->_seqNumb >= 4)) { + if (obj->_vx != obj->_oldvx) { // vx just stopped + if (obj->_vy > 0) + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; } - } else if (obj->vx != obj->oldvx) { - if (obj->vx > 0) - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + } else if (obj->_vx != obj->_oldvx) { + if (obj->_vx > 0) + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; else - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; } } - obj->oldvx = obj->vx; - obj->oldvy = obj->vy; - currImage = obj->currImagePtr; // Get (new) ptr to current image + obj->_oldvx = obj->_vx; + obj->_oldvy = obj->_vy; + currImage = obj->_currImagePtr; // Get (new) ptr to current image } - if (obj->vx || obj->vy) - obj->cycling = kCycleForward; + if (obj->_vx || obj->_vy) + obj->_cycling = kCycleForward; break; default: ; // Really, nothing } // Store boundaries - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2); + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + storeBoundary(obj->_x + currImage->_x1, obj->_x + currImage->_x2, obj->_y + currImage->_y2); } } // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) { + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->currImagePtr; // Get ptr to current image + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates - int x1 = obj->x + currImage->x1; // Left edge of object - int x2 = obj->x + currImage->x2; // Right edge - int y1 = obj->y + currImage->y1; // Top edge - int y2 = obj->y + currImage->y2; // Bottom edge + int x1 = obj->_x + currImage->_x1; // Left edge of object + int x2 = obj->_x + currImage->_x2; // Right edge + int y1 = obj->_y + currImage->_y1; // Top edge + int y2 = obj->_y + currImage->_y2; // Bottom edge - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(x1, x2, y2); // Clear our own boundary // Allowable motion wrt boundary - int dx = deltaX(x1, x2, obj->vx, y2); - if (dx != obj->vx) { + int dx = deltaX(x1, x2, obj->_vx, y2); + if (dx != obj->_vx) { // An object boundary collision! boundaryCollision(obj); - obj->vx = 0; + obj->_vx = 0; } - int dy = deltaY(x1, x2, obj->vy, y2); - if (dy != obj->vy) { + int dy = deltaY(x1, x2, obj->_vy, y2); + if (dy != obj->_vy) { // An object boundary collision! boundaryCollision(obj); - obj->vy = 0; + obj->_vy = 0; } - if ((obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) + if ((obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) storeBoundary(x1, x2, y2); // Re-store our own boundary - obj->x += dx; // Update object position - obj->y += dy; + obj->_x += dx; // Update object position + obj->_y += dy; // Don't let object go outside screen if (x1 < kEdge) - obj->x = kEdge2; + obj->_x = kEdge2; if (x2 > (kXPix - kEdge)) - obj->x = kXPix - kEdge2 - (x2 - x1); + obj->_x = kXPix - kEdge2 - (x2 - x1); if (y1 < kEdge) - obj->y = kEdge2; + obj->_y = kEdge2; if (y2 > (kYPix - kEdge)) - obj->y = kYPix - kEdge2 - (y2 - y1); + obj->_y = kYPix - kEdge2 - (y2 - y1); - if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != kPathWander2) && (obj->pathType != kPathChase2)) - obj->cycling = kCycleNotCycling; + if ((obj->_vx == 0) && (obj->_vy == 0) && (obj->_pathType != kPathWander2) && (obj->_pathType != kPathChase2)) + obj->_cycling = kCycleNotCycling; } } // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->currImagePtr; // Get ptr to current image - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > kCycleAlmostInvisible) && (obj->priority == kPriorityFloating)) - clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2); + seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing - if (_vm->_maze.enabledFl) { - seq_t *currImage = _vm->_hero->currImagePtr;// Get ptr to current image + if (_vm->_maze._enabledFl) { + seq_t *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image // hero coordinates - int x1 = _vm->_hero->x + currImage->x1; // Left edge of object - int x2 = _vm->_hero->x + currImage->x2; // Right edge - int y1 = _vm->_hero->y + currImage->y1; // Top edge - int y2 = _vm->_hero->y + currImage->y2; // Bottom edge + int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object + int x2 = _vm->_hero->_x + currImage->_x2; // Right edge + int y1 = _vm->_hero->_y + currImage->_y1; // Top edge + int y2 = _vm->_hero->_y + currImage->_y2; // Bottom edge _vm->_scheduler->processMaze(x1, x2, y1, y2); } @@ -252,15 +252,15 @@ void ObjectHandler_v3d::swapImages(int objIndex1, int objIndex2) { seqList_t tmpSeqList[kMaxSeqNumb]; int seqListSize = sizeof(seqList_t) * kMaxSeqNumb; - memmove(tmpSeqList, _objects[objIndex1].seqList, seqListSize); - memmove(_objects[objIndex1].seqList, _objects[objIndex2].seqList, seqListSize); - memmove(_objects[objIndex2].seqList, tmpSeqList, seqListSize); + memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize); + memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize); + memmove(_objects[objIndex2]._seqList, tmpSeqList, seqListSize); restoreSeq(&_objects[objIndex1]); - _objects[objIndex2].currImagePtr = _objects[objIndex2].seqList[0].seqPtr; + _objects[objIndex2]._currImagePtr = _objects[objIndex2]._seqList[0]._seqPtr; _vm->_heroImage = (_vm->_heroImage == kHeroIndex) ? objIndex2 : kHeroIndex; // Make sure baseline stays constant - _objects[objIndex1].y += _objects[objIndex2].currImagePtr->y2 - _objects[objIndex1].currImagePtr->y2; + _objects[objIndex1]._y += _objects[objIndex2]._currImagePtr->_y2 - _objects[objIndex1]._currImagePtr->_y2; } } // End of namespace Hugo diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp index 4eaed6fecf..b4255e607b 100644 --- a/engines/hugo/parser.cpp +++ b/engines/hugo/parser.cpp @@ -58,21 +58,21 @@ Parser::~Parser() { } uint16 Parser::getCmdDefaultVerbIdx(const uint16 index) const { - return _cmdList[index][0].verbIndex; + return _cmdList[index][0]._verbIndex; } /** * Read a cmd structure from Hugo.dat */ void Parser::readCmd(Common::ReadStream &in, cmd &curCmd) { - curCmd.verbIndex = in.readUint16BE(); - curCmd.reqIndex = in.readUint16BE(); - curCmd.textDataNoCarryIndex = in.readUint16BE(); - curCmd.reqState = in.readByte(); - curCmd.newState = in.readByte(); - curCmd.textDataWrongIndex = in.readUint16BE(); - curCmd.textDataDoneIndex = in.readUint16BE(); - curCmd.actIndex = in.readUint16BE(); + curCmd._verbIndex = in.readUint16BE(); + curCmd._reqIndex = in.readUint16BE(); + curCmd._textDataNoCarryIndex = in.readUint16BE(); + curCmd._reqState = in.readByte(); + curCmd._newState = in.readByte(); + curCmd._textDataWrongIndex = in.readUint16BE(); + curCmd._textDataDoneIndex = in.readUint16BE(); + curCmd._actIndex = in.readUint16BE(); } /** @@ -100,12 +100,12 @@ void Parser::loadCmdList(Common::ReadStream &in) { void Parser::readBG(Common::ReadStream &in, background_t &curBG) { - curBG.verbIndex = in.readUint16BE(); - curBG.nounIndex = in.readUint16BE(); - curBG.commentIndex = in.readSint16BE(); - curBG.matchFl = (in.readByte() != 0); - curBG.roomState = in.readByte(); - curBG.bonusIndex = in.readByte(); + curBG._verbIndex = in.readUint16BE(); + curBG._nounIndex = in.readUint16BE(); + curBG._commentIndex = in.readSint16BE(); + curBG._matchFl = (in.readByte() != 0); + curBG._roomState = in.readByte(); + curBG._bonusIndex = in.readByte(); } /** @@ -165,11 +165,11 @@ const char *Parser::useBG(const char *name) { debugC(1, kDebugEngine, "useBG(%s)", name); objectList_t p = _backgroundObjects[*_vm->_screen_p]; - for (int i = 0; p[i].verbIndex != 0; i++) { - if ((name == _vm->_text->getNoun(p[i].nounIndex, 0) && - p[i].verbIndex != _vm->_look) && - ((p[i].roomState == kStateDontCare) || (p[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) - return _vm->_text->getVerb(p[i].verbIndex, 0); + for (int i = 0; p[i]._verbIndex != 0; i++) { + if ((name == _vm->_text->getNoun(p[i]._nounIndex, 0) && + p[i]._verbIndex != _vm->_look) && + ((p[i]._roomState == kStateDontCare) || (p[i]._roomState == _vm->_screenStates[*_vm->_screen_p]))) + return _vm->_text->getVerb(p[i]._verbIndex, 0); } return 0; @@ -222,7 +222,7 @@ void Parser::charHandler() { _cmdLine[--_cmdLineIndex] = '\0'; break; case Common::KEYCODE_RETURN: // EOL, pass line to line handler - if (_cmdLineIndex && (_vm->_hero->pathType != kPathQuiet)) { + if (_cmdLineIndex && (_vm->_hero->_pathType != kPathQuiet)) { // Remove inventory bar if active if (_vm->_inventory->getInventoryState() == kInventoryActive) _vm->_inventory->setInventoryState(kInventoryUp); @@ -248,9 +248,9 @@ void Parser::charHandler() { _cmdLineCursor = (_cmdLineCursor == '_') ? ' ' : '_'; // See if recall button pressed - if (gameStatus.recallFl) { + if (gameStatus._recallFl) { // Copy previous line to current cmdline - gameStatus.recallFl = false; + gameStatus._recallFl = false; strcpy(_cmdLine, _vm->_line); _cmdLineIndex = strlen(_cmdLine); } @@ -259,9 +259,9 @@ void Parser::charHandler() { sprintf(_vm->_scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_vm->_config.turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config.soundFl) ? "On" : "Off"); // See if "look" button pressed - if (gameStatus.lookFl) { + if (gameStatus._lookFl) { command("look around"); - gameStatus.lookFl = false; + gameStatus._lookFl = false; } } @@ -288,8 +288,8 @@ void Parser::keyHandler(Common::Event event) { _vm->_file->restoreGame(0); break; case Common::KEYCODE_s: - if (gameStatus.viewState == kViewPlay) { - if (gameStatus.gameOverFl) + if (gameStatus._viewState == kViewPlay) { + if (gameStatus._gameOverFl) _vm->gameOverMsg(); else _vm->_file->saveGame(-1, Common::String()); @@ -304,8 +304,8 @@ void Parser::keyHandler(Common::Event event) { // Process key down event - called from OnKeyDown() switch (nChar) { // Set various toggle states case Common::KEYCODE_ESCAPE: // Escape key, may want to QUIT - if (gameStatus.viewState == kViewIntro) - gameStatus.skipIntroFl = true; + if (gameStatus._viewState == kViewIntro) + gameStatus._skipIntroFl = true; else { if (_vm->_inventory->getInventoryState() == kInventoryActive) // Remove inventory, if displayed _vm->_inventory->setInventoryState(kInventoryUp); @@ -333,7 +333,7 @@ void Parser::keyHandler(Common::Event event) { break; case Common::KEYCODE_F1: // User Help (DOS) if (_checkDoubleF1Fl) - gameStatus.helpFl = true; + gameStatus._helpFl = true; else _vm->_screen->userHelp(); _checkDoubleF1Fl = !_checkDoubleF1Fl; @@ -343,11 +343,11 @@ void Parser::keyHandler(Common::Event event) { _vm->_sound->toggleMusic(); break; case Common::KEYCODE_F3: // Repeat last line - gameStatus.recallFl = true; + gameStatus._recallFl = true; break; case Common::KEYCODE_F4: // Save game - if (gameStatus.viewState == kViewPlay) { - if (gameStatus.gameOverFl) + if (gameStatus._viewState == kViewPlay) { + if (gameStatus._gameOverFl) _vm->gameOverMsg(); else _vm->_file->saveGame(-1, Common::String()); @@ -366,7 +366,7 @@ void Parser::keyHandler(Common::Event event) { warning("STUB: F9 (DOS) - BossKey"); break; default: // Any other key - if (!gameStatus.storyModeFl) { // Keyboard disabled + if (!gameStatus._storyModeFl) { // Keyboard disabled // Add printable keys to ring buffer uint16 bnext = _putIndex + 1; if (bnext >= sizeof(_ringBuffer)) @@ -452,7 +452,7 @@ void Parser::showDosInventory() const { for (int i = 0; i < _vm->_object->_numObj; i++) { // Find widths of 2 columns if (_vm->_object->isCarried(i)) { - uint16 len = strlen(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)); + uint16 len = strlen(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)); if (index++ & 1) // Right hand column len2 = (len > len2) ? len : len2; else @@ -473,9 +473,9 @@ void Parser::showDosInventory() const { for (int i = 0; i < _vm->_object->_numObj; i++) { // Assign strings if (_vm->_object->isCarried(i)) { if (index++ & 1) - buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)) + "\n"; + buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)) + "\n"; else - buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2)) + Common::String(blanks, len1 - strlen(_vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 2))); + buffer += Common::String(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2)) + Common::String(blanks, len1 - strlen(_vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 2))); } } if (index & 1) diff --git a/engines/hugo/parser.h b/engines/hugo/parser.h index f8b9d9f13b..18f4916b1e 100644 --- a/engines/hugo/parser.h +++ b/engines/hugo/parser.h @@ -48,14 +48,14 @@ enum seqTextParser { * The following determines how a verb is acted on, for an object */ struct cmd { - uint16 verbIndex; // the verb - uint16 reqIndex; // ptr to list of required objects - uint16 textDataNoCarryIndex; // ptr to string if any of above not carried - byte reqState; // required state for verb to be done - byte newState; // new states if verb done - uint16 textDataWrongIndex; // ptr to string if wrong state - uint16 textDataDoneIndex; // ptr to string if verb done - uint16 actIndex; // Ptr to action list if verb done + uint16 _verbIndex; // the verb + uint16 _reqIndex; // ptr to list of required objects + uint16 _textDataNoCarryIndex; // ptr to string if any of above not carried + byte _reqState; // required state for verb to be done + byte _newState; // new states if verb done + uint16 _textDataWrongIndex; // ptr to string if wrong state + uint16 _textDataDoneIndex; // ptr to string if verb done + uint16 _actIndex; // Ptr to action list if verb done }; /** @@ -65,12 +65,12 @@ struct cmd { * "don't understand" we produce an interesting msg to keep user sane. */ struct background_t { - uint16 verbIndex; - uint16 nounIndex; - int commentIndex; // Index of comment produced on match - bool matchFl; // TRUE if noun must match when present - byte roomState; // "State" of room. Comments might differ. - byte bonusIndex; // Index of bonus score (0 = no bonus) + uint16 _verbIndex; + uint16 _nounIndex; + int _commentIndex; // Index of comment produced on match + bool _matchFl; // TRUE if noun must match when present + byte _roomState; // "State" of room. Comments might differ. + byte _bonusIndex; // Index of bonus score (0 = no bonus) }; typedef background_t *objectList_t; diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp index ccd428311b..aa43cce536 100644 --- a/engines/hugo/parser_v1d.cpp +++ b/engines/hugo/parser_v1d.cpp @@ -81,32 +81,32 @@ const char *Parser_v1d::findNextNoun(const char *noun) const { bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, char *comment) const { debugC(1, kDebugParser, "isNear(%s, %s, obj, %s)", verb, noun, comment); - if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive + if (!noun && !obj->_verbOnlyFl) { // No noun specified & object not context senesitive return false; - } else if (noun && (noun != _vm->_text->getNoun(obj->nounIndex, 0))) { // Noun specified & not same as object + } else if (noun && (noun != _vm->_text->getNoun(obj->_nounIndex, 0))) { // Noun specified & not same as object return false; - } else if (obj->carriedFl) { // Object is being carried + } else if (obj->_carriedFl) { // Object is being carried return true; - } else if (obj->screenIndex != *_vm->_screen_p) { // Not in same screen - if (obj->objValue) + } else if (obj->_screenIndex != *_vm->_screen_p) { // Not in same screen + if (obj->_objValue) strcpy (comment, _vm->_text->getTextParser(kCmtAny4)); return false; } - if (obj->cycling == kCycleInvisible) { - if (obj->seqNumb) { // There is an image + if (obj->_cycling == kCycleInvisible) { + if (obj->_seqNumb) { // There is an image strcpy(comment, _vm->_text->getTextParser(kCmtAny5)); return false; } else { // No image, assume visible - if ((obj->radius < 0) || - ((abs(obj->x - _vm->_hero->x) <= obj->radius) && - (abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) { + if ((obj->_radius < 0) || + ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) && + (abs(obj->_y - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) { return true; } else { // User is either not close enough (stationary, valueless objects) // or is not carrying it (small, portable objects of value) if (noun) { // Don't say unless object specified - if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) strcpy(comment, _vm->_text->getTextParser(kCmtAny4)); else strcpy(comment, _vm->_text->getTextParser(kCmtClose)); @@ -116,15 +116,15 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, ch } } - if ((obj->radius < 0) || - ((abs(obj->x - _vm->_hero->x) <= obj->radius) && - (abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) { + if ((obj->_radius < 0) || + ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) && + (abs(obj->_y + obj->_currImagePtr->_y2 - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) { return true; } else { // User is either not close enough (stationary, valueless objects) // or is not carrying it (small, portable objects of value) if (noun) { // Don't say unless object specified - if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) strcpy(comment, _vm->_text->getTextParser(kCmtAny4)); else strcpy(comment, _vm->_text->getTextParser(kCmtClose)); @@ -143,28 +143,28 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, ch bool Parser_v1d::isGenericVerb_v1(const char *word, object_t *obj) { debugC(1, kDebugParser, "isGenericVerb(%s, object_t *obj)", word); - if (!obj->genericCmd) + if (!obj->_genericCmd) return false; // Following is equivalent to switch, but couldn't do one if (word == _vm->_text->getVerb(_vm->_look, 0)) { - if ((LOOK & obj->genericCmd) == LOOK) - Utils::notifyBox(_vm->_text->getTextData(obj->dataIndex)); + if ((LOOK & obj->_genericCmd) == LOOK) + Utils::notifyBox(_vm->_text->getTextData(obj->_dataIndex)); else Utils::notifyBox(_vm->_text->getTextParser(kTBUnusual_1d)); } else if (word == _vm->_text->getVerb(_vm->_take, 0)) { - if (obj->carriedFl) + if (obj->_carriedFl) Utils::notifyBox(_vm->_text->getTextParser(kTBHave)); - else if ((TAKE & obj->genericCmd) == TAKE) + else if ((TAKE & obj->_genericCmd) == TAKE) takeObject(obj); - else if (!obj->verbOnlyFl) // Make sure not taking object in context! + else if (!obj->_verbOnlyFl) // Make sure not taking object in context! Utils::notifyBox(_vm->_text->getTextParser(kTBNoUse)); else return false; } else if (word == _vm->_text->getVerb(_vm->_drop, 0)) { - if (!obj->carriedFl) + if (!obj->_carriedFl) Utils::notifyBox(_vm->_text->getTextParser(kTBDontHave)); - else if ((DROP & obj->genericCmd) == DROP) + else if ((DROP & obj->_genericCmd) == DROP) dropObject(obj); else Utils::notifyBox(_vm->_text->getTextParser(kTBNeed)); @@ -185,42 +185,42 @@ bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) { debugC(1, kDebugParser, "isObjectVerb(%s, object_t *obj)", word); // First, find matching verb in cmd list - uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands + uint16 cmdIndex = obj->_cmdIndex; // ptr to list of commands if (!cmdIndex) // No commands for this obj return false; int i; - for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd - if (!strcmp(word, _vm->_text->getVerb(_cmdList[cmdIndex][i].verbIndex, 0))) // Is this verb catered for? + for (i = 0; _cmdList[cmdIndex][i]._verbIndex != 0; i++) { // For each cmd + if (!strcmp(word, _vm->_text->getVerb(_cmdList[cmdIndex][i]._verbIndex, 0))) // Is this verb catered for? break; } - if (_cmdList[cmdIndex][i].verbIndex == 0) // No + if (_cmdList[cmdIndex][i]._verbIndex == 0) // No return false; // Verb match found, check all required objects are being carried cmd *cmnd = &_cmdList[cmdIndex][i]; // ptr to struct cmd - if (cmnd->reqIndex) { // At least 1 thing in list - uint16 *reqs = _arrayReqs[cmnd->reqIndex]; // ptr to list of required objects + if (cmnd->_reqIndex) { // At least 1 thing in list + uint16 *reqs = _arrayReqs[cmnd->_reqIndex]; // ptr to list of required objects for (i = 0; reqs[i]; i++) { // for each obj if (!_vm->_object->isCarrying(reqs[i])) { - Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataNoCarryIndex)); + Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataNoCarryIndex)); return true; } } } // Required objects are present, now check state is correct - if ((obj->state != cmnd->reqState) && (cmnd->reqState != kStateDontCare)){ - Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataWrongIndex)); + if ((obj->_state != cmnd->_reqState) && (cmnd->_reqState != kStateDontCare)){ + Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataWrongIndex)); return true; } // Everything checked. Change the state and carry out any actions - if (cmnd->reqState != kStateDontCare) // Don't change new state if required state didn't care - obj->state = cmnd->newState; - Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataDoneIndex)); - _vm->_scheduler->insertActionList(cmnd->actIndex); + if (cmnd->_reqState != kStateDontCare) // Don't change new state if required state didn't care + obj->_state = cmnd->_newState; + Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataDoneIndex)); + _vm->_scheduler->insertActionList(cmnd->_actIndex); // Special case if verb is Take or Drop. Assume additional generic actions if ((word == _vm->_text->getVerb(_vm->_take, 0)) || (word == _vm->_text->getVerb(_vm->_drop, 0))) isGenericVerb_v1(word, obj); @@ -237,9 +237,9 @@ bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, objectL if (!noun) return false; - for (int i = 0; obj[i].verbIndex; i++) { - if ((verb == _vm->_text->getVerb(obj[i].verbIndex, 0)) && (noun == _vm->_text->getNoun(obj[i].nounIndex, 0))) { - Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex)); + for (int i = 0; obj[i]._verbIndex; i++) { + if ((verb == _vm->_text->getVerb(obj[i]._verbIndex, 0)) && (noun == _vm->_text->getNoun(obj[i]._nounIndex, 0))) { + Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex)); return true; } } @@ -252,13 +252,13 @@ bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, objectL void Parser_v1d::takeObject(object_t *obj) { debugC(1, kDebugParser, "takeObject(object_t *obj)"); - obj->carriedFl = true; - if (obj->seqNumb) // Don't change if no image to display - obj->cycling = kCycleAlmostInvisible; + obj->_carriedFl = true; + if (obj->_seqNumb) // Don't change if no image to display + obj->_cycling = kCycleAlmostInvisible; - _vm->adjustScore(obj->objValue); + _vm->adjustScore(obj->_objValue); - Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->nounIndex, TAKE_NAME))); + Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->_nounIndex, TAKE_NAME))); } /** @@ -267,13 +267,13 @@ void Parser_v1d::takeObject(object_t *obj) { void Parser_v1d::dropObject(object_t *obj) { debugC(1, kDebugParser, "dropObject(object_t *obj)"); - obj->carriedFl = false; - obj->screenIndex = *_vm->_screen_p; - if (obj->seqNumb) // Don't change if no image to display - obj->cycling = kCycleNotCycling; - obj->x = _vm->_hero->x - 1; - obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; - _vm->adjustScore(-obj->objValue); + obj->_carriedFl = false; + obj->_screenIndex = *_vm->_screen_p; + if (obj->_seqNumb) // Don't change if no image to display + obj->_cycling = kCycleNotCycling; + obj->_x = _vm->_hero->_x - 1; + obj->_y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1; + _vm->adjustScore(-obj->_objValue); Utils::notifyBox(_vm->_text->getTextParser(kTBOk)); } @@ -284,15 +284,15 @@ void Parser_v1d::dropObject(object_t *obj) { bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, objectList_t obj) const { debugC(1, kDebugParser, "isCatchallVerb(%d, %s, %s, object_list_t obj)", (testNounFl) ? 1 : 0, noun, verb); - if (_vm->_maze.enabledFl) + if (_vm->_maze._enabledFl) return false; if (testNounFl && !noun) return false; - for (int i = 0; obj[i].verbIndex; i++) { - if ((verb == _vm->_text->getVerb(obj[i].verbIndex, 0)) && ((noun == _vm->_text->getNoun(obj[i].nounIndex, 0)) || (obj[i].nounIndex == 0))) { - Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex)); + for (int i = 0; obj[i]._verbIndex; i++) { + if ((verb == _vm->_text->getVerb(obj[i]._verbIndex, 0)) && ((noun == _vm->_text->getNoun(obj[i]._nounIndex, 0)) || (obj[i]._nounIndex == 0))) { + Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex)); return true; } } @@ -310,7 +310,7 @@ void Parser_v1d::lineHandler() { // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { _vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh); - gameStatus.godModeFl = !gameStatus.godModeFl; + gameStatus._godModeFl = !gameStatus._godModeFl; return; } @@ -321,7 +321,7 @@ void Parser_v1d::lineHandler() { // fetch Hero carries named object // fetch all Hero carries all possible objects // find Takes hero to screen containing named object - if (gameStatus.godModeFl) { + if (gameStatus._godModeFl) { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { @@ -335,7 +335,7 @@ void Parser_v1d::lineHandler() { // Special code to allow me to get objects from anywhere if (strstr(_vm->_line, "fetch all")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (_vm->_object->_objects[i].genericCmd & TAKE) + if (_vm->_object->_objects[i]._genericCmd & TAKE) takeObject(&_vm->_object->_objects[i]); } return; @@ -343,7 +343,7 @@ void Parser_v1d::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -353,8 +353,8 @@ void Parser_v1d::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { - _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { + _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex); return; } } @@ -369,7 +369,7 @@ void Parser_v1d::lineHandler() { // SAVE/RESTORE if (!strcmp("save", _vm->_line)) { - if (gameStatus.gameOverFl) + if (gameStatus._gameOverFl) _vm->gameOverMsg(); else _vm->_file->saveGame(-1, Common::String()); @@ -387,7 +387,7 @@ void Parser_v1d::lineHandler() { if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces! return; - if (gameStatus.gameOverFl) { + if (gameStatus._gameOverFl) { // No commands allowed! _vm->gameOverMsg(); return; @@ -425,8 +425,8 @@ void Parser_v1d::lineHandler() { void Parser_v1d::showInventory() const { status_t &gameStatus = _vm->getGameStatus(); - if (gameStatus.viewState == kViewPlay) { - if (gameStatus.gameOverFl) + if (gameStatus._viewState == kViewPlay) { + if (gameStatus._gameOverFl) _vm->gameOverMsg(); else showDosInventory(); diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp index b1657c3bf4..832e6fd1b0 100644 --- a/engines/hugo/parser_v1w.cpp +++ b/engines/hugo/parser_v1w.cpp @@ -61,7 +61,7 @@ void Parser_v1w::lineHandler() { // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { _vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh); - gameStatus.godModeFl = !gameStatus.godModeFl; + gameStatus._godModeFl = !gameStatus._godModeFl; return; } @@ -72,7 +72,7 @@ void Parser_v1w::lineHandler() { // fetch Hero carries named object // fetch all Hero carries all possible objects // find Takes hero to screen containing named object - if (gameStatus.godModeFl) { + if (gameStatus._godModeFl) { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { @@ -86,7 +86,7 @@ void Parser_v1w::lineHandler() { // Special code to allow me to get objects from anywhere if (strstr(_vm->_line, "fetch all")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (_vm->_object->_objects[i].genericCmd & TAKE) + if (_vm->_object->_objects[i]._genericCmd & TAKE) takeObject(&_vm->_object->_objects[i]); } return; @@ -94,7 +94,7 @@ void Parser_v1w::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -104,8 +104,8 @@ void Parser_v1w::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { - _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { + _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex); return; } } @@ -121,12 +121,12 @@ void Parser_v1w::lineHandler() { } // SAVE/RESTORE - if (!strcmp("save", _vm->_line) && gameStatus.viewState == kViewPlay) { + if (!strcmp("save", _vm->_line) && gameStatus._viewState == kViewPlay) { _vm->_file->saveGame(-1, Common::String()); return; } - if (!strcmp("restore", _vm->_line) && (gameStatus.viewState == kViewPlay || gameStatus.viewState == kViewIdle)) { + if (!strcmp("restore", _vm->_line) && (gameStatus._viewState == kViewPlay || gameStatus._viewState == kViewIdle)) { _vm->_file->restoreGame(-1); return; } @@ -137,7 +137,7 @@ void Parser_v1w::lineHandler() { if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces! return; - if (gameStatus.gameOverFl) { + if (gameStatus._gameOverFl) { // No commands allowed! _vm->gameOverMsg(); return; @@ -148,7 +148,7 @@ void Parser_v1w::lineHandler() { // Test for nearby objects referenced explicitly for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; - if (isWordPresent(_vm->_text->getNounArray(obj->nounIndex))) { + if (isWordPresent(_vm->_text->getNounArray(obj->_nounIndex))) { if (isObjectVerb_v3(obj, farComment) || isGenericVerb_v3(obj, farComment)) return; } @@ -158,7 +158,7 @@ void Parser_v1w::lineHandler() { // Note comment is unused if not near. for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; - if (obj->verbOnlyFl) { + if (obj->_verbOnlyFl) { char contextComment[kCompLineSize * 5] = ""; // Unused comment for context objects if (isObjectVerb_v3(obj, contextComment) || isGenericVerb_v3(obj, contextComment)) return; @@ -185,7 +185,7 @@ void Parser_v1w::lineHandler() { // Nothing matches. Report recognition success to user. const char *verb = findVerb(); const char *noun = findNoun(); - if (verb == _vm->_text->getVerb(_vm->_look, 0) && _vm->_maze.enabledFl) { + if (verb == _vm->_text->getVerb(_vm->_look, 0) && _vm->_maze._enabledFl) { Utils::notifyBox(_vm->_text->getTextParser(kTBMaze)); _vm->_object->showTakeables(); } else if (verb && noun) { // A combination I didn't think of @@ -202,14 +202,14 @@ void Parser_v1w::lineHandler() { void Parser_v1w::showInventory() const { status_t &gameStatus = _vm->getGameStatus(); istate_t inventState = _vm->_inventory->getInventoryState(); - if (gameStatus.gameOverFl) { + if (gameStatus._gameOverFl) { _vm->gameOverMsg(); - } else if ((inventState == kInventoryOff) && (gameStatus.viewState == kViewPlay)) { + } else if ((inventState == kInventoryOff) && (gameStatus._viewState == kViewPlay)) { _vm->_inventory->setInventoryState(kInventoryDown); - gameStatus.viewState = kViewInvent; + gameStatus._viewState = kViewInvent; } else if (inventState == kInventoryActive) { _vm->_inventory->setInventoryState(kInventoryUp); - gameStatus.viewState = kViewInvent; + gameStatus._viewState = kViewInvent; } } diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp index 0095c4d726..2daf3c5e9f 100644 --- a/engines/hugo/parser_v2d.cpp +++ b/engines/hugo/parser_v2d.cpp @@ -60,7 +60,7 @@ void Parser_v2d::lineHandler() { // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { _vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh); - gameStatus.godModeFl = !gameStatus.godModeFl; + gameStatus._godModeFl = !gameStatus._godModeFl; return; } @@ -71,7 +71,7 @@ void Parser_v2d::lineHandler() { // fetch Hero carries named object // fetch all Hero carries all possible objects // find Takes hero to screen containing named object - if (gameStatus.godModeFl) { + if (gameStatus._godModeFl) { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { @@ -85,7 +85,7 @@ void Parser_v2d::lineHandler() { // Special code to allow me to get objects from anywhere if (strstr(_vm->_line, "fetch all")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (_vm->_object->_objects[i].genericCmd & TAKE) + if (_vm->_object->_objects[i]._genericCmd & TAKE) takeObject(&_vm->_object->_objects[i]); } return; @@ -93,7 +93,7 @@ void Parser_v2d::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -103,8 +103,8 @@ void Parser_v2d::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { - _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { + _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex); return; } } @@ -119,7 +119,7 @@ void Parser_v2d::lineHandler() { // SAVE/RESTORE if (!strcmp("save", _vm->_line)) { - if (gameStatus.gameOverFl) + if (gameStatus._gameOverFl) _vm->gameOverMsg(); else _vm->_file->saveGame(-1, Common::String()); @@ -137,7 +137,7 @@ void Parser_v2d::lineHandler() { if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces! return; - if (gameStatus.gameOverFl) { + if (gameStatus._gameOverFl) { // No commands allowed! _vm->gameOverMsg(); return; @@ -172,7 +172,7 @@ void Parser_v2d::lineHandler() { && !isCatchallVerb_v1(false, noun, verb, _catchallList)) { if (*farComment != '\0') { // An object matched but not near enough Utils::notifyBox(farComment); - } else if (_vm->_maze.enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) { + } else if (_vm->_maze._enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) { Utils::notifyBox(_vm->_text->getTextParser(kTBMaze)); _vm->_object->showTakeables(); } else if (verb && noun) { // A combination I didn't think of diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp index b45e9186b3..abfe263f6e 100644 --- a/engines/hugo/parser_v3d.cpp +++ b/engines/hugo/parser_v3d.cpp @@ -60,7 +60,7 @@ void Parser_v3d::lineHandler() { // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { _vm->_sound->playSound(!_vm->_soundTest, kSoundPriorityHigh); - gameStatus.godModeFl = !gameStatus.godModeFl; + gameStatus._godModeFl = !gameStatus._godModeFl; return; } @@ -71,7 +71,7 @@ void Parser_v3d::lineHandler() { // fetch Hero carries named object // fetch all Hero carries all possible objects // find Takes hero to screen containing named object - if (gameStatus.godModeFl) { + if (gameStatus._godModeFl) { // Special code to allow me to go straight to any screen if (strstr(_vm->_line, "goto")) { for (int i = 0; i < _vm->_numScreens; i++) { @@ -85,7 +85,7 @@ void Parser_v3d::lineHandler() { // Special code to allow me to get objects from anywhere if (strstr(_vm->_line, "fetch all")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (_vm->_object->_objects[i].genericCmd & TAKE) + if (_vm->_object->_objects[i]._genericCmd & TAKE) takeObject(&_vm->_object->_objects[i]); } return; @@ -93,7 +93,7 @@ void Parser_v3d::lineHandler() { if (strstr(_vm->_line, "fetch")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { + if (!scumm_stricmp(&_vm->_line[strlen("fetch") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { takeObject(&_vm->_object->_objects[i]); return; } @@ -103,8 +103,8 @@ void Parser_v3d::lineHandler() { // Special code to allow me to goto objects if (strstr(_vm->_line, "find")) { for (int i = 0; i < _vm->_object->_numObj; i++) { - if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i].nounIndex, 0))) { - _vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex); + if (!scumm_stricmp(&_vm->_line[strlen("find") + 1], _vm->_text->getNoun(_vm->_object->_objects[i]._nounIndex, 0))) { + _vm->_scheduler->newScreen(_vm->_object->_objects[i]._screenIndex); return; } } @@ -121,7 +121,7 @@ void Parser_v3d::lineHandler() { // SAVE/RESTORE if (!strcmp("save", _vm->_line)) { - if (gameStatus.gameOverFl) + if (gameStatus._gameOverFl) _vm->gameOverMsg(); else _vm->_file->saveGame(-1, Common::String()); @@ -139,7 +139,7 @@ void Parser_v3d::lineHandler() { if (strspn(_vm->_line, " ") == strlen(_vm->_line)) // Nothing but spaces! return; - if (gameStatus.gameOverFl) { + if (gameStatus._gameOverFl) { // No commands allowed! _vm->gameOverMsg(); return; @@ -150,7 +150,7 @@ void Parser_v3d::lineHandler() { // Test for nearby objects referenced explicitly for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; - if (isWordPresent(_vm->_text->getNounArray(obj->nounIndex))) { + if (isWordPresent(_vm->_text->getNounArray(obj->_nounIndex))) { if (isObjectVerb_v3(obj, farComment) || isGenericVerb_v3(obj, farComment)) return; } @@ -160,7 +160,7 @@ void Parser_v3d::lineHandler() { // Note comment is unused if not near. for (int i = 0; i < _vm->_object->_numObj; i++) { object_t *obj = &_vm->_object->_objects[i]; - if (obj->verbOnlyFl) { + if (obj->_verbOnlyFl) { char contextComment[kCompLineSize * 5] = ""; // Unused comment for context objects if (isObjectVerb_v3(obj, contextComment) || isGenericVerb_v3(obj, contextComment)) return; @@ -208,47 +208,47 @@ bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) { debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment); // First, find matching verb in cmd list - uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands + uint16 cmdIndex = obj->_cmdIndex; // ptr to list of commands if (cmdIndex == 0) // No commands for this obj return false; int i; - for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd - if (isWordPresent(_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex))) // Was this verb used? + for (i = 0; _cmdList[cmdIndex][i]._verbIndex != 0; i++) { // For each cmd + if (isWordPresent(_vm->_text->getVerbArray(_cmdList[cmdIndex][i]._verbIndex))) // Was this verb used? break; } - if (_cmdList[cmdIndex][i].verbIndex == 0) // No verbs used. + if (_cmdList[cmdIndex][i]._verbIndex == 0) // No verbs used. return false; // Verb match found. Check if object is Near - char *verb = *_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex); + char *verb = *_vm->_text->getVerbArray(_cmdList[cmdIndex][i]._verbIndex); if (!isNear_v3(obj, verb, comment)) return false; // Check all required objects are being carried cmd *cmnd = &_cmdList[cmdIndex][i]; // ptr to struct cmd - if (cmnd->reqIndex) { // At least 1 thing in list - uint16 *reqs = _arrayReqs[cmnd->reqIndex]; // ptr to list of required objects + if (cmnd->_reqIndex) { // At least 1 thing in list + uint16 *reqs = _arrayReqs[cmnd->_reqIndex]; // ptr to list of required objects for (i = 0; reqs[i]; i++) { // for each obj if (!_vm->_object->isCarrying(reqs[i])) { - Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataNoCarryIndex)); + Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataNoCarryIndex)); return true; } } } // Required objects are present, now check state is correct - if ((obj->state != cmnd->reqState) && (cmnd->reqState != kStateDontCare)) { - Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataWrongIndex)); + if ((obj->_state != cmnd->_reqState) && (cmnd->_reqState != kStateDontCare)) { + Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataWrongIndex)); return true; } // Everything checked. Change the state and carry out any actions - if (cmnd->reqState != kStateDontCare) // Don't change new state if required state didn't care - obj->state = cmnd->newState; - Utils::notifyBox(_vm->_text->getTextData(cmnd->textDataDoneIndex)); - _vm->_scheduler->insertActionList(cmnd->actIndex); + if (cmnd->_reqState != kStateDontCare) // Don't change new state if required state didn't care + obj->_state = cmnd->_newState; + Utils::notifyBox(_vm->_text->getTextData(cmnd->_textDataDoneIndex)); + _vm->_scheduler->insertActionList(cmnd->_actIndex); // See if any additional generic actions if ((verb == _vm->_text->getVerb(_vm->_look, 0)) || (verb == _vm->_text->getVerb(_vm->_take, 0)) || (verb == _vm->_text->getVerb(_vm->_drop, 0))) @@ -262,18 +262,18 @@ bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) { bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) { debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment); - if (!obj->genericCmd) + if (!obj->_genericCmd) return false; // Following is equivalent to switch, but couldn't do one if (isWordPresent(_vm->_text->getVerbArray(_vm->_look)) && isNear_v3(obj, _vm->_text->getVerb(_vm->_look, 0), comment)) { // Test state-dependent look before general look - if ((obj->genericCmd & LOOK_S) == LOOK_S) { - Utils::notifyBox(_vm->_text->getTextData(obj->stateDataIndex[obj->state])); + if ((obj->_genericCmd & LOOK_S) == LOOK_S) { + Utils::notifyBox(_vm->_text->getTextData(obj->_stateDataIndex[obj->_state])); } else { - if ((LOOK & obj->genericCmd) == LOOK) { - if (obj->dataIndex != 0) - Utils::notifyBox(_vm->_text->getTextData(obj->dataIndex)); + if ((LOOK & obj->_genericCmd) == LOOK) { + if (obj->_dataIndex != 0) + Utils::notifyBox(_vm->_text->getTextData(obj->_dataIndex)); else return false; } else { @@ -281,22 +281,22 @@ bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) { } } } else if (isWordPresent(_vm->_text->getVerbArray(_vm->_take)) && isNear_v3(obj, _vm->_text->getVerb(_vm->_take, 0), comment)) { - if (obj->carriedFl) + if (obj->_carriedFl) Utils::notifyBox(_vm->_text->getTextParser(kTBHave)); - else if ((TAKE & obj->genericCmd) == TAKE) + else if ((TAKE & obj->_genericCmd) == TAKE) takeObject(obj); - else if (obj->cmdIndex) // No comment if possible commands + else if (obj->_cmdIndex) // No comment if possible commands return false; - else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context! + else if (!obj->_verbOnlyFl && (TAKE & obj->_genericCmd) == TAKE) // Make sure not taking object in context! Utils::notifyBox(_vm->_text->getTextParser(kTBNoUse)); else return false; } else if (isWordPresent(_vm->_text->getVerbArray(_vm->_drop))) { - if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP)) + if (!obj->_carriedFl && ((DROP & obj->_genericCmd) == DROP)) Utils::notifyBox(_vm->_text->getTextParser(kTBDontHave)); - else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP)) + else if (obj->_carriedFl && ((DROP & obj->_genericCmd) == DROP)) dropObject(obj); - else if (obj->cmdIndex == 0) + else if (obj->_cmdIndex == 0) Utils::notifyBox(_vm->_text->getTextParser(kTBNeed)); else return false; @@ -316,32 +316,32 @@ bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) { bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const { debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment); - if (obj->carriedFl) // Object is being carried + if (obj->_carriedFl) // Object is being carried return true; - if (obj->screenIndex != *_vm->_screen_p) { + if (obj->_screenIndex != *_vm->_screen_p) { // Not in same screen - if (obj->objValue) + if (obj->_objValue) strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); else strcpy(comment, _vm->_text->getTextParser(kCmtAny2)); return false; } - if (obj->cycling == kCycleInvisible) { - if (obj->seqNumb) { + if (obj->_cycling == kCycleInvisible) { + if (obj->_seqNumb) { // There is an image strcpy(comment, _vm->_text->getTextParser(kCmtAny3)); return false; } else { // No image, assume visible - if ((obj->radius < 0) || - ((abs(obj->x - _vm->_hero->x) <= obj->radius) && - (abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) { + if ((obj->_radius < 0) || + ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) && + (abs(obj->_y - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) { return true; } else { // User is not close enough - if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); else strcpy(comment, _vm->_text->getTextParser(kCmtClose)); @@ -350,13 +350,13 @@ bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const } } - if ((obj->radius < 0) || - ((abs(obj->x - _vm->_hero->x) <= obj->radius) && - (abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) { + if ((obj->_radius < 0) || + ((abs(obj->_x - _vm->_hero->_x) <= obj->_radius) && + (abs(obj->_y + obj->_currImagePtr->_y2 - _vm->_hero->_y - _vm->_hero->_currImagePtr->_y2) <= obj->_radius))) { return true; } else { // User is not close enough - if (obj->objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) + if (obj->_objValue && (verb != _vm->_text->getVerb(_vm->_take, 0))) strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); else strcpy(comment, _vm->_text->getTextParser(kCmtClose)); @@ -371,15 +371,15 @@ bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const void Parser_v3d::takeObject(object_t *obj) { debugC(1, kDebugParser, "takeObject(object_t *obj)"); - obj->carriedFl = true; - if (obj->seqNumb) { // Don't change if no image to display - obj->cycling = kCycleInvisible; + obj->_carriedFl = true; + if (obj->_seqNumb) { // Don't change if no image to display + obj->_cycling = kCycleInvisible; } - _vm->adjustScore(obj->objValue); + _vm->adjustScore(obj->_objValue); - if (obj->seqNumb > 0) // If object has an image, force walk to dropped - obj->viewx = -1; // (possibly moved) object next time taken! - Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->nounIndex, TAKE_NAME))); + if (obj->_seqNumb > 0) // If object has an image, force walk to dropped + obj->_viewx = -1; // (possibly moved) object next time taken! + Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(obj->_nounIndex, TAKE_NAME))); } /** @@ -388,16 +388,16 @@ void Parser_v3d::takeObject(object_t *obj) { void Parser_v3d::dropObject(object_t *obj) { debugC(1, kDebugParser, "dropObject(object_t *obj)"); - obj->carriedFl = false; - obj->screenIndex = *_vm->_screen_p; - if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1)) - obj->cycling = kCycleForward; + obj->_carriedFl = false; + obj->_screenIndex = *_vm->_screen_p; + if ((obj->_seqNumb > 1) || (obj->_seqList[0]._imageNbr > 1)) + obj->_cycling = kCycleForward; else - obj->cycling = kCycleNotCycling; - obj->x = _vm->_hero->x - 1; - obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; - obj->y = (obj->y + obj->currImagePtr->y2 < kYPix) ? obj->y : kYPix - obj->currImagePtr->y2 - 10; - _vm->adjustScore(-obj->objValue); + obj->_cycling = kCycleNotCycling; + obj->_x = _vm->_hero->_x - 1; + obj->_y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1; + obj->_y = (obj->_y + obj->_currImagePtr->_y2 < kYPix) ? obj->_y : kYPix - obj->_currImagePtr->_y2 - 10; + _vm->adjustScore(-obj->_objValue); Utils::notifyBox(_vm->_text->getTextParser(kTBOk)); } @@ -410,19 +410,19 @@ void Parser_v3d::dropObject(object_t *obj) { bool Parser_v3d::isCatchallVerb_v3(objectList_t obj) const { debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)"); - if (_vm->_maze.enabledFl) + if (_vm->_maze._enabledFl) return false; - for (int i = 0; obj[i].verbIndex != 0; i++) { - if (isWordPresent(_vm->_text->getVerbArray(obj[i].verbIndex)) && obj[i].nounIndex == 0 && - (!obj[i].matchFl || !findNoun()) && - ((obj[i].roomState == kStateDontCare) || - (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) { - Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex)); - _vm->_scheduler->processBonus(obj[i].bonusIndex); + for (int i = 0; obj[i]._verbIndex != 0; i++) { + if (isWordPresent(_vm->_text->getVerbArray(obj[i]._verbIndex)) && obj[i]._nounIndex == 0 && + (!obj[i]._matchFl || !findNoun()) && + ((obj[i]._roomState == kStateDontCare) || + (obj[i]._roomState == _vm->_screenStates[*_vm->_screen_p]))) { + Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex)); + _vm->_scheduler->processBonus(obj[i]._bonusIndex); // If this is LOOK (without a noun), show any takeable objects - if (*(_vm->_text->getVerbArray(obj[i].verbIndex)) == _vm->_text->getVerb(_vm->_look, 0)) + if (*(_vm->_text->getVerbArray(obj[i]._verbIndex)) == _vm->_text->getVerb(_vm->_look, 0)) _vm->_object->showTakeables(); return true; @@ -438,16 +438,16 @@ bool Parser_v3d::isCatchallVerb_v3(objectList_t obj) const { bool Parser_v3d::isBackgroundWord_v3(objectList_t obj) const { debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)"); - if (_vm->_maze.enabledFl) + if (_vm->_maze._enabledFl) return false; - for (int i = 0; obj[i].verbIndex != 0; i++) { - if (isWordPresent(_vm->_text->getVerbArray(obj[i].verbIndex)) && - isWordPresent(_vm->_text->getNounArray(obj[i].nounIndex)) && - ((obj[i].roomState == kStateDontCare) || - (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) { - Utils::notifyBox(_vm->_file->fetchString(obj[i].commentIndex)); - _vm->_scheduler->processBonus(obj[i].bonusIndex); + for (int i = 0; obj[i]._verbIndex != 0; i++) { + if (isWordPresent(_vm->_text->getVerbArray(obj[i]._verbIndex)) && + isWordPresent(_vm->_text->getNounArray(obj[i]._nounIndex)) && + ((obj[i]._roomState == kStateDontCare) || + (obj[i]._roomState == _vm->_screenStates[*_vm->_screen_p]))) { + Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex)); + _vm->_scheduler->processBonus(obj[i]._bonusIndex); return true; } } diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index 281aacf031..552ddaf5c9 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -67,35 +67,35 @@ void Route::setDirection(const uint16 keyCode) { switch (keyCode) { case Common::KEYCODE_UP: case Common::KEYCODE_KP8: - obj->currImagePtr = obj->seqList[SEQ_UP].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_UP]._seqPtr; break; case Common::KEYCODE_DOWN: case Common::KEYCODE_KP2: - obj->currImagePtr = obj->seqList[SEQ_DOWN].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_DOWN]._seqPtr; break; case Common::KEYCODE_LEFT: case Common::KEYCODE_KP4: - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; break; case Common::KEYCODE_RIGHT: case Common::KEYCODE_KP6: - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; break; case Common::KEYCODE_HOME: case Common::KEYCODE_KP7: - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; break; case Common::KEYCODE_END: case Common::KEYCODE_KP1: - obj->currImagePtr = obj->seqList[SEQ_LEFT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_LEFT]._seqPtr; break; case Common::KEYCODE_PAGEUP: case Common::KEYCODE_KP9: - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; break; case Common::KEYCODE_PAGEDOWN: case Common::KEYCODE_KP3: - obj->currImagePtr = obj->seqList[SEQ_RIGHT].seqPtr; + obj->_currImagePtr = obj->_seqList[SEQ_RIGHT]._seqPtr; break; } } @@ -109,66 +109,66 @@ void Route::setWalk(const uint16 direction) { object_t *obj = _vm->_hero; // Pointer to hero object - if (_vm->getGameStatus().storyModeFl || obj->pathType != kPathUser) // Make sure user has control + if (_vm->getGameStatus()._storyModeFl || obj->_pathType != kPathUser) // Make sure user has control return; - if (!obj->vx && !obj->vy) + if (!obj->_vx && !obj->_vy) _oldWalkDirection = 0; // Fix for consistant restarts if (direction != _oldWalkDirection) { // Direction has changed setDirection(direction); // Face new direction - obj->vx = obj->vy = 0; + obj->_vx = obj->_vy = 0; switch (direction) { // And set correct velocity case Common::KEYCODE_UP: case Common::KEYCODE_KP8: - obj->vy = -kStepDy; + obj->_vy = -kStepDy; break; case Common::KEYCODE_DOWN: case Common::KEYCODE_KP2: - obj->vy = kStepDy; + obj->_vy = kStepDy; break; case Common::KEYCODE_LEFT: case Common::KEYCODE_KP4: - obj->vx = -kStepDx; + obj->_vx = -kStepDx; break; case Common::KEYCODE_RIGHT: case Common::KEYCODE_KP6: - obj->vx = kStepDx; + obj->_vx = kStepDx; break; case Common::KEYCODE_HOME: case Common::KEYCODE_KP7: - obj->vx = -kStepDx; + obj->_vx = -kStepDx; // Note: in v1 Dos and v2 Dos, obj->vy is set to DY - obj->vy = -kStepDy / 2; + obj->_vy = -kStepDy / 2; break; case Common::KEYCODE_END: case Common::KEYCODE_KP1: - obj->vx = -kStepDx; + obj->_vx = -kStepDx; // Note: in v1 Dos and v2 Dos, obj->vy is set to -DY - obj->vy = kStepDy / 2; + obj->_vy = kStepDy / 2; break; case Common::KEYCODE_PAGEUP: case Common::KEYCODE_KP9: - obj->vx = kStepDx; + obj->_vx = kStepDx; // Note: in v1 Dos and v2 Dos, obj->vy is set to -DY - obj->vy = -kStepDy / 2; + obj->_vy = -kStepDy / 2; break; case Common::KEYCODE_PAGEDOWN: case Common::KEYCODE_KP3: - obj->vx = kStepDx; + obj->_vx = kStepDx; // Note: in v1 Dos and v2 Dos, obj->vy is set to DY - obj->vy = kStepDy / 2; + obj->_vy = kStepDy / 2; break; } _oldWalkDirection = direction; - obj->cycling = kCycleForward; + obj->_cycling = kCycleForward; } else { // Same key twice - halt hero - obj->vy = 0; - obj->vx = 0; + obj->_vy = 0; + obj->_vx = 0; _oldWalkDirection = 0; - obj->cycling = kCycleNotCycling; + obj->_cycling = kCycleNotCycling; } } @@ -228,7 +228,7 @@ void Route::segment(int16 x, int16 y) { if (y <= 0 || y >= kYPix - 1) return; - if (_vm->_hero->x < x1) { + if (_vm->_hero->_x < x1) { // Hero x not in segment, search x1..x2 // Find all segments above current for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { @@ -241,7 +241,7 @@ void Route::segment(int16 x, int16 y) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } - } else if (_vm->_hero->x + kHeroMaxWidth > x2) { + } else if (_vm->_hero->_x + kHeroMaxWidth > x2) { // Hero x not in segment, search x1..x2 // Find all segments above current for (x = x2; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x >= x1; x--) { @@ -257,22 +257,22 @@ void Route::segment(int16 x, int16 y) { } else { // Organize search around hero x position - this gives // better chance for more direct route. - for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { + for (x = _vm->_hero->_x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); } - for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) { + for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->_x; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); } - for (x = _vm->_hero->x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { + for (x = _vm->_hero->_x; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } - for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->x; x++) { + for (x = x1; !(_routeFoundFl || _fullStackFl || _fullSegmentFl) && x < _vm->_hero->_x; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); } @@ -327,16 +327,16 @@ bool Route::findRoute(const int16 cx, const int16 cy) { _destY = cy; // Destination coords _destX = cx; // Destination coords - int16 herox1 = _vm->_hero->x + _vm->_hero->currImagePtr->x1; // Hero baseline - int16 herox2 = _vm->_hero->x + _vm->_hero->currImagePtr->x2; // Hero baseline - int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2; // Hero baseline + int16 herox1 = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1; // Hero baseline + int16 herox2 = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x2; // Hero baseline + int16 heroy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2; // Hero baseline // Store all object baselines into objbound (except hero's = [0]) object_t *obj; // Ptr to object int i; for (i = 1, obj = &_vm->_object->_objects[i]; i < _vm->_object->_numObj; i++, obj++) { - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != kCycleInvisible) && (obj->priority == kPriorityFloating)) - _vm->_object->storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2); + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) + _vm->_object->storeBoundary(obj->_oldx + obj->_currImagePtr->_x1, obj->_oldx + obj->_currImagePtr->_x2, obj->_oldy + obj->_currImagePtr->_y2); } // Combine objbound and boundary bitmaps to local byte map @@ -350,8 +350,8 @@ bool Route::findRoute(const int16 cx, const int16 cy) { // Clear all object baselines from objbound for (i = 0, obj = _vm->_object->_objects; i < _vm->_object->_numObj; i++, obj++) { - if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != kCycleInvisible) && (obj->priority == kPriorityFloating)) - _vm->_object->clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2); + if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) + _vm->_object->clearBoundary(obj->_oldx + obj->_currImagePtr->_x1, obj->_oldx + obj->_currImagePtr->_x2, obj->_oldy + obj->_currImagePtr->_y2); } // Search from hero to destination @@ -433,18 +433,18 @@ void Route::processRoute() { return; // Current hero position - int16 herox = _vm->_hero->x + _vm->_hero->currImagePtr->x1; - int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2; + int16 herox = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1; + int16 heroy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2; Point *routeNode = &_route[_routeIndex]; // Arrived at node? if (abs(herox - routeNode->x) < kStepDx + 1 && abs(heroy - routeNode->y) < kStepDy) { // kStepDx too low // Close enough - position hero exactly - _vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1; - _vm->_hero->y = _vm->_hero->oldy = routeNode->y - _vm->_hero->currImagePtr->y2; - _vm->_hero->vx = _vm->_hero->vy = 0; - _vm->_hero->cycling = kCycleNotCycling; + _vm->_hero->_x = _vm->_hero->_oldx = routeNode->x - _vm->_hero->_currImagePtr->_x1; + _vm->_hero->_y = _vm->_hero->_oldy = routeNode->y - _vm->_hero->_currImagePtr->_y2; + _vm->_hero->_vx = _vm->_hero->_vy = 0; + _vm->_hero->_cycling = kCycleNotCycling; // Arrived at final node? if (--_routeIndex < 0) { @@ -458,7 +458,7 @@ void Route::processRoute() { _vm->_object->lookObject(&_vm->_object->_objects[_routeObjId]); turnedFl = false; } else { - setDirection(_vm->_object->_objects[_routeObjId].direction); + setDirection(_vm->_object->_objects[_routeObjId]._direction); _routeIndex++; // Come round again turnedFl = true; } @@ -468,7 +468,7 @@ void Route::processRoute() { _vm->_object->useObject(_routeObjId); turnedFl = false; } else { - setDirection(_vm->_object->_objects[_routeObjId].direction); + setDirection(_vm->_object->_objects[_routeObjId]._direction); _routeIndex++; // Come round again turnedFl = true; } @@ -477,7 +477,7 @@ void Route::processRoute() { break; } } - } else if (_vm->_hero->vx == 0 && _vm->_hero->vy == 0) { + } else if (_vm->_hero->_vx == 0 && _vm->_hero->_vy == 0) { // Set direction of travel if at a node // Note realignment when changing to (thinner) up/down sprite, // otherwise hero could bump into boundaries along route. @@ -487,10 +487,10 @@ void Route::processRoute() { setWalk(Common::KEYCODE_LEFT); } else if (heroy < routeNode->y) { setWalk(Common::KEYCODE_DOWN); - _vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1; + _vm->_hero->_x = _vm->_hero->_oldx = routeNode->x - _vm->_hero->_currImagePtr->_x1; } else if (heroy > routeNode->y) { setWalk(Common::KEYCODE_UP); - _vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1; + _vm->_hero->_x = _vm->_hero->_oldx = routeNode->x - _vm->_hero->_currImagePtr->_x1; } } } @@ -504,7 +504,7 @@ bool Route::startRoute(const go_t routeType, const int16 objId, int16 cx, int16 debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", routeType, objId, cx, cy); // Don't attempt to walk if user does not have control - if (_vm->_hero->pathType != kPathUser) + if (_vm->_hero->_pathType != kPathUser) return false; // if inventory showing, make it go away @@ -521,7 +521,7 @@ bool Route::startRoute(const go_t routeType, const int16 objId, int16 cx, int16 bool foundFl = false; // TRUE if route found ok if ((foundFl = findRoute(cx, cy))) { // Found a route? _routeIndex = _routeListIndex; // Node index - _vm->_hero->vx = _vm->_hero->vy = 0; // Stop manual motion + _vm->_hero->_vx = _vm->_hero->_vy = 0; // Stop manual motion } return foundFl; diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 896e8fa2ce..18e414420a 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -112,7 +112,7 @@ void Scheduler::insertActionList(const uint16 actIndex) { uint32 Scheduler::getWinTicks() const { debugC(5, kDebugSchedule, "getWinTicks()"); - return _vm->getGameStatus().tick; + return _vm->getGameStatus()._tick; } /** @@ -656,32 +656,32 @@ void Scheduler::screenActions(const int screenNum) { void Scheduler::processMaze(const int x1, const int x2, const int y1, const int y2) { debugC(1, kDebugSchedule, "processMaze"); - if (x1 < _vm->_maze.x1) { + if (x1 < _vm->_maze._x1) { // Exit west _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - 1; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x2 - kShiftSize - (x2 - x1); - _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y; + _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x2 - kShiftSize - (x2 - x1); + _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->_y; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); - } else if (x2 > _vm->_maze.x2) { + } else if (x2 > _vm->_maze._x2) { // Exit east _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + 1; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x1 + kShiftSize; - _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y; + _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x1 + kShiftSize; + _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->_y; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); - } else if (y1 < _vm->_maze.y1 - kShiftSize) { + } else if (y1 < _vm->_maze._y1 - kShiftSize) { // Exit north - _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - _vm->_maze.size; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x3; - _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze.y2 - kShiftSize - (y2 - y1); + _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - _vm->_maze._size; + _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x3; + _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze._y2 - kShiftSize - (y2 - y1); _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); - } else if (y2 > _vm->_maze.y2 - kShiftSize / 2) { + } else if (y2 > _vm->_maze._y2 - kShiftSize / 2) { // Exit south - _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + _vm->_maze.size; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze.x4; - _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze.y1 + kShiftSize; + _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + _vm->_maze._size; + _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x4; + _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze._y1 + kShiftSize; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } @@ -1144,7 +1144,7 @@ void Scheduler::insertAction(act *action) { break; // Workaround: When dying, switch to storyMode in order to block the keyboard. case GAMEOVER: - _vm->getGameStatus().storyModeFl = true; + _vm->getGameStatus()._storyModeFl = true; // No break on purpose default: curEvent->localActionFl = true; // Rest are for current screen only @@ -1205,12 +1205,12 @@ event_t *Scheduler::doAction(event_t *curEvent) { insertActionList(action->a0.actIndex); break; case START_OBJ: // act1: Start an object cycling - _vm->_object->_objects[action->a1.objIndex].cycleNumb = action->a1.cycleNumb; - _vm->_object->_objects[action->a1.objIndex].cycling = action->a1.cycle; + _vm->_object->_objects[action->a1.objIndex]._cycleNumb = action->a1.cycleNumb; + _vm->_object->_objects[action->a1.objIndex]._cycling = action->a1.cycle; break; case INIT_OBJXY: // act2: Initialize an object - _vm->_object->_objects[action->a2.objIndex].x = action->a2.x; // Coordinates - _vm->_object->_objects[action->a2.objIndex].y = action->a2.y; + _vm->_object->_objects[action->a2.objIndex]._x = action->a2.x; // Coordinates + _vm->_object->_objects[action->a2.objIndex]._y = action->a2.y; break; case PROMPT: // act3: Prompt user for key phrase promptAction(action); @@ -1225,21 +1225,21 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_object->setCarry(action->a6.objIndex, action->a6.carriedFl); // carried status break; case INIT_HF_COORD: // act7: Initialize an object to hero's "feet" coords - _vm->_object->_objects[action->a7.objIndex].x = _vm->_hero->x - 1; - _vm->_object->_objects[action->a7.objIndex].y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1; - _vm->_object->_objects[action->a7.objIndex].screenIndex = *_vm->_screen_p; // Don't forget screen! + _vm->_object->_objects[action->a7.objIndex]._x = _vm->_hero->_x - 1; + _vm->_object->_objects[action->a7.objIndex]._y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1; + _vm->_object->_objects[action->a7.objIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! break; case NEW_SCREEN: // act8: Start new screen newScreen(action->a8.screenIndex); break; case INIT_OBJSTATE: // act9: Initialize an object state - _vm->_object->_objects[action->a9.objIndex].state = action->a9.newState; + _vm->_object->_objects[action->a9.objIndex]._state = action->a9.newState; break; case INIT_PATH: // act10: Initialize an object path and velocity _vm->_object->setPath(action->a10.objIndex, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath); break; case COND_R: // act11: action lists conditional on object state - if (_vm->_object->_objects[action->a11.objIndex].state == action->a11.stateReq) + if (_vm->_object->_objects[action->a11.objIndex]._state == action->a11.stateReq) insertActionList(action->a11.actPassIndex); else insertActionList(action->a11.actFailIndex); @@ -1251,7 +1251,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_object->swapImages(action->a13.objIndex1, action->a13.objIndex2); break; case COND_SCR: // act14: Conditional on current screen - if (_vm->_object->_objects[action->a14.objIndex].screenIndex == action->a14.screenReq) + if (_vm->_object->_objects[action->a14.objIndex]._screenIndex == action->a14.screenReq) insertActionList(action->a14.actPassIndex); else insertActionList(action->a14.actFailIndex); @@ -1262,16 +1262,16 @@ event_t *Scheduler::doAction(event_t *curEvent) { case INIT_OBJ_SEQ: // act16: Set sequence number to use // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! t>0 is safe - _vm->_object->_objects[action->a16.objIndex].currImagePtr = _vm->_object->_objects[action->a16.objIndex].seqList[action->a16.seqIndex].seqPtr; + _vm->_object->_objects[action->a16.objIndex]._currImagePtr = _vm->_object->_objects[action->a16.objIndex]._seqList[action->a16.seqIndex]._seqPtr; break; case SET_STATE_BITS: // act17: OR mask with curr obj state - _vm->_object->_objects[action->a17.objIndex].state |= action->a17.stateMask; + _vm->_object->_objects[action->a17.objIndex]._state |= action->a17.stateMask; break; case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state - _vm->_object->_objects[action->a18.objIndex].state &= ~action->a18.stateMask; + _vm->_object->_objects[action->a18.objIndex]._state &= ~action->a18.stateMask; break; case TEST_STATE_BITS: // act19: If all bits set, do apass else afail - if ((_vm->_object->_objects[action->a19.objIndex].state & action->a19.stateMask) == action->a19.stateMask) + if ((_vm->_object->_objects[action->a19.objIndex]._state & action->a19.stateMask) == action->a19.stateMask) insertActionList(action->a19.actPassIndex); else insertActionList(action->a19.actFailIndex); @@ -1282,12 +1282,12 @@ event_t *Scheduler::doAction(event_t *curEvent) { case GAMEOVER: // act21: Game over! // NOTE: Must wait at least 1 tick before issuing this action if // any objects are to be made invisible! - gameStatus.gameOverFl = true; + gameStatus._gameOverFl = true; break; case INIT_HH_COORD: // act22: Initialize an object to hero's actual coords - _vm->_object->_objects[action->a22.objIndex].x = _vm->_hero->x; - _vm->_object->_objects[action->a22.objIndex].y = _vm->_hero->y; - _vm->_object->_objects[action->a22.objIndex].screenIndex = *_vm->_screen_p;// Don't forget screen! + _vm->_object->_objects[action->a22.objIndex]._x = _vm->_hero->_x; + _vm->_object->_objects[action->a22.objIndex]._y = _vm->_hero->_y; + _vm->_object->_objects[action->a22.objIndex]._screenIndex = *_vm->_screen_p;// Don't forget screen! break; case EXIT: // act23: Exit game back to DOS _vm->endGame(); @@ -1297,8 +1297,8 @@ event_t *Scheduler::doAction(event_t *curEvent) { break; case COND_BOX: // act25: Conditional on bounding box obj1 = &_vm->_object->_objects[action->a25.objIndex]; - dx = obj1->x + obj1->currImagePtr->x1; - dy = obj1->y + obj1->currImagePtr->y2; + dx = obj1->_x + obj1->_currImagePtr->_x1; + dy = obj1->_y + obj1->_currImagePtr->_y2; if ((dx >= action->a25.x1) && (dx <= action->a25.x2) && (dy >= action->a25.y1) && (dy <= action->a25.y2)) insertActionList(action->a25.actPassIndex); @@ -1312,10 +1312,10 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_sound->playSound(action->a26.soundIndex, kSoundPriorityMedium); break; case ADD_SCORE: // act27: Add object's value to score - _vm->adjustScore(_vm->_object->_objects[action->a27.objIndex].objValue); + _vm->adjustScore(_vm->_object->_objects[action->a27.objIndex]._objValue); break; case SUB_SCORE: // act28: Subtract object's value from score - _vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex].objValue); + _vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex]._objValue); break; case COND_CARRY: // act29: Conditional on object being carried if (_vm->_object->isCarried(action->a29.objIndex)) @@ -1324,24 +1324,24 @@ event_t *Scheduler::doAction(event_t *curEvent) { insertActionList(action->a29.actFailIndex); break; case INIT_MAZE: // act30: Enable and init maze structure - _vm->_maze.enabledFl = true; - _vm->_maze.size = action->a30.mazeSize; - _vm->_maze.x1 = action->a30.x1; - _vm->_maze.y1 = action->a30.y1; - _vm->_maze.x2 = action->a30.x2; - _vm->_maze.y2 = action->a30.y2; - _vm->_maze.x3 = action->a30.x3; - _vm->_maze.x4 = action->a30.x4; - _vm->_maze.firstScreenIndex = action->a30.firstScreenIndex; + _vm->_maze._enabledFl = true; + _vm->_maze._size = action->a30.mazeSize; + _vm->_maze._x1 = action->a30.x1; + _vm->_maze._y1 = action->a30.y1; + _vm->_maze._x2 = action->a30.x2; + _vm->_maze._y2 = action->a30.y2; + _vm->_maze._x3 = action->a30.x3; + _vm->_maze._x4 = action->a30.x4; + _vm->_maze._firstScreenIndex = action->a30.firstScreenIndex; break; case EXIT_MAZE: // act31: Disable maze mode - _vm->_maze.enabledFl = false; + _vm->_maze._enabledFl = false; break; case INIT_PRIORITY: - _vm->_object->_objects[action->a32.objIndex].priority = action->a32.priority; + _vm->_object->_objects[action->a32.objIndex]._priority = action->a32.priority; break; case INIT_SCREEN: - _vm->_object->_objects[action->a33.objIndex].screenIndex = action->a33.screenIndex; + _vm->_object->_objects[action->a33.objIndex]._screenIndex = action->a33.screenIndex; break; case AGSCHEDULE: // act34: Schedule a (global) action list insertActionList(action->a34.actIndex); @@ -1359,15 +1359,15 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_screenStates[action->a37.screenIndex] = action->a37.newState; break; case INIT_LIPS: // act38: Position lips on object - _vm->_object->_objects[action->a38.lipsObjIndex].x = _vm->_object->_objects[action->a38.objIndex].x + action->a38.dxLips; - _vm->_object->_objects[action->a38.lipsObjIndex].y = _vm->_object->_objects[action->a38.objIndex].y + action->a38.dyLips; - _vm->_object->_objects[action->a38.lipsObjIndex].screenIndex = *_vm->_screen_p; // Don't forget screen! - _vm->_object->_objects[action->a38.lipsObjIndex].cycling = kCycleForward; + _vm->_object->_objects[action->a38.lipsObjIndex]._x = _vm->_object->_objects[action->a38.objIndex]._x + action->a38.dxLips; + _vm->_object->_objects[action->a38.lipsObjIndex]._y = _vm->_object->_objects[action->a38.objIndex]._y + action->a38.dyLips; + _vm->_object->_objects[action->a38.lipsObjIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! + _vm->_object->_objects[action->a38.lipsObjIndex]._cycling = kCycleForward; break; case INIT_STORY_MODE: // act39: Init story_mode flag // This is similar to the QUIET path mode, except that it is // independant of it and it additionally disables the ">" prompt - gameStatus.storyModeFl = action->a39.storyModeFl; + gameStatus._storyModeFl = action->a39.storyModeFl; break; case WARN: // act40: Text box (CF TEXT) Utils::notifyBox(_vm->_file->fetchString(action->a40.stringIndex)); @@ -1379,7 +1379,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { insertActionList(action->a41.actFailIndex); break; case TEXT_TAKE: // act42: Text box with "take" message - Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->a42.objIndex].nounIndex, TAKE_NAME))); + Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->a42.objIndex]._nounIndex, TAKE_NAME))); break; case YESNO: // act43: Prompt user for Yes or No if (Utils::yesNoBox(_vm->_file->fetchString(action->a43.promptIndex))) @@ -1403,16 +1403,16 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_mouse->setJumpExitFl(action->a46.jumpExitFl); break; case INIT_VIEW: // act47: Init object.viewx, viewy, dir - _vm->_object->_objects[action->a47.objIndex].viewx = action->a47.viewx; - _vm->_object->_objects[action->a47.objIndex].viewy = action->a47.viewy; - _vm->_object->_objects[action->a47.objIndex].direction = action->a47.direction; + _vm->_object->_objects[action->a47.objIndex]._viewx = action->a47.viewx; + _vm->_object->_objects[action->a47.objIndex]._viewy = action->a47.viewy; + _vm->_object->_objects[action->a47.objIndex]._direction = action->a47.direction; break; case INIT_OBJ_FRAME: // act48: Set seq,frame number to use // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! t>0 is safe - _vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].seqList[action->a48.seqIndex].seqPtr; + _vm->_object->_objects[action->a48.objIndex]._currImagePtr = _vm->_object->_objects[action->a48.objIndex]._seqList[action->a48.seqIndex]._seqPtr; for (dx = 0; dx < action->a48.frameIndex; dx++) - _vm->_object->_objects[action->a48.objIndex].currImagePtr = _vm->_object->_objects[action->a48.objIndex].currImagePtr->nextSeqPtr; + _vm->_object->_objects[action->a48.objIndex]._currImagePtr = _vm->_object->_objects[action->a48.objIndex]._currImagePtr->_nextSeqPtr; break; case OLD_SONG: // Replaces ACT26 for DOS games. @@ -1644,6 +1644,6 @@ void Scheduler_v1w::runScheduler() { while (curEvent && (curEvent->time <= ticker)) // While mature events found curEvent = doAction(curEvent); // Perform the action (returns next_p) - _vm->getGameStatus().tick++; // Accessed elsewhere via getTicks() + _vm->getGameStatus()._tick++; // Accessed elsewhere via getTicks() } } // End of namespace Hugo diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp index d0b4e3dfe8..eed4164d5e 100644 --- a/engines/hugo/sound.cpp +++ b/engines/hugo/sound.cpp @@ -186,7 +186,7 @@ void SoundHandler::playMusic(int16 tune) { uint16 size; // Size of sequence data if (_vm->_config.musicFl) { - _vm->getGameStatus().song = tune; + _vm->getGameStatus()._song = tune; seqPtr = _vm->_file->getSound(tune, &size); playMIDI(seqPtr, size); free(seqPtr); @@ -245,7 +245,7 @@ void SoundHandler::checkMusic() { return; for (int i = 0; _vm->_defltTunes[i] != -1; i++) { - if (_vm->_defltTunes[i] == _vm->getGameStatus().song) { + if (_vm->_defltTunes[i] == _vm->getGameStatus()._song) { if (_vm->_defltTunes[i + 1] != -1) playMusic(_vm->_defltTunes[i + 1]); else -- cgit v1.2.3 From 998448128c8527427b1b472d17c68b7770ee6f4c Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 11:50:49 +0200 Subject: HUGO: Some more renaming --- engines/hugo/display.cpp | 66 ++++++++++++++++++++++---------------------- engines/hugo/display.h | 8 +++--- engines/hugo/file.cpp | 70 +++++++++++++++++++++++------------------------ engines/hugo/file.h | 42 ++++++++++++++-------------- engines/hugo/file_v1w.cpp | 28 +++++++++---------- engines/hugo/file_v2d.cpp | 46 +++++++++++++++---------------- engines/hugo/file_v3d.cpp | 60 ++++++++++++++++++++-------------------- 7 files changed, 160 insertions(+), 160 deletions(-) diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp index 7028195dd4..12a9edfbb7 100644 --- a/engines/hugo/display.cpp +++ b/engines/hugo/display.cpp @@ -85,20 +85,20 @@ Screen::Screen(HugoEngine *vm) : _vm(vm) { fontLoadedFl[i] = false; } for (int i = 0; i < kBlitListSize; i++) { - _dlBlistList[i].x = 0; - _dlBlistList[i].y = 0; - _dlBlistList[i].dx = 0; - _dlBlistList[i].dy = 0; + _dlBlistList[i]._x = 0; + _dlBlistList[i]._y = 0; + _dlBlistList[i]._dx = 0; + _dlBlistList[i]._dy = 0; } for (int i = 0; i < kRectListSize; i++) { - _dlAddList[i].x = 0; - _dlAddList[i].y = 0; - _dlAddList[i].dx = 0; - _dlAddList[i].dy = 0; - _dlRestoreList[i].x = 0; - _dlRestoreList[i].y = 0; - _dlRestoreList[i].dx = 0; - _dlRestoreList[i].dy = 0; + _dlAddList[i]._x = 0; + _dlAddList[i]._y = 0; + _dlAddList[i]._dx = 0; + _dlAddList[i]._dy = 0; + _dlRestoreList[i]._x = 0; + _dlRestoreList[i]._y = 0; + _dlRestoreList[i]._dx = 0; + _dlRestoreList[i]._dy = 0; } } @@ -274,15 +274,15 @@ void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool for void Screen::merge(const rect_t *rectA, rect_t *rectB) { debugC(6, kDebugDisplay, "merge()"); - int16 xa = rectA->x + rectA->dx; // Find x2,y2 for each rectangle - int16 xb = rectB->x + rectB->dx; - int16 ya = rectA->y + rectA->dy; - int16 yb = rectB->y + rectB->dy; + int16 xa = rectA->_x + rectA->_dx; // Find x2,y2 for each rectangle + int16 xb = rectB->_x + rectB->_dx; + int16 ya = rectA->_y + rectA->_dy; + int16 yb = rectB->_y + rectB->_dy; - rectB->x = MIN(rectA->x, rectB->x); // Minimum x,y - rectB->y = MIN(rectA->y, rectB->y); - rectB->dx = MAX(xa, xb) - rectB->x; // Maximum dx,dy - rectB->dy = MAX(ya, yb) - rectB->y; + rectB->_x = MIN(rectA->_x, rectB->_x); // Minimum x,y + rectB->_y = MIN(rectA->_y, rectB->_y); + rectB->_dx = MAX(xa, xb) - rectB->_x; // Maximum dx,dy + rectB->_dy = MAX(ya, yb) - rectB->_y; } /** @@ -301,7 +301,7 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble int16 c = 0; rect_t *bp = blist; for (int16 b = 0; b < blen; b++, bp++) { - if (bp->dx) // blist entry used + if (bp->_dx) // blist entry used if (isOverlapping(list, bp)) coalesce[c++] = b; } @@ -318,7 +318,7 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble while (--c) { rect_t *cp = &blist[coalesce[c]]; merge(cp, bp); - cp->dx = 0; // Delete entry + cp->_dx = 0; // Delete entry } } } @@ -348,10 +348,10 @@ void Screen::displayList(dupdate_t update, ...) { } va_start(marker, update); // Initialize variable arguments p = &_dlAddList[_dlAddIndex]; - p->x = va_arg(marker, int); // x - p->y = va_arg(marker, int); // y - p->dx = va_arg(marker, int); // dx - p->dy = va_arg(marker, int); // dy + p->_x = va_arg(marker, int); // x + p->_y = va_arg(marker, int); // y + p->_dx = va_arg(marker, int); // dx + p->_dy = va_arg(marker, int); // dy va_end(marker); // Reset variable arguments _dlAddIndex++; break; @@ -370,15 +370,15 @@ void Screen::displayList(dupdate_t update, ...) { // Blit the combined blit-list for (_dlRestoreIndex = 0, p = _dlBlistList; _dlRestoreIndex < blitLength; _dlRestoreIndex++, p++) { - if (p->dx) // Marks a used entry - displayRect(p->x, p->y, p->dx, p->dy); + if (p->_dx) // Marks a used entry + displayRect(p->_x, p->_y, p->_dx, p->_dy); } break; case kDisplayRestore: // Restore each rectangle for (_dlRestoreIndex = 0, p = _dlAddList; _dlRestoreIndex < _dlAddIndex; _dlRestoreIndex++, p++) { // Restoring from _backBuffer to _frontBuffer _dlRestoreList[_dlRestoreIndex] = *p; // Copy add-list to restore-list - moveImage(_backBuffer, p->x, p->y, p->dx, p->dy, kXPix, _frontBuffer, p->x, p->y, kXPix); + moveImage(_backBuffer, p->_x, p->_y, p->_dx, p->_dy, kXPix, _frontBuffer, p->_x, p->_y, kXPix); } _dlAddIndex = 0; // Reset add-list break; @@ -628,19 +628,19 @@ void Screen::hideCursor() { } bool Screen::isInX(const int16 x, const rect_t *rect) const { - return (x >= rect->x) && (x <= rect->x + rect->dx); + return (x >= rect->_x) && (x <= rect->_x + rect->_dx); } bool Screen::isInY(const int16 y, const rect_t *rect) const { - return (y >= rect->y) && (y <= rect->y + rect->dy); + return (y >= rect->_y) && (y <= rect->_y + rect->_dy); } /** * Check if two rectangles are overlapping */ bool Screen::isOverlapping(const rect_t *rectA, const rect_t *rectB) const { - return (isInX(rectA->x, rectB) || isInX(rectA->x + rectA->dx, rectB) || isInX(rectB->x, rectA) || isInX(rectB->x + rectB->dx, rectA)) && - (isInY(rectA->y, rectB) || isInY(rectA->y + rectA->dy, rectB) || isInY(rectB->y, rectA) || isInY(rectB->y + rectB->dy, rectA)); + return (isInX(rectA->_x, rectB) || isInX(rectA->_x + rectA->_dx, rectB) || isInX(rectB->_x, rectA) || isInX(rectB->_x + rectB->_dx, rectA)) && + (isInY(rectA->_y, rectB) || isInY(rectA->_y + rectA->_dy, rectB) || isInY(rectB->_y, rectA) || isInY(rectB->_y + rectB->_dy, rectA)); } /** diff --git a/engines/hugo/display.h b/engines/hugo/display.h index 38c63e9fe5..0d8120e916 100644 --- a/engines/hugo/display.h +++ b/engines/hugo/display.h @@ -39,10 +39,10 @@ static const int kCenter = -1; // Used to center text in x class Screen { public: struct rect_t { // Rectangle used in Display list - int16 x; // Position in dib - int16 y; // Position in dib - int16 dx; // width - int16 dy; // height + int16 _x; // Position in dib + int16 _y; // Position in dib + int16 _dx; // width + int16 _dy; // height }; Screen(HugoEngine *vm); diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index 8b03a9a430..a3fc5dfe49 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -53,7 +53,7 @@ static const int s_bootCypherLen = sizeof(s_bootCypher) - 1; FileManager::FileManager(HugoEngine *vm) : _vm(vm) { - has_read_header = false; + _hasReadHeader = false; firstUIFFl = true; } @@ -115,23 +115,23 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr debugC(1, kDebugFile, "readPCX(..., %s)", name); // Read in the PCC header and check consistency - PCC_header.mfctr = f.readByte(); - PCC_header.vers = f.readByte(); - PCC_header.enc = f.readByte(); - PCC_header.bpx = f.readByte(); - PCC_header.x1 = f.readUint16LE(); - PCC_header.y1 = f.readUint16LE(); - PCC_header.x2 = f.readUint16LE(); - PCC_header.y2 = f.readUint16LE(); - PCC_header.xres = f.readUint16LE(); - PCC_header.yres = f.readUint16LE(); - f.read(PCC_header.palette, sizeof(PCC_header.palette)); - PCC_header.vmode = f.readByte(); - PCC_header.planes = f.readByte(); - PCC_header.bytesPerLine = f.readUint16LE(); - f.read(PCC_header.fill2, sizeof(PCC_header.fill2)); - - if (PCC_header.mfctr != 10) + _PCCHeader._mfctr = f.readByte(); + _PCCHeader._vers = f.readByte(); + _PCCHeader._enc = f.readByte(); + _PCCHeader._bpx = f.readByte(); + _PCCHeader._x1 = f.readUint16LE(); + _PCCHeader._y1 = f.readUint16LE(); + _PCCHeader._x2 = f.readUint16LE(); + _PCCHeader._y2 = f.readUint16LE(); + _PCCHeader._xres = f.readUint16LE(); + _PCCHeader._yres = f.readUint16LE(); + f.read(_PCCHeader._palette, sizeof(_PCCHeader._palette)); + _PCCHeader._vmode = f.readByte(); + _PCCHeader._planes = f.readByte(); + _PCCHeader._bytesPerLine = f.readUint16LE(); + f.read(_PCCHeader._fill2, sizeof(_PCCHeader._fill2)); + + if (_PCCHeader._mfctr != 10) error("Bad data file format: %s", name); // Allocate memory for seq_t if 0 @@ -142,10 +142,10 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr // Find size of image data in 8-bit DIB format // Note save of x2 - marks end of valid data before garbage - uint16 bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl + uint16 bytesPerLine4 = _PCCHeader._bytesPerLine * 4; // 4-bit bpl seqPtr->_bytesPerLine8 = bytesPerLine4 * 2; // 8-bit bpl - seqPtr->_lines = PCC_header.y2 - PCC_header.y1 + 1; - seqPtr->_x2 = PCC_header.x2 - PCC_header.x1 + 1; + seqPtr->_lines = _PCCHeader._y2 - _PCCHeader._y1 + 1; + seqPtr->_x2 = _PCCHeader._x2 - _PCCHeader._x1 + 1; // Size of the image uint16 size = seqPtr->_lines * seqPtr->_bytesPerLine8; @@ -168,12 +168,12 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr for (int i = 0; i < (c & kLengthMask); i++) { *p++ = d; if ((uint16)(p - pline) == bytesPerLine4) - p = convertPCC(pline, y++, PCC_header.bytesPerLine, imagePtr); + p = convertPCC(pline, y++, _PCCHeader._bytesPerLine, imagePtr); } } else { *p++ = c; if ((uint16)(p - pline) == bytesPerLine4) - p = convertPCC(pline, y++, PCC_header.bytesPerLine, imagePtr); + p = convertPCC(pline, y++, _PCCHeader._bytesPerLine, imagePtr); } } return seqPtr; @@ -296,27 +296,27 @@ sound_pt FileManager::getSound(const int16 sound, uint16 *size) { return 0; } - if (!has_read_header) { + if (!_hasReadHeader) { for (int i = 0; i < kMaxSounds; i++) { - s_hdr[i]._size = fp.readUint16LE(); - s_hdr[i]._offset = fp.readUint32LE(); + _s_hdr[i]._size = fp.readUint16LE(); + _s_hdr[i]._offset = fp.readUint32LE(); } if (fp.err()) error("Wrong sound file format"); - has_read_header = true; + _hasReadHeader = true; } - *size = s_hdr[sound]._size; + *size = _s_hdr[sound]._size; if (*size == 0) error("Wrong sound file format or missing sound %d", sound); // Allocate memory for sound or music, if possible - sound_pt soundPtr = (byte *)malloc(s_hdr[sound]._size); // Ptr to sound data + sound_pt soundPtr = (byte *)malloc(_s_hdr[sound]._size); // Ptr to sound data assert(soundPtr); // Seek to data and read it - fp.seek(s_hdr[sound]._offset, SEEK_SET); - if (fp.read(soundPtr, s_hdr[sound]._size) != s_hdr[sound]._size) + fp.seek(_s_hdr[sound]._offset, SEEK_SET); + if (fp.read(soundPtr, _s_hdr[sound]._size) != _s_hdr[sound]._size) error("Wrong sound file format"); fp.close(); @@ -639,8 +639,8 @@ uif_hdr_t *FileManager::getUIFHeader(const uif_t id) { error("Wrong UIF file format"); for (int i = 0; i < kMaxUifs; ++i) { - UIFHeader[i].size = ip.readUint16LE(); - UIFHeader[i].offset = ip.readUint32LE(); + UIFHeader[i]._size = ip.readUint16LE(); + UIFHeader[i]._offset = ip.readUint32LE(); } ip.close(); @@ -661,7 +661,7 @@ void FileManager::readUIFItem(const int16 id, byte *buf) { // Seek to data uif_hdr_t *UIFHeaderPtr = getUIFHeader((uif_t)id); - ip.seek(UIFHeaderPtr->offset, SEEK_SET); + ip.seek(UIFHeaderPtr->_offset, SEEK_SET); // We support pcx images and straight data seq_t *dummySeq; // Dummy seq_t for image data @@ -671,7 +671,7 @@ void FileManager::readUIFItem(const int16 id, byte *buf) { free(dummySeq); break; default: // Read file data into supplied array - if (ip.read(buf, UIFHeaderPtr->size) != UIFHeaderPtr->size) + if (ip.read(buf, UIFHeaderPtr->_size) != UIFHeaderPtr->_size) error("Wrong UIF file format"); break; } diff --git a/engines/hugo/file.h b/engines/hugo/file.h index 3792c01ab4..81d3c73f5a 100644 --- a/engines/hugo/file.h +++ b/engines/hugo/file.h @@ -37,8 +37,8 @@ namespace Hugo { enum ovl_t {kOvlBoundary, kOvlOverlay, kOvlBase}; struct uif_hdr_t { // UIF font/image look up - uint16 size; // Size of uif item - uint32 offset; // Offset of item in file + uint16 _size; // Size of uif item + uint32 _offset; // Offset of item in file }; @@ -85,24 +85,24 @@ protected: * Structure of scenery file lookup entry */ struct sceneBlock_t { - uint32 scene_off; - uint32 scene_len; - uint32 b_off; - uint32 b_len; - uint32 o_off; - uint32 o_len; - uint32 ob_off; - uint32 ob_len; + uint32 _scene_off; + uint32 _scene_len; + uint32 _b_off; + uint32 _b_len; + uint32 _o_off; + uint32 _o_len; + uint32 _ob_off; + uint32 _ob_len; }; - struct PCC_header_t { // Structure of PCX file header - byte mfctr, vers, enc, bpx; - uint16 x1, y1, x2, y2; // bounding box - uint16 xres, yres; - byte palette[3 * kNumColors]; // EGA color palette - byte vmode, planes; - uint16 bytesPerLine; // Bytes per line - byte fill2[60]; + struct _PCCHeader_t { // Structure of PCX file header + byte _mfctr, _vers, _enc, _bpx; + uint16 _x1, _y1, _x2, _y2; // bounding box + uint16 _xres, _yres; + byte _palette[3 * kNumColors]; // EGA color palette + byte _vmode, _planes; + uint16 _bytesPerLine; // Bytes per line + byte _fill2[60]; }; // Header of a PCC file bool firstUIFFl; @@ -112,13 +112,13 @@ protected: Common::File _sceneryArchive1; // Handle for scenery file Common::File _objectsArchive; // Handle for objects file - PCC_header_t PCC_header; + _PCCHeader_t _PCCHeader; seq_t *readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr, const bool firstFl, const char *name); // If this is the first call, read the lookup table - bool has_read_header; - sound_hdr_t s_hdr[kMaxSounds]; // Sound lookup table + bool _hasReadHeader; + sound_hdr_t _s_hdr[kMaxSounds]; // Sound lookup table private: byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, image_pt dataPtr) const; diff --git a/engines/hugo/file_v1w.cpp b/engines/hugo/file_v1w.cpp index 8a06cef939..3bb4b66367 100644 --- a/engines/hugo/file_v1w.cpp +++ b/engines/hugo/file_v1w.cpp @@ -52,28 +52,28 @@ void FileManager_v1w::readOverlay(const int screenNum, image_pt image, ovl_t ove _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Database header entry - sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock.b_off = _sceneryArchive1.readUint32LE(); - sceneBlock.b_len = _sceneryArchive1.readUint32LE(); - sceneBlock.o_off = _sceneryArchive1.readUint32LE(); - sceneBlock.o_len = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); + sceneBlock._b_off = _sceneryArchive1.readUint32LE(); + sceneBlock._b_len = _sceneryArchive1.readUint32LE(); + sceneBlock._o_off = _sceneryArchive1.readUint32LE(); + sceneBlock._o_len = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); uint32 i = 0; switch (overlayType) { case kOvlBoundary: - _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET); - i = sceneBlock.b_len; + _sceneryArchive1.seek(sceneBlock._b_off, SEEK_SET); + i = sceneBlock._b_len; break; case kOvlOverlay: - _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET); - i = sceneBlock.o_len; + _sceneryArchive1.seek(sceneBlock._o_off, SEEK_SET); + i = sceneBlock._o_len; break; case kOvlBase: - _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET); - i = sceneBlock.ob_len; + _sceneryArchive1.seek(sceneBlock._ob_off, SEEK_SET); + i = sceneBlock._ob_len; break; default: error("Bad overlayType: %d", overlayType); diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp index 520e1b77b6..009b0b0bb8 100644 --- a/engines/hugo/file_v2d.cpp +++ b/engines/hugo/file_v2d.cpp @@ -81,16 +81,16 @@ void FileManager_v2d::readBackground(const int screenIndex) { _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Read a database header entry - sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock.b_off = _sceneryArchive1.readUint32LE(); - sceneBlock.b_len = _sceneryArchive1.readUint32LE(); - sceneBlock.o_off = _sceneryArchive1.readUint32LE(); - sceneBlock.o_len = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); + sceneBlock._b_off = _sceneryArchive1.readUint32LE(); + sceneBlock._b_len = _sceneryArchive1.readUint32LE(); + sceneBlock._o_off = _sceneryArchive1.readUint32LE(); + sceneBlock._o_len = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); - _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET); + _sceneryArchive1.seek(sceneBlock._scene_off, SEEK_SET); // Read the image into dummy seq and static dib_a seq_t *dummySeq; // Image sequence structure for Read_pcx @@ -108,28 +108,28 @@ void FileManager_v2d::readOverlay(const int screenNum, image_pt image, ovl_t ove _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Database header entry - sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock.b_off = _sceneryArchive1.readUint32LE(); - sceneBlock.b_len = _sceneryArchive1.readUint32LE(); - sceneBlock.o_off = _sceneryArchive1.readUint32LE(); - sceneBlock.o_len = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); + sceneBlock._b_off = _sceneryArchive1.readUint32LE(); + sceneBlock._b_len = _sceneryArchive1.readUint32LE(); + sceneBlock._o_off = _sceneryArchive1.readUint32LE(); + sceneBlock._o_len = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); uint32 i = 0; switch (overlayType) { case kOvlBoundary: - _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET); - i = sceneBlock.b_len; + _sceneryArchive1.seek(sceneBlock._b_off, SEEK_SET); + i = sceneBlock._b_len; break; case kOvlOverlay: - _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET); - i = sceneBlock.o_len; + _sceneryArchive1.seek(sceneBlock._o_off, SEEK_SET); + i = sceneBlock._o_len; break; case kOvlBase: - _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET); - i = sceneBlock.ob_len; + _sceneryArchive1.seek(sceneBlock._ob_off, SEEK_SET); + i = sceneBlock._ob_len; break; default: error("Bad overlayType: %d", overlayType); diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp index d86003a040..99a3a68d9e 100644 --- a/engines/hugo/file_v3d.cpp +++ b/engines/hugo/file_v3d.cpp @@ -53,22 +53,22 @@ void FileManager_v3d::readBackground(const int screenIndex) { _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Read a database header entry - sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock.b_off = _sceneryArchive1.readUint32LE(); - sceneBlock.b_len = _sceneryArchive1.readUint32LE(); - sceneBlock.o_off = _sceneryArchive1.readUint32LE(); - sceneBlock.o_len = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); + sceneBlock._b_off = _sceneryArchive1.readUint32LE(); + sceneBlock._b_len = _sceneryArchive1.readUint32LE(); + sceneBlock._o_off = _sceneryArchive1.readUint32LE(); + sceneBlock._o_len = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); seq_t *dummySeq; // Image sequence structure for Read_pcx if (screenIndex < 20) { - _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET); + _sceneryArchive1.seek(sceneBlock._scene_off, SEEK_SET); // Read the image into dummy seq and static dib_a dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); } else { - _sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET); + _sceneryArchive2.seek(sceneBlock._scene_off, SEEK_SET); // Read the image into dummy seq and static dib_a dummySeq = readPCX(_sceneryArchive2, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); } @@ -113,30 +113,30 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Database header entry - sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock.b_off = _sceneryArchive1.readUint32LE(); - sceneBlock.b_len = _sceneryArchive1.readUint32LE(); - sceneBlock.o_off = _sceneryArchive1.readUint32LE(); - sceneBlock.o_len = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); + sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); + sceneBlock._b_off = _sceneryArchive1.readUint32LE(); + sceneBlock._b_len = _sceneryArchive1.readUint32LE(); + sceneBlock._o_off = _sceneryArchive1.readUint32LE(); + sceneBlock._o_len = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); + sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); uint32 i = 0; if (screenNum < 20) { switch (overlayType) { case kOvlBoundary: - _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET); - i = sceneBlock.b_len; + _sceneryArchive1.seek(sceneBlock._b_off, SEEK_SET); + i = sceneBlock._b_len; break; case kOvlOverlay: - _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET); - i = sceneBlock.o_len; + _sceneryArchive1.seek(sceneBlock._o_off, SEEK_SET); + i = sceneBlock._o_len; break; case kOvlBase: - _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET); - i = sceneBlock.ob_len; + _sceneryArchive1.seek(sceneBlock._ob_off, SEEK_SET); + i = sceneBlock._ob_len; break; default: error("Bad overlayType: %d", overlayType); @@ -166,16 +166,16 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove } else { switch (overlayType) { case kOvlBoundary: - _sceneryArchive2.seek(sceneBlock.b_off, SEEK_SET); - i = sceneBlock.b_len; + _sceneryArchive2.seek(sceneBlock._b_off, SEEK_SET); + i = sceneBlock._b_len; break; case kOvlOverlay: - _sceneryArchive2.seek(sceneBlock.o_off, SEEK_SET); - i = sceneBlock.o_len; + _sceneryArchive2.seek(sceneBlock._o_off, SEEK_SET); + i = sceneBlock._o_len; break; case kOvlBase: - _sceneryArchive2.seek(sceneBlock.ob_off, SEEK_SET); - i = sceneBlock.ob_len; + _sceneryArchive2.seek(sceneBlock._ob_off, SEEK_SET); + i = sceneBlock._ob_len; break; default: error("Bad overlayType: %d", overlayType); -- cgit v1.2.3 From 045613af95b84b6a57526125da35b949d0f431ea Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 12:54:40 +0300 Subject: SCI: Shuffle the kernel functions inside kfile.cpp This puts them in the order that they are defined in the kernel tables --- engines/sci/engine/kfile.cpp | 1144 +++++++++++++++++++++--------------------- 1 file changed, 580 insertions(+), 564 deletions(-) diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 052332957b..445a019368 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -152,18 +152,6 @@ reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) { -#ifdef ENABLE_SCI32 - // SCI32 uses a parameter here. It is used to modify a string, stored in a - // global variable, so that game scripts store the save directory. We - // don't really set a save game directory, thus not setting the string to - // anything is the correct thing to do here. - //if (argc > 0) - // warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0])); -#endif - return s->_segMan->getSaveDirPtr(); -} - reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) { if (argc > 1) { // SCI1.1/SCI32 @@ -194,292 +182,187 @@ reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 1); } -reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) { - Common::String game_id = s->_segMan->getString(argv[0]); - uint16 virtualId = argv[1].toUint16(); - - debug(3, "kCheckSaveGame(%s, %d)", game_id.c_str(), virtualId); +reg_t kValidPath(EngineState *s, int argc, reg_t *argv) { + Common::String path = s->_segMan->getString(argv[0]); - Common::Array saves; - listSavegames(saves); + debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.offset); - // we allow 0 (happens in QfG2 when trying to restore from an empty saved game list) and return false in that case - if (virtualId == 0) - return NULL_REG; + // Always return true + return make_reg(0, 1); +} - // Find saved-game - if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END)) - error("kCheckSaveGame: called with invalid savegameId"); - uint savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START; - int savegameNr = findSavegame(saves, savegameId); - if (savegameNr == -1) - return NULL_REG; +#ifdef ENABLE_SCI32 - // Check for compatible savegame version - int ver = saves[savegameNr].version; - if (ver < MINIMUM_SAVEGAME_VERSION || ver > CURRENT_SAVEGAME_VERSION) - return NULL_REG; +reg_t kCD(EngineState *s, int argc, reg_t *argv) { + // TODO: Stub + switch (argv[0].toUint16()) { + case 0: + // Return whether the contents of disc argv[1] is available. + return TRUE_REG; + default: + warning("CD(%d)", argv[0].toUint16()); + } - // Otherwise we assume the savegame is OK - return TRUE_REG; + return NULL_REG; } -reg_t kGetSaveFiles(EngineState *s, int argc, reg_t *argv) { - Common::String game_id = s->_segMan->getString(argv[0]); - - debug(3, "kGetSaveFiles(%s)", game_id.c_str()); +#endif - // Scripts ask for current save files, we can assume that if afterwards they ask us to create a new slot they really - // mean new slot instead of overwriting the old one - s->_lastSaveVirtualId = SAVEGAMEID_OFFICIALRANGE_START; +// ---- FileIO operations ----------------------------------------------------- - Common::Array saves; - listSavegames(saves); - uint totalSaves = MIN(saves.size(), MAX_SAVEGAME_NR); +reg_t kFileIO(EngineState *s, int argc, reg_t *argv) { + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} - reg_t *slot = s->_segMan->derefRegPtr(argv[2], totalSaves); +reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { + Common::String name = s->_segMan->getString(argv[0]); - if (!slot) { - warning("kGetSaveFiles: %04X:%04X invalid or too small to hold slot data", PRINT_REG(argv[2])); - totalSaves = 0; +#ifdef ENABLE_SCI32 + if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { + if (s->_virtualIndexFile) { + return make_reg(0, VIRTUALFILE_HANDLE); + } else { + Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH); + Common::String wrappedName = g_sci->wrapFilename(englishName); + if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) { + s->_virtualIndexFile = new VirtualIndexFile(wrappedName); + return make_reg(0, VIRTUALFILE_HANDLE); + } + } } +#endif - const uint bufSize = (totalSaves * SCI_MAX_SAVENAME_LENGTH) + 1; - char *saveNames = new char[bufSize]; - char *saveNamePtr = saveNames; + // SCI32 can call K_FILEIO_OPEN with only one argument. It seems to + // just be checking if it exists. + int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16(); + bool unwrapFilename = true; - for (uint i = 0; i < totalSaves; i++) { - *slot++ = make_reg(0, saves[i].id + SAVEGAMEID_OFFICIALRANGE_START); // Store the virtual savegame ID ffs. see above - strcpy(saveNamePtr, saves[i].name); - saveNamePtr += SCI_MAX_SAVENAME_LENGTH; + // SQ4 floppy prepends /\ to the filenames + if (name.hasPrefix("/\\")) { + name.deleteChar(0); + name.deleteChar(0); } - *saveNamePtr = 0; // Terminate list + // SQ4 floppy attempts to update the savegame index file sq4sg.dir when + // deleting saved games. We don't use an index file for saving or loading, + // so just stop the game from modifying the file here in order to avoid + // having it saved in the ScummVM save directory. + if (name == "sq4sg.dir") { + debugC(kDebugLevelFile, "Not opening unused file sq4sg.dir"); + return SIGNAL_REG; + } - s->_segMan->memcpy(argv[1], (byte *)saveNames, bufSize); - delete[] saveNames; + if (name.empty()) { + // Happens many times during KQ1 (e.g. when typing something) + debugC(kDebugLevelFile, "Attempted to open a file with an empty filename"); + return SIGNAL_REG; + } + debugC(kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode); - return make_reg(0, totalSaves); + // QFG import rooms get a virtual filelisting instead of an actual one + if (g_sci->inQfGImportRoom()) { + // We need to find out what the user actually selected, "savedHeroes" is + // already destroyed when we get here. That's why we need to remember + // selection via kDrawControl. + name = s->_dirseeker.getVirtualFilename(s->_chosenQfGImportItem); + unwrapFilename = false; + } + + return file_open(s, name, mode, unwrapFilename); } -reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { - Common::String game_id; - int16 virtualId = argv[1].toSint16(); - int16 savegameId = -1; - Common::String game_description; - Common::String version; +reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { + debugC(kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16()); - if (argc > 3) - version = s->_segMan->getString(argv[3]); + if (argv[0] == SIGNAL_REG) + return s->r_acc; + + uint16 handle = argv[0].toUint16(); - // We check here, we don't want to delete a users save in case we are within a kernel function - if (s->executionStackBase) { - warning("kSaveGame - won't save from within kernel function"); - return NULL_REG; +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + s->_virtualIndexFile->close(); + return SIGNAL_REG; } +#endif - if (argv[0].isNull()) { - // Direct call, from a patched Game::save - if ((argv[1] != SIGNAL_REG) || (!argv[2].isNull())) - error("kSaveGame: assumed patched call isn't accurate"); - - // we are supposed to show a dialog for the user and let him choose where to save - g_sci->_soundCmd->pauseAll(true); // pause music - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); - savegameId = dialog->runModalWithCurrentTarget(); - game_description = dialog->getResultString(); - if (game_description.empty()) { - // create our own description for the saved game, the user didnt enter it - game_description = dialog->createDefaultSaveDescription(savegameId); - } - delete dialog; - g_sci->_soundCmd->pauseAll(false); // unpause music ( we can't have it paused during save) - if (savegameId < 0) - return NULL_REG; - - } else { - // Real call from script - game_id = s->_segMan->getString(argv[0]); - if (argv[2].isNull()) - error("kSaveGame: called with description being NULL"); - game_description = s->_segMan->getString(argv[2]); - - debug(3, "kSaveGame(%s,%d,%s,%s)", game_id.c_str(), virtualId, game_description.c_str(), version.c_str()); + FileHandle *f = getFileFromHandle(s, handle); + if (f) { + f->close(); + if (getSciVersion() <= SCI_VERSION_0_LATE) + return s->r_acc; // SCI0 semantics: no value returned + return SIGNAL_REG; + } - Common::Array saves; - listSavegames(saves); + if (getSciVersion() <= SCI_VERSION_0_LATE) + return s->r_acc; // SCI0 semantics: no value returned + return NULL_REG; +} - if ((virtualId >= SAVEGAMEID_OFFICIALRANGE_START) && (virtualId <= SAVEGAMEID_OFFICIALRANGE_END)) { - // savegameId is an actual Id, so search for it just to make sure - savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START; - if (findSavegame(saves, savegameId) == -1) - return NULL_REG; - } else if (virtualId < SAVEGAMEID_OFFICIALRANGE_START) { - // virtualId is low, we assume that scripts expect us to create new slot - if (virtualId == s->_lastSaveVirtualId) { - // if last virtual id is the same as this one, we assume that caller wants to overwrite last save - savegameId = s->_lastSaveNewId; - } else { - uint savegameNr; - // savegameId is in lower range, scripts expect us to create a new slot - for (savegameId = 0; savegameId < SAVEGAMEID_OFFICIALRANGE_START; savegameId++) { - for (savegameNr = 0; savegameNr < saves.size(); savegameNr++) { - if (savegameId == saves[savegameNr].id) - break; - } - if (savegameNr == saves.size()) - break; - } - if (savegameId == SAVEGAMEID_OFFICIALRANGE_START) - error("kSavegame: no more savegame slots available"); - } - } else { - error("kSaveGame: invalid savegameId used"); - } +reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) { + uint16 handle = argv[0].toUint16(); + uint16 size = argv[2].toUint16(); + int bytesRead = 0; + char *buf = new char[size]; + debugC(kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size); - // Save in case caller wants to overwrite last newly created save - s->_lastSaveVirtualId = virtualId; - s->_lastSaveNewId = savegameId; +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + bytesRead = s->_virtualIndexFile->read(buf, size); + } else { +#endif + FileHandle *f = getFileFromHandle(s, handle); + if (f) + bytesRead = f->_in->read(buf, size); +#ifdef ENABLE_SCI32 } +#endif - s->r_acc = NULL_REG; + // TODO: What happens if less bytes are read than what has + // been requested? (i.e. if bytesRead is non-zero, but still + // less than size) + if (bytesRead > 0) + s->_segMan->memcpy(argv[1], (const byte*)buf, size); - Common::String filename = g_sci->getSavegameName(savegameId); - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - Common::OutSaveFile *out; + delete[] buf; + return make_reg(0, bytesRead); +} - out = saveFileMan->openForSaving(filename); - if (!out) { - warning("Error opening savegame \"%s\" for writing", filename.c_str()); - } else { - if (!gamestate_save(s, out, game_description, version)) { - warning("Saving the game failed"); - } else { - s->r_acc = TRUE_REG; // save successful - } - - out->finalize(); - if (out->err()) { - warning("Writing the savegame failed"); - s->r_acc = NULL_REG; // write failure - } - delete out; - } - - return s->r_acc; -} - -reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { - Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : ""; - int16 savegameId = argv[1].toSint16(); - bool pausedMusic = false; - - debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId); - - if (argv[0].isNull()) { - // Direct call, either from launcher or from a patched Game::restore - if (savegameId == -1) { - // we are supposed to show a dialog for the user and let him choose a saved game - g_sci->_soundCmd->pauseAll(true); // pause music - GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); - savegameId = dialog->runModalWithCurrentTarget(); - delete dialog; - if (savegameId < 0) { - g_sci->_soundCmd->pauseAll(false); // unpause music - return s->r_acc; - } - pausedMusic = true; - } - // don't adjust ID of the saved game, it's already correct - } else { - if (argv[2].isNull()) - error("kRestoreGame: called with parameter 2 being NULL"); - // Real call from script, we need to adjust ID - if ((savegameId < SAVEGAMEID_OFFICIALRANGE_START) || (savegameId > SAVEGAMEID_OFFICIALRANGE_END)) { - warning("Savegame ID %d is not allowed", savegameId); - return TRUE_REG; - } - savegameId -= SAVEGAMEID_OFFICIALRANGE_START; - } - - s->r_acc = NULL_REG; // signals success +reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { + uint16 handle = argv[0].toUint16(); + uint16 size = argv[2].toUint16(); + char *buf = new char[size]; + bool success = false; + s->_segMan->memcpy((byte *)buf, argv[1], size); + debugC(kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size); - Common::Array saves; - listSavegames(saves); - if (findSavegame(saves, savegameId) == -1) { - s->r_acc = TRUE_REG; - warning("Savegame ID %d not found", savegameId); +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) { + s->_virtualIndexFile->write(buf, size); + success = true; } else { - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - Common::String filename = g_sci->getSavegameName(savegameId); - Common::SeekableReadStream *in; - - in = saveFileMan->openForLoading(filename); - if (in) { - // found a savegame file - - gamestate_restore(s, in); - delete in; - - if (g_sci->getGameId() == GID_MOTHERGOOSE256) { - // WORKAROUND: Mother Goose SCI1/SCI1.1 does some weird things for - // saving a previously restored game. - // We set the current savedgame-id directly and remove the script - // code concerning this via script patch. - s->variables[VAR_GLOBAL][0xB3].offset = SAVEGAMEID_OFFICIALRANGE_START + savegameId; - } - } else { - s->r_acc = TRUE_REG; - warning("Savegame #%d not found", savegameId); +#endif + FileHandle *f = getFileFromHandle(s, handle); + if (f) { + f->_out->write(buf, size); + success = true; } +#ifdef ENABLE_SCI32 } +#endif - if (!s->r_acc.isNull()) { - // no success? - if (pausedMusic) - g_sci->_soundCmd->pauseAll(false); // unpause music - } - - return s->r_acc; -} - -reg_t kValidPath(EngineState *s, int argc, reg_t *argv) { - Common::String path = s->_segMan->getString(argv[0]); - - debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.offset); - - // Always return true - return make_reg(0, 1); -} - -reg_t kFileIO(EngineState *s, int argc, reg_t *argv) { - if (!s) - return make_reg(0, getSciVersion()); - error("not supposed to call this"); + delete[] buf; + if (success) + return NULL_REG; + return make_reg(0, 6); // DOS - invalid handle } -reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { +reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); - -#ifdef ENABLE_SCI32 - if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { - if (s->_virtualIndexFile) { - return make_reg(0, VIRTUALFILE_HANDLE); - } else { - Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH); - Common::String wrappedName = g_sci->wrapFilename(englishName); - if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) { - s->_virtualIndexFile = new VirtualIndexFile(wrappedName); - return make_reg(0, VIRTUALFILE_HANDLE); - } - } - } -#endif - - // SCI32 can call K_FILEIO_OPEN with only one argument. It seems to - // just be checking if it exists. - int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16(); - bool unwrapFilename = true; + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + bool result; // SQ4 floppy prepends /\ to the filenames if (name.hasPrefix("/\\")) { @@ -487,407 +370,546 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { name.deleteChar(0); } - // SQ4 floppy attempts to update the savegame index file sq4sg.dir when - // deleting saved games. We don't use an index file for saving or loading, - // so just stop the game from modifying the file here in order to avoid - // having it saved in the ScummVM save directory. - if (name == "sq4sg.dir") { - debugC(kDebugLevelFile, "Not opening unused file sq4sg.dir"); - return SIGNAL_REG; - } - - if (name.empty()) { - // Happens many times during KQ1 (e.g. when typing something) - debugC(kDebugLevelFile, "Attempted to open a file with an empty filename"); - return SIGNAL_REG; - } - debugC(kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode); + // Special case for SQ4 floppy: This game has hardcoded names for all of + // its savegames, and they are all named "sq4sg.xxx", where xxx is the + // slot. We just take the slot number here, and delete the appropriate + // save game. + if (name.hasPrefix("sq4sg.")) { + // Special handling for SQ4... get the slot number and construct the + // save game name. + int slotNum = atoi(name.c_str() + name.size() - 3); + Common::Array saves; + listSavegames(saves); + int savedir_nr = saves[slotNum].id; + name = g_sci->getSavegameName(savedir_nr); + result = saveFileMan->removeSavefile(name); + } else if (getSciVersion() >= SCI_VERSION_2) { + // The file name may be already wrapped, so check both cases + result = saveFileMan->removeSavefile(name); + if (!result) { + const Common::String wrappedName = g_sci->wrapFilename(name); + result = saveFileMan->removeSavefile(wrappedName); + } - // QFG import rooms get a virtual filelisting instead of an actual one - if (g_sci->inQfGImportRoom()) { - // We need to find out what the user actually selected, "savedHeroes" is - // already destroyed when we get here. That's why we need to remember - // selection via kDrawControl. - name = s->_dirseeker.getVirtualFilename(s->_chosenQfGImportItem); - unwrapFilename = false; +#ifdef ENABLE_SCI32 + if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { + delete s->_virtualIndexFile; + s->_virtualIndexFile = 0; + } +#endif + } else { + const Common::String wrappedName = g_sci->wrapFilename(name); + result = saveFileMan->removeSavefile(wrappedName); } - return file_open(s, name, mode, unwrapFilename); + debugC(kDebugLevelFile, "kFileIO(unlink): %s", name.c_str()); + if (result) + return NULL_REG; + return make_reg(0, 2); // DOS - file not found error code } -reg_t kFileIOClose(EngineState *s, int argc, reg_t *argv) { - debugC(kDebugLevelFile, "kFileIO(close): %d", argv[0].toUint16()); +reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { + uint16 maxsize = argv[1].toUint16(); + char *buf = new char[maxsize]; + uint16 handle = argv[2].toUint16(); + debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, maxsize); + uint32 bytesRead; - if (argv[0] == SIGNAL_REG) - return s->r_acc; - - uint16 handle = argv[0].toUint16(); +#ifdef ENABLE_SCI32 + if (handle == VIRTUALFILE_HANDLE) + bytesRead = s->_virtualIndexFile->readLine(buf, maxsize); + else +#endif + bytesRead = fgets_wrapper(s, buf, maxsize, handle); + + s->_segMan->memcpy(argv[0], (const byte*)buf, maxsize); + delete[] buf; + return bytesRead ? argv[0] : NULL_REG; +} + +reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { + int handle = argv[0].toUint16(); + Common::String str = s->_segMan->getString(argv[1]); + debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle); #ifdef ENABLE_SCI32 if (handle == VIRTUALFILE_HANDLE) { - s->_virtualIndexFile->close(); - return SIGNAL_REG; + s->_virtualIndexFile->write(str.c_str(), str.size()); + return NULL_REG; } #endif FileHandle *f = getFileFromHandle(s, handle); + if (f) { - f->close(); + f->_out->write(str.c_str(), str.size()); if (getSciVersion() <= SCI_VERSION_0_LATE) return s->r_acc; // SCI0 semantics: no value returned - return SIGNAL_REG; + return NULL_REG; } if (getSciVersion() <= SCI_VERSION_0_LATE) return s->r_acc; // SCI0 semantics: no value returned - return NULL_REG; + return make_reg(0, 6); // DOS - invalid handle } -reg_t kFileIOReadRaw(EngineState *s, int argc, reg_t *argv) { +reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { uint16 handle = argv[0].toUint16(); - uint16 size = argv[2].toUint16(); - int bytesRead = 0; - char *buf = new char[size]; - debugC(kDebugLevelFile, "kFileIO(readRaw): %d, %d", handle, size); + uint16 offset = ABS(argv[1].toSint16()); // can be negative + uint16 whence = argv[2].toUint16(); + debugC(kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence); #ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) { - bytesRead = s->_virtualIndexFile->read(buf, size); - } else { + if (handle == VIRTUALFILE_HANDLE) + return make_reg(0, s->_virtualIndexFile->seek(offset, whence)); #endif - FileHandle *f = getFileFromHandle(s, handle); - if (f) - bytesRead = f->_in->read(buf, size); -#ifdef ENABLE_SCI32 + + FileHandle *f = getFileFromHandle(s, handle); + + if (f && f->_in) { + // Backward seeking isn't supported in zip file streams, thus adapt the + // parameters accordingly if games ask for such a seek mode. A known + // case where this is requested is the save file manager in Phantasmagoria + if (whence == SEEK_END) { + whence = SEEK_SET; + offset = f->_in->size() - offset; + } + + return make_reg(0, f->_in->seek(offset, whence)); + } else if (f && f->_out) { + error("kFileIOSeek: Unsupported seek operation on a writeable stream (offset: %d, whence: %d)", offset, whence); } -#endif - // TODO: What happens if less bytes are read than what has - // been requested? (i.e. if bytesRead is non-zero, but still - // less than size) - if (bytesRead > 0) - s->_segMan->memcpy(argv[1], (const byte*)buf, size); + return SIGNAL_REG; +} - delete[] buf; - return make_reg(0, bytesRead); +reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv) { + Common::String mask = s->_segMan->getString(argv[0]); + reg_t buf = argv[1]; + int attr = argv[2].toUint16(); // We won't use this, Win32 might, though... + debugC(kDebugLevelFile, "kFileIO(findFirst): %s, 0x%x", mask.c_str(), attr); + + // We remove ".*". mask will get prefixed, so we will return all additional files for that gameid + if (mask == "*.*") + mask = "*"; + return s->_dirseeker.firstFile(mask, buf, s->_segMan); } -reg_t kFileIOWriteRaw(EngineState *s, int argc, reg_t *argv) { - uint16 handle = argv[0].toUint16(); - uint16 size = argv[2].toUint16(); - char *buf = new char[size]; - bool success = false; - s->_segMan->memcpy((byte *)buf, argv[1], size); - debugC(kDebugLevelFile, "kFileIO(writeRaw): %d, %d", handle, size); +reg_t kFileIOFindNext(EngineState *s, int argc, reg_t *argv) { + debugC(kDebugLevelFile, "kFileIO(findNext)"); + return s->_dirseeker.nextFile(s->_segMan); +} + +reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { + Common::String name = s->_segMan->getString(argv[0]); #ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) { - s->_virtualIndexFile->write(buf, size); - success = true; - } else { + // Cache the file existence result for the Phantasmagoria + // save index file, as the game scripts keep checking for + // its existence. + if (name == PHANTASMAGORIA_SAVEGAME_INDEX && s->_virtualIndexFile) + return TRUE_REG; #endif - FileHandle *f = getFileFromHandle(s, handle); - if (f) { - f->_out->write(buf, size); - success = true; - } -#ifdef ENABLE_SCI32 + + bool exists = false; + + // Check for regular file + exists = Common::File::exists(name); + + // Check for a savegame with the name + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + if (!exists) + exists = !saveFileMan->listSavefiles(name).empty(); + + // Try searching for the file prepending "target-" + const Common::String wrappedName = g_sci->wrapFilename(name); + if (!exists) { + exists = !saveFileMan->listSavefiles(wrappedName).empty(); } -#endif - delete[] buf; - if (success) - return NULL_REG; - return make_reg(0, 6); // DOS - invalid handle -} + // SCI2+ debug mode + if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) { + if (!exists && name == "1.scr") // PQ4 + exists = true; + if (!exists && name == "18.scr") // QFG4 + exists = true; + if (!exists && name == "99.scr") // GK1, KQ7 + exists = true; + if (!exists && name == "classes") // GK2, SQ6, LSL7 + exists = true; + } -reg_t kFileIOReadString(EngineState *s, int argc, reg_t *argv) { - uint16 maxsize = argv[1].toUint16(); - char *buf = new char[maxsize]; - uint16 handle = argv[2].toUint16(); - debugC(kDebugLevelFile, "kFileIO(readString): %d, %d", handle, maxsize); - uint32 bytesRead; + // Special case for non-English versions of LSL5: The English version of + // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if + // memory.drv exists (which is where the game's password is stored). If + // it's not found, it calls kFileIO() again, case K_FILEIO_OPEN for + // writing and creates a new file. Non-English versions call kFileIO(), + // case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be + // found. We create a default memory.drv file with no password, so that + // the game can continue. + if (!exists && name == "memory.drv") { + // Create a new file, and write the bytes for the empty password + // string inside + byte defaultContent[] = { 0xE9, 0xE9, 0xEB, 0xE1, 0x0D, 0x0A, 0x31, 0x30, 0x30, 0x30 }; + Common::WriteStream *outFile = saveFileMan->openForSaving(wrappedName); + for (int i = 0; i < 10; i++) + outFile->writeByte(defaultContent[i]); + outFile->finalize(); + exists = !outFile->err(); // check whether we managed to create the file. + delete outFile; + } -#ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) - bytesRead = s->_virtualIndexFile->readLine(buf, maxsize); - else -#endif - bytesRead = fgets_wrapper(s, buf, maxsize, handle); + // Special case for KQ6 Mac: The game checks for two video files to see + // if they exist before it plays them. Since we support multiple naming + // schemes for resource fork files, we also need to support that here in + // case someone has a "HalfDome.bin" file, etc. + if (!exists && g_sci->getGameId() == GID_KQ6 && g_sci->getPlatform() == Common::kPlatformMacintosh && + (name == "HalfDome" || name == "Kq6Movie")) + exists = Common::MacResManager::exists(name); - s->_segMan->memcpy(argv[0], (const byte*)buf, maxsize); - delete[] buf; - return bytesRead ? argv[0] : NULL_REG; + debugC(kDebugLevelFile, "kFileIO(fileExists) %s -> %d", name.c_str(), exists); + return make_reg(0, exists); } -reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) { - int handle = argv[0].toUint16(); - Common::String str = s->_segMan->getString(argv[1]); - debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle); +reg_t kFileIORename(EngineState *s, int argc, reg_t *argv) { + Common::String oldName = s->_segMan->getString(argv[0]); + Common::String newName = s->_segMan->getString(argv[1]); + + // SCI1.1 returns 0 on success and a DOS error code on fail. SCI32 + // returns -1 on fail. We just return -1 for all versions. + if (g_sci->getSaveFileManager()->renameSavefile(oldName, newName)) + return NULL_REG; + else + return SIGNAL_REG; +} #ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) { - s->_virtualIndexFile->write(str.c_str(), str.size()); +reg_t kFileIOReadByte(EngineState *s, int argc, reg_t *argv) { + // Read the byte into the low byte of the accumulator + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (!f) return NULL_REG; - } -#endif + return make_reg(0, (s->r_acc.toUint16() & 0xff00) | f->_in->readByte()); +} - FileHandle *f = getFileFromHandle(s, handle); +reg_t kFileIOWriteByte(EngineState *s, int argc, reg_t *argv) { + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (f) + f->_out->writeByte(argv[1].toUint16() & 0xff); + return s->r_acc; // FIXME: does this really not return anything? +} - if (f) { - f->_out->write(str.c_str(), str.size()); - if (getSciVersion() <= SCI_VERSION_0_LATE) - return s->r_acc; // SCI0 semantics: no value returned +reg_t kFileIOReadWord(EngineState *s, int argc, reg_t *argv) { + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (!f) return NULL_REG; - } + return make_reg(0, f->_in->readUint16LE()); +} - if (getSciVersion() <= SCI_VERSION_0_LATE) - return s->r_acc; // SCI0 semantics: no value returned - return make_reg(0, 6); // DOS - invalid handle +reg_t kFileIOWriteWord(EngineState *s, int argc, reg_t *argv) { + FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); + if (f) + f->_out->writeUint16LE(argv[1].toUint16()); + return s->r_acc; // FIXME: does this really not return anything? } -reg_t kFileIOUnlink(EngineState *s, int argc, reg_t *argv) { - Common::String name = s->_segMan->getString(argv[0]); - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - bool result; +reg_t kFileIOCreateSaveSlot(EngineState *s, int argc, reg_t *argv) { + // Used in Shivers when the user enters his name on the guest book + // in the beginning to start the game. - // SQ4 floppy prepends /\ to the filenames - if (name.hasPrefix("/\\")) { - name.deleteChar(0); - name.deleteChar(0); - } + // Creates a new save slot, and returns if the operation was successful - // Special case for SQ4 floppy: This game has hardcoded names for all of - // its savegames, and they are all named "sq4sg.xxx", where xxx is the - // slot. We just take the slot number here, and delete the appropriate - // save game. - if (name.hasPrefix("sq4sg.")) { - // Special handling for SQ4... get the slot number and construct the - // save game name. - int slotNum = atoi(name.c_str() + name.size() - 3); - Common::Array saves; - listSavegames(saves); - int savedir_nr = saves[slotNum].id; - name = g_sci->getSavegameName(savedir_nr); - result = saveFileMan->removeSavefile(name); - } else if (getSciVersion() >= SCI_VERSION_2) { - // The file name may be already wrapped, so check both cases - result = saveFileMan->removeSavefile(name); - if (!result) { - const Common::String wrappedName = g_sci->wrapFilename(name); - result = saveFileMan->removeSavefile(wrappedName); - } + // Argument 0 denotes the save slot as a negative integer, 2 means "0" + // Argument 1 is a string, with the file name, obtained from kSave(5). + // The interpreter checks if it can be written to (by checking for free + // disk space and write permissions) -#ifdef ENABLE_SCI32 - if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { - delete s->_virtualIndexFile; - s->_virtualIndexFile = 0; - } -#endif - } else { - const Common::String wrappedName = g_sci->wrapFilename(name); - result = saveFileMan->removeSavefile(wrappedName); - } + // We don't really use or need any of this... - debugC(kDebugLevelFile, "kFileIO(unlink): %s", name.c_str()); - if (result) - return NULL_REG; - return make_reg(0, 2); // DOS - file not found error code + uint16 saveSlot = argv[0].toUint16(); + char* fileName = s->_segMan->lookupString(argv[1])->getRawData(); + warning("kFileIOCreateSaveSlot(%d, '%s')", saveSlot, fileName); + + return TRUE_REG; // slot creation was successful } -reg_t kFileIOSeek(EngineState *s, int argc, reg_t *argv) { - uint16 handle = argv[0].toUint16(); - uint16 offset = ABS(argv[1].toSint16()); // can be negative - uint16 whence = argv[2].toUint16(); - debugC(kDebugLevelFile, "kFileIO(seek): %d, %d, %d", handle, offset, whence); +#endif + +// ---- Save operations ------------------------------------------------------- #ifdef ENABLE_SCI32 - if (handle == VIRTUALFILE_HANDLE) - return make_reg(0, s->_virtualIndexFile->seek(offset, whence)); + +reg_t kSave(EngineState *s, int argc, reg_t *argv) { + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} + #endif - FileHandle *f = getFileFromHandle(s, handle); +reg_t kSaveGame(EngineState *s, int argc, reg_t *argv) { + Common::String game_id; + int16 virtualId = argv[1].toSint16(); + int16 savegameId = -1; + Common::String game_description; + Common::String version; - if (f && f->_in) { - // Backward seeking isn't supported in zip file streams, thus adapt the - // parameters accordingly if games ask for such a seek mode. A known - // case where this is requested is the save file manager in Phantasmagoria - if (whence == SEEK_END) { - whence = SEEK_SET; - offset = f->_in->size() - offset; + if (argc > 3) + version = s->_segMan->getString(argv[3]); + + // We check here, we don't want to delete a users save in case we are within a kernel function + if (s->executionStackBase) { + warning("kSaveGame - won't save from within kernel function"); + return NULL_REG; + } + + if (argv[0].isNull()) { + // Direct call, from a patched Game::save + if ((argv[1] != SIGNAL_REG) || (!argv[2].isNull())) + error("kSaveGame: assumed patched call isn't accurate"); + + // we are supposed to show a dialog for the user and let him choose where to save + g_sci->_soundCmd->pauseAll(true); // pause music + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + savegameId = dialog->runModalWithCurrentTarget(); + game_description = dialog->getResultString(); + if (game_description.empty()) { + // create our own description for the saved game, the user didnt enter it + game_description = dialog->createDefaultSaveDescription(savegameId); } + delete dialog; + g_sci->_soundCmd->pauseAll(false); // unpause music ( we can't have it paused during save) + if (savegameId < 0) + return NULL_REG; - return make_reg(0, f->_in->seek(offset, whence)); - } else if (f && f->_out) { - error("kFileIOSeek: Unsupported seek operation on a writeable stream (offset: %d, whence: %d)", offset, whence); + } else { + // Real call from script + game_id = s->_segMan->getString(argv[0]); + if (argv[2].isNull()) + error("kSaveGame: called with description being NULL"); + game_description = s->_segMan->getString(argv[2]); + + debug(3, "kSaveGame(%s,%d,%s,%s)", game_id.c_str(), virtualId, game_description.c_str(), version.c_str()); + + Common::Array saves; + listSavegames(saves); + + if ((virtualId >= SAVEGAMEID_OFFICIALRANGE_START) && (virtualId <= SAVEGAMEID_OFFICIALRANGE_END)) { + // savegameId is an actual Id, so search for it just to make sure + savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START; + if (findSavegame(saves, savegameId) == -1) + return NULL_REG; + } else if (virtualId < SAVEGAMEID_OFFICIALRANGE_START) { + // virtualId is low, we assume that scripts expect us to create new slot + if (virtualId == s->_lastSaveVirtualId) { + // if last virtual id is the same as this one, we assume that caller wants to overwrite last save + savegameId = s->_lastSaveNewId; + } else { + uint savegameNr; + // savegameId is in lower range, scripts expect us to create a new slot + for (savegameId = 0; savegameId < SAVEGAMEID_OFFICIALRANGE_START; savegameId++) { + for (savegameNr = 0; savegameNr < saves.size(); savegameNr++) { + if (savegameId == saves[savegameNr].id) + break; + } + if (savegameNr == saves.size()) + break; + } + if (savegameId == SAVEGAMEID_OFFICIALRANGE_START) + error("kSavegame: no more savegame slots available"); + } + } else { + error("kSaveGame: invalid savegameId used"); + } + + // Save in case caller wants to overwrite last newly created save + s->_lastSaveVirtualId = virtualId; + s->_lastSaveNewId = savegameId; } - return SIGNAL_REG; -} + s->r_acc = NULL_REG; -reg_t kFileIOFindFirst(EngineState *s, int argc, reg_t *argv) { - Common::String mask = s->_segMan->getString(argv[0]); - reg_t buf = argv[1]; - int attr = argv[2].toUint16(); // We won't use this, Win32 might, though... - debugC(kDebugLevelFile, "kFileIO(findFirst): %s, 0x%x", mask.c_str(), attr); + Common::String filename = g_sci->getSavegameName(savegameId); + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + Common::OutSaveFile *out; + + out = saveFileMan->openForSaving(filename); + if (!out) { + warning("Error opening savegame \"%s\" for writing", filename.c_str()); + } else { + if (!gamestate_save(s, out, game_description, version)) { + warning("Saving the game failed"); + } else { + s->r_acc = TRUE_REG; // save successful + } + + out->finalize(); + if (out->err()) { + warning("Writing the savegame failed"); + s->r_acc = NULL_REG; // write failure + } + delete out; + } - // We remove ".*". mask will get prefixed, so we will return all additional files for that gameid - if (mask == "*.*") - mask = "*"; - return s->_dirseeker.firstFile(mask, buf, s->_segMan); + return s->r_acc; } -reg_t kFileIOFindNext(EngineState *s, int argc, reg_t *argv) { - debugC(kDebugLevelFile, "kFileIO(findNext)"); - return s->_dirseeker.nextFile(s->_segMan); -} +reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) { + Common::String game_id = !argv[0].isNull() ? s->_segMan->getString(argv[0]) : ""; + int16 savegameId = argv[1].toSint16(); + bool pausedMusic = false; -reg_t kFileIOExists(EngineState *s, int argc, reg_t *argv) { - Common::String name = s->_segMan->getString(argv[0]); + debug(3, "kRestoreGame(%s,%d)", game_id.c_str(), savegameId); -#ifdef ENABLE_SCI32 - // Cache the file existence result for the Phantasmagoria - // save index file, as the game scripts keep checking for - // its existence. - if (name == PHANTASMAGORIA_SAVEGAME_INDEX && s->_virtualIndexFile) - return TRUE_REG; -#endif + if (argv[0].isNull()) { + // Direct call, either from launcher or from a patched Game::restore + if (savegameId == -1) { + // we are supposed to show a dialog for the user and let him choose a saved game + g_sci->_soundCmd->pauseAll(true); // pause music + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + savegameId = dialog->runModalWithCurrentTarget(); + delete dialog; + if (savegameId < 0) { + g_sci->_soundCmd->pauseAll(false); // unpause music + return s->r_acc; + } + pausedMusic = true; + } + // don't adjust ID of the saved game, it's already correct + } else { + if (argv[2].isNull()) + error("kRestoreGame: called with parameter 2 being NULL"); + // Real call from script, we need to adjust ID + if ((savegameId < SAVEGAMEID_OFFICIALRANGE_START) || (savegameId > SAVEGAMEID_OFFICIALRANGE_END)) { + warning("Savegame ID %d is not allowed", savegameId); + return TRUE_REG; + } + savegameId -= SAVEGAMEID_OFFICIALRANGE_START; + } - bool exists = false; + s->r_acc = NULL_REG; // signals success - // Check for regular file - exists = Common::File::exists(name); + Common::Array saves; + listSavegames(saves); + if (findSavegame(saves, savegameId) == -1) { + s->r_acc = TRUE_REG; + warning("Savegame ID %d not found", savegameId); + } else { + Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); + Common::String filename = g_sci->getSavegameName(savegameId); + Common::SeekableReadStream *in; - // Check for a savegame with the name - Common::SaveFileManager *saveFileMan = g_sci->getSaveFileManager(); - if (!exists) - exists = !saveFileMan->listSavefiles(name).empty(); + in = saveFileMan->openForLoading(filename); + if (in) { + // found a savegame file - // Try searching for the file prepending "target-" - const Common::String wrappedName = g_sci->wrapFilename(name); - if (!exists) { - exists = !saveFileMan->listSavefiles(wrappedName).empty(); - } + gamestate_restore(s, in); + delete in; - // SCI2+ debug mode - if (DebugMan.isDebugChannelEnabled(kDebugLevelDebugMode)) { - if (!exists && name == "1.scr") // PQ4 - exists = true; - if (!exists && name == "18.scr") // QFG4 - exists = true; - if (!exists && name == "99.scr") // GK1, KQ7 - exists = true; - if (!exists && name == "classes") // GK2, SQ6, LSL7 - exists = true; + if (g_sci->getGameId() == GID_MOTHERGOOSE256) { + // WORKAROUND: Mother Goose SCI1/SCI1.1 does some weird things for + // saving a previously restored game. + // We set the current savedgame-id directly and remove the script + // code concerning this via script patch. + s->variables[VAR_GLOBAL][0xB3].offset = SAVEGAMEID_OFFICIALRANGE_START + savegameId; + } + } else { + s->r_acc = TRUE_REG; + warning("Savegame #%d not found", savegameId); + } } - // Special case for non-English versions of LSL5: The English version of - // LSL5 calls kFileIO(), case K_FILEIO_OPEN for reading to check if - // memory.drv exists (which is where the game's password is stored). If - // it's not found, it calls kFileIO() again, case K_FILEIO_OPEN for - // writing and creates a new file. Non-English versions call kFileIO(), - // case K_FILEIO_FILE_EXISTS instead, and fail if memory.drv can't be - // found. We create a default memory.drv file with no password, so that - // the game can continue. - if (!exists && name == "memory.drv") { - // Create a new file, and write the bytes for the empty password - // string inside - byte defaultContent[] = { 0xE9, 0xE9, 0xEB, 0xE1, 0x0D, 0x0A, 0x31, 0x30, 0x30, 0x30 }; - Common::WriteStream *outFile = saveFileMan->openForSaving(wrappedName); - for (int i = 0; i < 10; i++) - outFile->writeByte(defaultContent[i]); - outFile->finalize(); - exists = !outFile->err(); // check whether we managed to create the file. - delete outFile; + if (!s->r_acc.isNull()) { + // no success? + if (pausedMusic) + g_sci->_soundCmd->pauseAll(false); // unpause music } - // Special case for KQ6 Mac: The game checks for two video files to see - // if they exist before it plays them. Since we support multiple naming - // schemes for resource fork files, we also need to support that here in - // case someone has a "HalfDome.bin" file, etc. - if (!exists && g_sci->getGameId() == GID_KQ6 && g_sci->getPlatform() == Common::kPlatformMacintosh && - (name == "HalfDome" || name == "Kq6Movie")) - exists = Common::MacResManager::exists(name); + return s->r_acc; +} - debugC(kDebugLevelFile, "kFileIO(fileExists) %s -> %d", name.c_str(), exists); - return make_reg(0, exists); +reg_t kGetSaveDir(EngineState *s, int argc, reg_t *argv) { +#ifdef ENABLE_SCI32 + // SCI32 uses a parameter here. It is used to modify a string, stored in a + // global variable, so that game scripts store the save directory. We + // don't really set a save game directory, thus not setting the string to + // anything is the correct thing to do here. + //if (argc > 0) + // warning("kGetSaveDir called with %d parameter(s): %04x:%04x", argc, PRINT_REG(argv[0])); +#endif + return s->_segMan->getSaveDirPtr(); } -reg_t kFileIORename(EngineState *s, int argc, reg_t *argv) { - Common::String oldName = s->_segMan->getString(argv[0]); - Common::String newName = s->_segMan->getString(argv[1]); +reg_t kCheckSaveGame(EngineState *s, int argc, reg_t *argv) { + Common::String game_id = s->_segMan->getString(argv[0]); + uint16 virtualId = argv[1].toUint16(); - // SCI1.1 returns 0 on success and a DOS error code on fail. SCI32 - // returns -1 on fail. We just return -1 for all versions. - if (g_sci->getSaveFileManager()->renameSavefile(oldName, newName)) - return NULL_REG; - else - return SIGNAL_REG; -} + debug(3, "kCheckSaveGame(%s, %d)", game_id.c_str(), virtualId); -#ifdef ENABLE_SCI32 -reg_t kFileIOReadByte(EngineState *s, int argc, reg_t *argv) { - // Read the byte into the low byte of the accumulator - FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); - if (!f) + Common::Array saves; + listSavegames(saves); + + // we allow 0 (happens in QfG2 when trying to restore from an empty saved game list) and return false in that case + if (virtualId == 0) return NULL_REG; - return make_reg(0, (s->r_acc.toUint16() & 0xff00) | f->_in->readByte()); -} -reg_t kFileIOWriteByte(EngineState *s, int argc, reg_t *argv) { - FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); - if (f) - f->_out->writeByte(argv[1].toUint16() & 0xff); - return s->r_acc; // FIXME: does this really not return anything? -} + // Find saved-game + if ((virtualId < SAVEGAMEID_OFFICIALRANGE_START) || (virtualId > SAVEGAMEID_OFFICIALRANGE_END)) + error("kCheckSaveGame: called with invalid savegameId"); + uint savegameId = virtualId - SAVEGAMEID_OFFICIALRANGE_START; + int savegameNr = findSavegame(saves, savegameId); + if (savegameNr == -1) + return NULL_REG; -reg_t kFileIOReadWord(EngineState *s, int argc, reg_t *argv) { - FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); - if (!f) + // Check for compatible savegame version + int ver = saves[savegameNr].version; + if (ver < MINIMUM_SAVEGAME_VERSION || ver > CURRENT_SAVEGAME_VERSION) return NULL_REG; - return make_reg(0, f->_in->readUint16LE()); -} -reg_t kFileIOWriteWord(EngineState *s, int argc, reg_t *argv) { - FileHandle *f = getFileFromHandle(s, argv[0].toUint16()); - if (f) - f->_out->writeUint16LE(argv[1].toUint16()); - return s->r_acc; // FIXME: does this really not return anything? + // Otherwise we assume the savegame is OK + return TRUE_REG; } -reg_t kFileIOCreateSaveSlot(EngineState *s, int argc, reg_t *argv) { - // Used in Shivers when the user enters his name on the guest book - // in the beginning to start the game. +reg_t kGetSaveFiles(EngineState *s, int argc, reg_t *argv) { + Common::String game_id = s->_segMan->getString(argv[0]); - // Creates a new save slot, and returns if the operation was successful + debug(3, "kGetSaveFiles(%s)", game_id.c_str()); - // Argument 0 denotes the save slot as a negative integer, 2 means "0" - // Argument 1 is a string, with the file name, obtained from kSave(5). - // The interpreter checks if it can be written to (by checking for free - // disk space and write permissions) + // Scripts ask for current save files, we can assume that if afterwards they ask us to create a new slot they really + // mean new slot instead of overwriting the old one + s->_lastSaveVirtualId = SAVEGAMEID_OFFICIALRANGE_START; - // We don't really use or need any of this... + Common::Array saves; + listSavegames(saves); + uint totalSaves = MIN(saves.size(), MAX_SAVEGAME_NR); - uint16 saveSlot = argv[0].toUint16(); - char* fileName = s->_segMan->lookupString(argv[1])->getRawData(); - warning("kFileIOCreateSaveSlot(%d, '%s')", saveSlot, fileName); + reg_t *slot = s->_segMan->derefRegPtr(argv[2], totalSaves); - return TRUE_REG; // slot creation was successful -} + if (!slot) { + warning("kGetSaveFiles: %04X:%04X invalid or too small to hold slot data", PRINT_REG(argv[2])); + totalSaves = 0; + } -reg_t kCD(EngineState *s, int argc, reg_t *argv) { - // TODO: Stub - switch (argv[0].toUint16()) { - case 0: - // Return whether the contents of disc argv[1] is available. - return TRUE_REG; - default: - warning("CD(%d)", argv[0].toUint16()); + const uint bufSize = (totalSaves * SCI_MAX_SAVENAME_LENGTH) + 1; + char *saveNames = new char[bufSize]; + char *saveNamePtr = saveNames; + + for (uint i = 0; i < totalSaves; i++) { + *slot++ = make_reg(0, saves[i].id + SAVEGAMEID_OFFICIALRANGE_START); // Store the virtual savegame ID ffs. see above + strcpy(saveNamePtr, saves[i].name); + saveNamePtr += SCI_MAX_SAVENAME_LENGTH; } - return NULL_REG; + *saveNamePtr = 0; // Terminate list + + s->_segMan->memcpy(argv[1], (byte *)saveNames, bufSize); + delete[] saveNames; + + return make_reg(0, totalSaves); } +#ifdef ENABLE_SCI32 + reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv) { // Normally, this creates the name of the save catalogue/directory to save into. // First parameter is the string to save the result into. Second is a string @@ -928,12 +950,6 @@ reg_t kAutoSave(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } -reg_t kSave(EngineState *s, int argc, reg_t *argv) { - if (!s) - return make_reg(0, getSciVersion()); - error("not supposed to call this"); -} - #endif } // End of namespace Sci -- cgit v1.2.3 From d3929bd4bc4dbd0f7f2b57000be757e6bc7706e8 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 14:50:09 +0200 Subject: HUGO: Some more renaming --- engines/hugo/file.h | 16 +++---- engines/hugo/file_v1w.cpp | 28 ++++++------ engines/hugo/file_v2d.cpp | 46 +++++++++---------- engines/hugo/file_v3d.cpp | 60 ++++++++++++------------- engines/hugo/intro.cpp | 110 +++++++++++++++++++++++----------------------- engines/hugo/intro.h | 6 +-- engines/hugo/route.cpp | 22 +++++----- engines/hugo/route.h | 4 +- 8 files changed, 146 insertions(+), 146 deletions(-) diff --git a/engines/hugo/file.h b/engines/hugo/file.h index 81d3c73f5a..817bf49daf 100644 --- a/engines/hugo/file.h +++ b/engines/hugo/file.h @@ -85,14 +85,14 @@ protected: * Structure of scenery file lookup entry */ struct sceneBlock_t { - uint32 _scene_off; - uint32 _scene_len; - uint32 _b_off; - uint32 _b_len; - uint32 _o_off; - uint32 _o_len; - uint32 _ob_off; - uint32 _ob_len; + uint32 _sceneOffset; + uint32 _sceneLength; + uint32 _boundaryOffset; + uint32 _boundaryLength; + uint32 _overlayOffset; + uint32 _overlayLength; + uint32 _baseOffset; + uint32 _baseLength; }; struct _PCCHeader_t { // Structure of PCX file header diff --git a/engines/hugo/file_v1w.cpp b/engines/hugo/file_v1w.cpp index 3bb4b66367..fba13d6915 100644 --- a/engines/hugo/file_v1w.cpp +++ b/engines/hugo/file_v1w.cpp @@ -52,28 +52,28 @@ void FileManager_v1w::readOverlay(const int screenNum, image_pt image, ovl_t ove _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Database header entry - sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock._b_off = _sceneryArchive1.readUint32LE(); - sceneBlock._b_len = _sceneryArchive1.readUint32LE(); - sceneBlock._o_off = _sceneryArchive1.readUint32LE(); - sceneBlock._o_len = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayLength = _sceneryArchive1.readUint32LE(); + sceneBlock._baseOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._baseLength = _sceneryArchive1.readUint32LE(); uint32 i = 0; switch (overlayType) { case kOvlBoundary: - _sceneryArchive1.seek(sceneBlock._b_off, SEEK_SET); - i = sceneBlock._b_len; + _sceneryArchive1.seek(sceneBlock._boundaryOffset, SEEK_SET); + i = sceneBlock._boundaryLength; break; case kOvlOverlay: - _sceneryArchive1.seek(sceneBlock._o_off, SEEK_SET); - i = sceneBlock._o_len; + _sceneryArchive1.seek(sceneBlock._overlayOffset, SEEK_SET); + i = sceneBlock._overlayLength; break; case kOvlBase: - _sceneryArchive1.seek(sceneBlock._ob_off, SEEK_SET); - i = sceneBlock._ob_len; + _sceneryArchive1.seek(sceneBlock._baseOffset, SEEK_SET); + i = sceneBlock._baseLength; break; default: error("Bad overlayType: %d", overlayType); diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp index 009b0b0bb8..7239e5174a 100644 --- a/engines/hugo/file_v2d.cpp +++ b/engines/hugo/file_v2d.cpp @@ -81,16 +81,16 @@ void FileManager_v2d::readBackground(const int screenIndex) { _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Read a database header entry - sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock._b_off = _sceneryArchive1.readUint32LE(); - sceneBlock._b_len = _sceneryArchive1.readUint32LE(); - sceneBlock._o_off = _sceneryArchive1.readUint32LE(); - sceneBlock._o_len = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayLength = _sceneryArchive1.readUint32LE(); + sceneBlock._baseOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._baseLength = _sceneryArchive1.readUint32LE(); - _sceneryArchive1.seek(sceneBlock._scene_off, SEEK_SET); + _sceneryArchive1.seek(sceneBlock._sceneOffset, SEEK_SET); // Read the image into dummy seq and static dib_a seq_t *dummySeq; // Image sequence structure for Read_pcx @@ -108,28 +108,28 @@ void FileManager_v2d::readOverlay(const int screenNum, image_pt image, ovl_t ove _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Database header entry - sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock._b_off = _sceneryArchive1.readUint32LE(); - sceneBlock._b_len = _sceneryArchive1.readUint32LE(); - sceneBlock._o_off = _sceneryArchive1.readUint32LE(); - sceneBlock._o_len = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayLength = _sceneryArchive1.readUint32LE(); + sceneBlock._baseOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._baseLength = _sceneryArchive1.readUint32LE(); uint32 i = 0; switch (overlayType) { case kOvlBoundary: - _sceneryArchive1.seek(sceneBlock._b_off, SEEK_SET); - i = sceneBlock._b_len; + _sceneryArchive1.seek(sceneBlock._boundaryOffset, SEEK_SET); + i = sceneBlock._boundaryLength; break; case kOvlOverlay: - _sceneryArchive1.seek(sceneBlock._o_off, SEEK_SET); - i = sceneBlock._o_len; + _sceneryArchive1.seek(sceneBlock._overlayOffset, SEEK_SET); + i = sceneBlock._overlayLength; break; case kOvlBase: - _sceneryArchive1.seek(sceneBlock._ob_off, SEEK_SET); - i = sceneBlock._ob_len; + _sceneryArchive1.seek(sceneBlock._baseOffset, SEEK_SET); + i = sceneBlock._baseLength; break; default: error("Bad overlayType: %d", overlayType); diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp index 99a3a68d9e..34c745efb6 100644 --- a/engines/hugo/file_v3d.cpp +++ b/engines/hugo/file_v3d.cpp @@ -53,22 +53,22 @@ void FileManager_v3d::readBackground(const int screenIndex) { _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Read a database header entry - sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock._b_off = _sceneryArchive1.readUint32LE(); - sceneBlock._b_len = _sceneryArchive1.readUint32LE(); - sceneBlock._o_off = _sceneryArchive1.readUint32LE(); - sceneBlock._o_len = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayLength = _sceneryArchive1.readUint32LE(); + sceneBlock._baseOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._baseLength = _sceneryArchive1.readUint32LE(); seq_t *dummySeq; // Image sequence structure for Read_pcx if (screenIndex < 20) { - _sceneryArchive1.seek(sceneBlock._scene_off, SEEK_SET); + _sceneryArchive1.seek(sceneBlock._sceneOffset, SEEK_SET); // Read the image into dummy seq and static dib_a dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); } else { - _sceneryArchive2.seek(sceneBlock._scene_off, SEEK_SET); + _sceneryArchive2.seek(sceneBlock._sceneOffset, SEEK_SET); // Read the image into dummy seq and static dib_a dummySeq = readPCX(_sceneryArchive2, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); } @@ -113,30 +113,30 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); sceneBlock_t sceneBlock; // Database header entry - sceneBlock._scene_off = _sceneryArchive1.readUint32LE(); - sceneBlock._scene_len = _sceneryArchive1.readUint32LE(); - sceneBlock._b_off = _sceneryArchive1.readUint32LE(); - sceneBlock._b_len = _sceneryArchive1.readUint32LE(); - sceneBlock._o_off = _sceneryArchive1.readUint32LE(); - sceneBlock._o_len = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_off = _sceneryArchive1.readUint32LE(); - sceneBlock._ob_len = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._boundaryLength = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._overlayLength = _sceneryArchive1.readUint32LE(); + sceneBlock._baseOffset = _sceneryArchive1.readUint32LE(); + sceneBlock._baseLength = _sceneryArchive1.readUint32LE(); uint32 i = 0; if (screenNum < 20) { switch (overlayType) { case kOvlBoundary: - _sceneryArchive1.seek(sceneBlock._b_off, SEEK_SET); - i = sceneBlock._b_len; + _sceneryArchive1.seek(sceneBlock._boundaryOffset, SEEK_SET); + i = sceneBlock._boundaryLength; break; case kOvlOverlay: - _sceneryArchive1.seek(sceneBlock._o_off, SEEK_SET); - i = sceneBlock._o_len; + _sceneryArchive1.seek(sceneBlock._overlayOffset, SEEK_SET); + i = sceneBlock._overlayLength; break; case kOvlBase: - _sceneryArchive1.seek(sceneBlock._ob_off, SEEK_SET); - i = sceneBlock._ob_len; + _sceneryArchive1.seek(sceneBlock._baseOffset, SEEK_SET); + i = sceneBlock._baseLength; break; default: error("Bad overlayType: %d", overlayType); @@ -166,16 +166,16 @@ void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t ove } else { switch (overlayType) { case kOvlBoundary: - _sceneryArchive2.seek(sceneBlock._b_off, SEEK_SET); - i = sceneBlock._b_len; + _sceneryArchive2.seek(sceneBlock._boundaryOffset, SEEK_SET); + i = sceneBlock._boundaryLength; break; case kOvlOverlay: - _sceneryArchive2.seek(sceneBlock._o_off, SEEK_SET); - i = sceneBlock._o_len; + _sceneryArchive2.seek(sceneBlock._overlayOffset, SEEK_SET); + i = sceneBlock._overlayLength; break; case kOvlBase: - _sceneryArchive2.seek(sceneBlock._ob_off, SEEK_SET); - i = sceneBlock._ob_len; + _sceneryArchive2.seek(sceneBlock._baseOffset, SEEK_SET); + i = sceneBlock._baseLength; break; default: error("Bad overlayType: %d", overlayType); diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp index 599d8f21d3..f2ae06eb39 100644 --- a/engines/hugo/intro.cpp +++ b/engines/hugo/intro.cpp @@ -86,12 +86,12 @@ void intro_v1d::preNewGame() { void intro_v1d::introInit() { _introState = 0; - introTicks = 0; - surf.w = 320; - surf.h = 200; - surf.pixels = _vm->_screen->getFrontBuffer(); - surf.pitch = 320; - surf.format = Graphics::PixelFormat::createFormatCLUT8(); + _introTicks = 0; + _surf.w = 320; + _surf.h = 200; + _surf.pixels = _vm->_screen->getFrontBuffer(); + _surf.pitch = 320; + _surf.format = Graphics::PixelFormat::createFormatCLUT8(); _vm->_screen->displayList(kDisplayInit); } @@ -101,7 +101,7 @@ bool intro_v1d::introPlay() { if (_vm->getGameStatus()._skipIntroFl) return true; - if (introTicks < introSize) { + if (_introTicks < introSize) { switch (_introState++) { case 0: _vm->_screen->drawRectangle(true, 0, 0, 319, 199, _TMAGENTA); @@ -113,7 +113,7 @@ bool intro_v1d::introPlay() { _vm->_screen->drawShape(250,92,_TLIGHTMAGENTA,_TMAGENTA); // TROMAN, size 10-5 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8"); char buffer[80]; @@ -126,19 +126,19 @@ bool intro_v1d::introPlay() { else error("Unknown registration flag in hugo.bsf: %d", _vm->_boot._registered); - font.drawString(&surf, buffer, 0, 163, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); - font.drawString(&surf, _vm->getCopyrightString(), 0, 176, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 163, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, _vm->getCopyrightString(), 0, 176, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) { sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib); - font.drawString(&surf, buffer, 0, 75, 320, _TMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 75, 320, _TMAGENTA, Graphics::kTextAlignCenter); } // SCRIPT, size 24-16 strcpy(buffer, "Hugo's"); - if (font.loadFromFON("SCRIPT.FON")) { - font.drawString(&surf, buffer, 0, 20, 320, _TMAGENTA, Graphics::kTextAlignCenter); + if (_font.loadFromFON("SCRIPT.FON")) { + _font.drawString(&_surf, buffer, 0, 20, 320, _TMAGENTA, Graphics::kTextAlignCenter); } else { // Workaround: SCRIPT.FON doesn't load properly at the moment _vm->_screen->loadFont(2); @@ -146,78 +146,78 @@ bool intro_v1d::introPlay() { } // TROMAN, size 30-24 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 24))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 24))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 24"); strcpy(buffer, "House of Horrors !"); - font.drawString(&surf, buffer, 0, 50, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 50, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); break; case 2: _vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK); // TROMAN, size 16-9 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 14"); strcpy(buffer, "S t a r r i n g :"); - font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); break; case 3: // TROMAN, size 20-9 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 18"); strcpy(buffer, "Hugo !"); - font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); break; case 4: _vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK); // TROMAN, size 16-9 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 14))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 14"); strcpy(buffer, "P r o d u c e d b y :"); - font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); break; case 5: // TROMAN size 16-9 strcpy(buffer, "David P Gray !"); - font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); break; case 6: _vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK); // TROMAN, size 16-9 strcpy(buffer, "D i r e c t e d b y :"); - font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); break; case 7: // TROMAN, size 16-9 strcpy(buffer, "David P Gray !"); - font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); break; case 8: _vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK); // TROMAN, size 16-9 strcpy(buffer, "M u s i c b y :"); - font.drawString(&surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 95, 320, _TMAGENTA, Graphics::kTextAlignCenter); break; case 9: // TROMAN, size 16-9 strcpy(buffer, "David P Gray !"); - font.drawString(&surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 115, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); break; case 10: _vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK); // TROMAN, size 20-14 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 18))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 18"); strcpy(buffer, "E n j o y !"); - font.drawString(&surf, buffer, 0, 100, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 100, 320, _TLIGHTMAGENTA, Graphics::kTextAlignCenter); break; } @@ -226,7 +226,7 @@ bool intro_v1d::introPlay() { g_system->delayMillis(1000); } - return (++introTicks >= introSize); + return (++_introTicks >= introSize); } intro_v2d::intro_v2d(HugoEngine *vm) : IntroHandler(vm) { @@ -241,16 +241,16 @@ void intro_v2d::preNewGame() { void intro_v2d::introInit() { _vm->_screen->displayList(kDisplayInit); _vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen - surf.w = 320; - surf.h = 200; - surf.pixels = _vm->_screen->getFrontBuffer(); - surf.pitch = 320; - surf.format = Graphics::PixelFormat::createFormatCLUT8(); + _surf.w = 320; + _surf.h = 200; + _surf.pixels = _vm->_screen->getFrontBuffer(); + _surf.pitch = 320; + _surf.format = Graphics::PixelFormat::createFormatCLUT8(); char buffer[128]; // TROMAN, size 10-5 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8"); if (_vm->_boot._registered) @@ -258,12 +258,12 @@ void intro_v2d::introInit() { else sprintf(buffer, "%s Shareware Version", _vm->getCopyrightString()); - font.drawString(&surf, buffer, 0, 186, 320, _TLIGHTRED, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 186, 320, _TLIGHTRED, Graphics::kTextAlignCenter); if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) { // TROMAN, size 10-5 sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib); - font.drawString(&surf, buffer, 0, 1, 320, _TLIGHTRED, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 1, 320, _TLIGHTRED, Graphics::kTextAlignCenter); } _vm->_screen->displayBackground(); @@ -287,11 +287,11 @@ void intro_v3d::preNewGame() { void intro_v3d::introInit() { _vm->_screen->displayList(kDisplayInit); _vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen - surf.w = 320; - surf.h = 200; - surf.pixels = _vm->_screen->getFrontBuffer(); - surf.pitch = 320; - surf.format = Graphics::PixelFormat::createFormatCLUT8(); + _surf.w = 320; + _surf.h = 200; + _surf.pixels = _vm->_screen->getFrontBuffer(); + _surf.pitch = 320; + _surf.format = Graphics::PixelFormat::createFormatCLUT8(); char buffer[128]; if (_vm->_boot._registered) @@ -300,14 +300,14 @@ void intro_v3d::introInit() { sprintf(buffer,"%s Shareware Version", _vm->getCopyrightString()); // TROMAN, size 10-5 - if (!font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) + if (!_font.loadFromFON("TMSRB.FON", Graphics::WinFontDirEntry("Tms Rmn", 8))) error("Unable to load font TMSRB.FON, face 'Tms Rmn', size 8"); - font.drawString(&surf, buffer, 0, 190, 320, _TBROWN, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 190, 320, _TBROWN, Graphics::kTextAlignCenter); if ((*_vm->_boot._distrib != '\0') && (scumm_stricmp(_vm->_boot._distrib, "David P. Gray"))) { sprintf(buffer, "Distributed by %s.", _vm->_boot._distrib); - font.drawString(&surf, buffer, 0, 0, 320, _TBROWN, Graphics::kTextAlignCenter); + _font.drawString(&_surf, buffer, 0, 0, 320, _TBROWN, Graphics::kTextAlignCenter); } _vm->_screen->displayBackground(); @@ -316,7 +316,7 @@ void intro_v3d::introInit() { _vm->_file->readBackground(22); // display screen MAP_3d _vm->_screen->displayBackground(); - introTicks = 0; + _introTicks = 0; _vm->_sound->_DOSSongPtr = _vm->_sound->_DOSIntroSong; } @@ -328,12 +328,12 @@ bool intro_v3d::introPlay() { if (_vm->getGameStatus()._skipIntroFl) return true; - if (introTicks < getIntroSize()) { - font.drawString(&surf, ".", _introX[introTicks], _introY[introTicks] - kDibOffY, 320, _TBRIGHTWHITE); + if (_introTicks < getIntroSize()) { + _font.drawString(&_surf, ".", _introX[_introTicks], _introY[_introTicks] - kDibOffY, 320, _TBRIGHTWHITE); _vm->_screen->displayBackground(); // Text boxes at various times - switch (introTicks) { + switch (_introTicks) { case 4: Utils::notifyBox(_vm->_text->getTextIntro(kIntro1)); break; @@ -346,7 +346,7 @@ bool intro_v3d::introPlay() { } } - return (++introTicks >= getIntroSize()); + return (++_introTicks >= getIntroSize()); } intro_v1w::intro_v1w(HugoEngine *vm) : IntroHandler(vm) { @@ -407,7 +407,7 @@ void intro_v3w::introInit() { g_system->delayMillis(3000); _vm->_file->readBackground(22); // display screen MAP_3w _vm->_screen->displayBackground(); - introTicks = 0; + _introTicks = 0; _vm->_screen->loadFont(0); } @@ -419,13 +419,13 @@ bool intro_v3w::introPlay() { if (_vm->getGameStatus()._skipIntroFl) return true; - if (introTicks < getIntroSize()) { + if (_introTicks < getIntroSize()) { // Scale viewport x_intro,y_intro to screen (offsetting y) - _vm->_screen->writeStr(_introX[introTicks], _introY[introTicks] - kDibOffY, "x", _TBRIGHTWHITE); + _vm->_screen->writeStr(_introX[_introTicks], _introY[_introTicks] - kDibOffY, "x", _TBRIGHTWHITE); _vm->_screen->displayBackground(); // Text boxes at various times - switch (introTicks) { + switch (_introTicks) { case 4: Utils::notifyBox(_vm->_text->getTextIntro(kIntro1)); break; @@ -438,6 +438,6 @@ bool intro_v3w::introPlay() { } } - return (++introTicks >= getIntroSize()); + return (++_introTicks >= getIntroSize()); } } // End of namespace Hugo diff --git a/engines/hugo/intro.h b/engines/hugo/intro.h index 1bb039216a..d5a5a4e4b4 100644 --- a/engines/hugo/intro.h +++ b/engines/hugo/intro.h @@ -42,8 +42,8 @@ enum seqTextIntro { class IntroHandler { public: IntroHandler(HugoEngine *vm); - Graphics::Surface surf; - Graphics::WinFont font; + Graphics::Surface _surf; + Graphics::WinFont _font; virtual ~IntroHandler(); @@ -62,7 +62,7 @@ protected: byte *_introX; byte *_introY; byte _introXSize; - int16 introTicks; // Count calls to introPlay() + int16 _introTicks; // Count calls to introPlay() }; class intro_v1w : public IntroHandler { diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index 552ddaf5c9..7f63ccac3b 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -286,9 +286,9 @@ void Route::segment(int16 x, int16 y) { } else { // Create segment seg_p = &_segment[_segmentNumb]; - seg_p->y = y; - seg_p->x1 = x1; - seg_p->x2 = x2; + seg_p->_y = y; + seg_p->_x1 = x1; + seg_p->_x2 = x2; _segmentNumb++; } } @@ -368,9 +368,9 @@ bool Route::findRoute(const int16 cx, const int16 cy) { _route[0].y = _destY; // Make a final segment for hero's base (we left a spare) - _segment[_segmentNumb].y = heroy; - _segment[_segmentNumb].x1 = herox1; - _segment[_segmentNumb].x2 = herox2; + _segment[_segmentNumb]._y = heroy; + _segment[_segmentNumb]._x1 = herox1; + _segment[_segmentNumb]._x2 = herox2; _segmentNumb++; Point *routeNode; // Ptr to route node @@ -378,22 +378,22 @@ bool Route::findRoute(const int16 cx, const int16 cy) { for (i = 0, _routeListIndex = 0; i < _segmentNumb - 1; i++) { if ((routeNode = newNode()) == 0) // New node for new segment return false; // Too many nodes - routeNode->y = _segment[i].y; + routeNode->y = _segment[i]._y; // Look ahead for furthest straight line for (int16 j = i + 1; j < _segmentNumb; j++) { segment_t *seg_p = &_segment[j]; // Can we get to this segment from previous node? - if (seg_p->x1 <= routeNode->x && seg_p->x2 >= routeNode->x + _heroWidth - 1) { - routeNode->y = seg_p->y; // Yes, keep updating node + if (seg_p->_x1 <= routeNode->x && seg_p->_x2 >= routeNode->x + _heroWidth - 1) { + routeNode->y = seg_p->_y; // Yes, keep updating node } else { // No, create another node on previous segment to reach it if ((routeNode = newNode()) == 0) // Add new route node return false; // Too many nodes // Find overlap between old and new segments - int16 x1 = MAX(_segment[j - 1].x1, seg_p->x1); - int16 x2 = MIN(_segment[j - 1].x2, seg_p->x2); + int16 x1 = MAX(_segment[j - 1]._x1, seg_p->_x1); + int16 x2 = MIN(_segment[j - 1]._x2, seg_p->_x2); // If room, add a little offset to reduce staircase effect int16 dx = kHeroMaxWidth >> 1; diff --git a/engines/hugo/route.h b/engines/hugo/route.h index a95dd2151b..b20ac771d7 100644 --- a/engines/hugo/route.h +++ b/engines/hugo/route.h @@ -43,8 +43,8 @@ struct Point { }; struct segment_t { // Search segment - int16 y; // y position - int16 x1, x2; // Range of segment + int16 _y; // y position + int16 _x1, _x2; // Range of segment }; class Route { -- cgit v1.2.3 From 0c7fcff8a3fa10fc9bedcf0ac299809f9a140632 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 16:28:47 +0200 Subject: HUGO: Use Common::Point in pathfinding --- engines/hugo/route.cpp | 6 +++--- engines/hugo/route.h | 11 ++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index 7f63ccac3b..873cb587af 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -298,7 +298,7 @@ void Route::segment(int16 x, int16 y) { * Create and return ptr to new node. Initialize with previous node. * Returns 0 if MAX_NODES exceeded */ -Point *Route::newNode() { +Common::Point *Route::newNode() { debugC(1, kDebugRoute, "newNode"); _routeListIndex++; @@ -373,7 +373,7 @@ bool Route::findRoute(const int16 cx, const int16 cy) { _segment[_segmentNumb]._x2 = herox2; _segmentNumb++; - Point *routeNode; // Ptr to route node + Common::Point *routeNode; // Ptr to route node // Look in segments[] for straight lines from destination to hero for (i = 0, _routeListIndex = 0; i < _segmentNumb - 1; i++) { if ((routeNode = newNode()) == 0) // New node for new segment @@ -435,7 +435,7 @@ void Route::processRoute() { // Current hero position int16 herox = _vm->_hero->_x + _vm->_hero->_currImagePtr->_x1; int16 heroy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2; - Point *routeNode = &_route[_routeIndex]; + Common::Point *routeNode = &_route[_routeIndex]; // Arrived at node? if (abs(herox - routeNode->x) < kStepDx + 1 && abs(heroy - routeNode->y) < kStepDy) { diff --git a/engines/hugo/route.h b/engines/hugo/route.h index b20ac771d7..53b0dd0f88 100644 --- a/engines/hugo/route.h +++ b/engines/hugo/route.h @@ -30,6 +30,8 @@ #ifndef HUGO_ROUTE_H #define HUGO_ROUTE_H +#include "common/rect.h" + namespace Hugo { /** @@ -37,11 +39,6 @@ namespace Hugo { */ enum go_t {kRouteSpace, kRouteExit, kRouteLook, kRouteGet}; -struct Point { - int x; - int y; -}; - struct segment_t { // Search segment int16 _y; // y position int16 _x1, _x2; // Range of segment @@ -75,7 +72,7 @@ private: byte _boundaryMap[kYPix][kXPix]; // Boundary byte map segment_t _segment[kMaxSeg]; // List of points in fill-path - Point _route[kMaxNodes]; // List of nodes in route (global) + Common::Point _route[kMaxNodes]; // List of nodes in route (global) int16 _segmentNumb; // Count number of segments int16 _routeListIndex; // Index into route list int16 _destX; @@ -87,7 +84,7 @@ private: void segment(int16 x, int16 y); bool findRoute(const int16 cx, const int16 cy); - Point *newNode(); + Common::Point *newNode(); }; } // End of namespace Hugo -- cgit v1.2.3 From fbc2c6d08ac96c92e2424118dc9b0548628287e5 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 17:44:09 +0200 Subject: HUGO: More renaming --- engines/hugo/dialogs.cpp | 8 +- engines/hugo/file.cpp | 24 +- engines/hugo/file.h | 6 +- engines/hugo/hugo.cpp | 12 +- engines/hugo/hugo.h | 32 +- engines/hugo/mouse.cpp | 46 +- engines/hugo/parser.cpp | 4 +- engines/hugo/schedule.cpp | 1032 ++++++++++++++++++++++----------------------- engines/hugo/schedule.h | 519 +++++++++++------------ engines/hugo/sound.cpp | 12 +- 10 files changed, 840 insertions(+), 855 deletions(-) diff --git a/engines/hugo/dialogs.cpp b/engines/hugo/dialogs.cpp index 0efd47a3bd..0f07d52aee 100644 --- a/engines/hugo/dialogs.cpp +++ b/engines/hugo/dialogs.cpp @@ -109,12 +109,12 @@ void TopMenu::reflowLayout() { // Set the graphics to the 'on' buttons, except for the variable ones _whatButton->setGfx(_arrayBmp[4 * kMenuWhat + scale - 1]); - _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + scale - 1 + ((_vm->_config.musicFl) ? 0 : 2)]); - _soundFXButton->setGfx(_arrayBmp[4 * kMenuSoundFX + scale - 1 + ((_vm->_config.soundFl) ? 0 : 2)]); + _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + scale - 1 + ((_vm->_config._musicFl) ? 0 : 2)]); + _soundFXButton->setGfx(_arrayBmp[4 * kMenuSoundFX + scale - 1 + ((_vm->_config._soundFl) ? 0 : 2)]); _saveButton->setGfx(_arrayBmp[4 * kMenuSave + scale - 1]); _loadButton->setGfx(_arrayBmp[4 * kMenuLoad + scale - 1]); _recallButton->setGfx(_arrayBmp[4 * kMenuRecall + scale - 1]); - _turboButton->setGfx(_arrayBmp[4 * kMenuTurbo + scale - 1 + ((_vm->_config.turboFl) ? 0 : 2)]); + _turboButton->setGfx(_arrayBmp[4 * kMenuTurbo + scale - 1 + ((_vm->_config._turboFl) ? 0 : 2)]); _lookButton->setGfx(_arrayBmp[4 * kMenuLook + scale - 1]); _inventButton->setGfx(_arrayBmp[4 * kMenuInventory + scale - 1]); } @@ -176,7 +176,7 @@ void TopMenu::handleCommand(GUI::CommandSender *sender, uint32 command, uint32 d break; case kCmdMusic: _vm->_sound->toggleMusic(); - _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + (g_system->getOverlayWidth() > 320 ? 2 : 1) - 1 + ((_vm->_config.musicFl) ? 0 : 2)]); + _musicButton->setGfx(_arrayBmp[4 * kMenuMusic + (g_system->getOverlayWidth() > 320 ? 2 : 1) - 1 + ((_vm->_config._musicFl) ? 0 : 2)]); _musicButton->draw(); g_gui.theme()->updateScreen(); g_system->updateScreen(); diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index a3fc5dfe49..219e29a25a 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -54,7 +54,7 @@ static const int s_bootCypherLen = sizeof(s_bootCypher) - 1; FileManager::FileManager(HugoEngine *vm) : _vm(vm) { _hasReadHeader = false; - firstUIFFl = true; + _firstUIFFl = true; } FileManager::~FileManager() { @@ -624,28 +624,28 @@ void FileManager::readBootFile() { * This file contains, between others, the bitmaps of the fonts used in the application * UIF means User interface database (Windows Only) */ -uif_hdr_t *FileManager::getUIFHeader(const uif_t id) { - debugC(1, kDebugFile, "getUIFHeader(%d)", id); +uif_hdr_t *FileManager::get_UIFHeader(const uif_t id) { + debugC(1, kDebugFile, "get_UIFHeader(%d)", id); // Initialize offset lookup if not read yet - if (firstUIFFl) { - firstUIFFl = false; + if (_firstUIFFl) { + _firstUIFFl = false; // Open unbuffered to do far read Common::File ip; // Image data file if (!ip.open(getUifFilename())) error("File not found: %s", getUifFilename()); - if (ip.size() < (int32)sizeof(UIFHeader)) + if (ip.size() < (int32)sizeof(_UIFHeader)) error("Wrong UIF file format"); for (int i = 0; i < kMaxUifs; ++i) { - UIFHeader[i]._size = ip.readUint16LE(); - UIFHeader[i]._offset = ip.readUint32LE(); + _UIFHeader[i]._size = ip.readUint16LE(); + _UIFHeader[i]._offset = ip.readUint32LE(); } ip.close(); } - return &UIFHeader[id]; + return &_UIFHeader[id]; } /** @@ -660,8 +660,8 @@ void FileManager::readUIFItem(const int16 id, byte *buf) { error("File not found: %s", getUifFilename()); // Seek to data - uif_hdr_t *UIFHeaderPtr = getUIFHeader((uif_t)id); - ip.seek(UIFHeaderPtr->_offset, SEEK_SET); + uif_hdr_t *_UIFHeaderPtr = get_UIFHeader((uif_t)id); + ip.seek(_UIFHeaderPtr->_offset, SEEK_SET); // We support pcx images and straight data seq_t *dummySeq; // Dummy seq_t for image data @@ -671,7 +671,7 @@ void FileManager::readUIFItem(const int16 id, byte *buf) { free(dummySeq); break; default: // Read file data into supplied array - if (ip.read(buf, UIFHeaderPtr->_size) != UIFHeaderPtr->_size) + if (ip.read(buf, _UIFHeaderPtr->_size) != _UIFHeaderPtr->_size) error("Wrong UIF file format"); break; } diff --git a/engines/hugo/file.h b/engines/hugo/file.h index 817bf49daf..e7c467a315 100644 --- a/engines/hugo/file.h +++ b/engines/hugo/file.h @@ -105,8 +105,8 @@ protected: byte _fill2[60]; }; // Header of a PCC file - bool firstUIFFl; - uif_hdr_t UIFHeader[kMaxUifs]; // Lookup for uif fonts/images + bool _firstUIFFl; + uif_hdr_t _UIFHeader[kMaxUifs]; // Lookup for uif fonts/images Common::File _stringArchive; // Handle for string file Common::File _sceneryArchive1; // Handle for scenery file @@ -122,7 +122,7 @@ protected: private: byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, image_pt dataPtr) const; - uif_hdr_t *getUIFHeader(const uif_t id); + uif_hdr_t *get_UIFHeader(const uif_t id); //Strangerke : Not used? void printBootText(); diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index 450f4ff837..7462da0df8 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -562,10 +562,10 @@ void HugoEngine::initStatus() { void HugoEngine::initConfig() { debugC(1, kDebugEngine, "initConfig()"); - _config.musicFl = true; // Music state initially on - _config.soundFl = true; // Sound state initially on - _config.turboFl = false; // Turbo state initially off - initPlaylist(_config.playlist); // Initialize default tune playlist + _config._musicFl = true; // Music state initially on + _config._soundFl = true; // Sound state initially on + _config._turboFl = false; // Turbo state initially off + initPlaylist(_config._playlist); // Initialize default tune playlist _file->readBootFile(); // Read startup structure } @@ -577,7 +577,7 @@ void HugoEngine::resetConfig() { // Find first tune and play it for (int16 i = 0; i < kMaxTunes; i++) { - if (_config.playlist[i]) { + if (_config._playlist[i]) { _sound->playMusic(i); break; } @@ -694,7 +694,7 @@ bool HugoEngine::canSaveGameStateCurrently() { } int8 HugoEngine::getTPS() const { - return ((_config.turboFl) ? kTurboTps : _normalTPS); + return ((_config._turboFl) ? kTurboTps : _normalTPS); } void HugoEngine::syncSoundSettings() { diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 3ad6fced24..68b771faa4 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -83,10 +83,10 @@ static const int kHeroMinWidth = 16; // Minimum width of hero typedef char command_t[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor) struct config_t { // User's config (saved) - bool musicFl; // State of Music button/menu item - bool soundFl; // State of Sound button/menu item - bool turboFl; // State of Turbo button/menu item - bool playlist[kMaxTunes]; // Tune playlist + bool _musicFl; // State of Music button/menu item + bool _soundFl; // State of Sound button/menu item + bool _turboFl; // State of Turbo button/menu item + bool _playlist[kMaxTunes]; // Tune playlist }; typedef byte icondib_t[kXPix * kInvDy]; // Icon bar dib @@ -185,32 +185,16 @@ struct status_t { // Game status (not saved) uint32 _tick; // Current time in ticks vstate_t _viewState; // View state machine int16 _song; // Current song - -// Strangerke - Suppress as related to playback -// bool playbackFl; // Game is in playback mode -// bool recordFl; // Game is in record mode -// Strangerke - Not used ? -// bool helpFl; // Calling WinHelp (don't disable music) -// bool mmtimeFl; // Multimedia timer supported -// bool demoFl; // Game is in demo mode -// bool textBoxFl; // Game is (halted) in text box -// int16 screenWidth; // Desktop screen width -// int16 saveSlot; // Current slot to save/restore game -// int16 cx, cy; // Cursor position (dib coords) -// uint32 saveTick; // Time of last save in ticks -// -// typedef char fpath_t[kMaxPath]; // File path -// fpath_t path; // Alternate path for saved files }; /** * Structure to define an EXIT or other collision-activated hotspot */ struct hotspot_t { - int screenIndex; // Screen in which hotspot appears - int x1, y1, x2, y2; // Bounding box of hotspot - uint16 actIndex; // Actions to carry out if a 'hit' - int16 viewx, viewy, direction; // Used in auto-route mode + int _screenIndex; // Screen in which hotspot appears + int _x1, _y1, _x2, _y2; // Bounding box of hotspot + uint16 _actIndex; // Actions to carry out if a 'hit' + int16 _viewx, _viewy, _direction; // Used in auto-route mode }; class FileManager; diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index 323f362b10..864934a0d3 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -98,11 +98,11 @@ int MouseHandler::getMouseY() const { } int16 MouseHandler::getDirection(const int16 hotspotId) const { - return _hotspots[hotspotId].direction; + return _hotspots[hotspotId]._direction; } int16 MouseHandler::getHotspotActIndex(const int16 hotspotId) const { - return _hotspots[hotspotId].actIndex; + return _hotspots[hotspotId]._actIndex; } /** @@ -137,9 +137,9 @@ void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy int16 MouseHandler::findExit(const int16 cx, const int16 cy, byte screenId) { debugC(2, kDebugMouse, "findExit(%d, %d, %d)", cx, cy, screenId); - for (int i = 0; _hotspots[i].screenIndex >= 0; i++) { - if (_hotspots[i].screenIndex == screenId) { - if (cx >= _hotspots[i].x1 && cx <= _hotspots[i].x2 && cy >= _hotspots[i].y1 && cy <= _hotspots[i].y2) + for (int i = 0; _hotspots[i]._screenIndex >= 0; i++) { + if (_hotspots[i]._screenIndex == screenId) { + if (cx >= _hotspots[i]._x1 && cx <= _hotspots[i]._x2 && cy >= _hotspots[i]._y1 && cy <= _hotspots[i]._y2) return i; } } @@ -224,19 +224,19 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int break; case kExitHotspot: // Walk to exit hotspot i = findExit(cx, cy, *_vm->_screen_p); - x = _hotspots[i].viewx; - y = _hotspots[i].viewy; + x = _hotspots[i]._viewx; + y = _hotspots[i]._viewy; if (x >= 0) { // Hotspot refers to an exit // Special case of immediate exit if (_jumpExitFl) { // Get rid of iconbar if necessary if (_vm->_inventory->getInventoryState() != kInventoryOff) _vm->_inventory->setInventoryState(kInventoryUp); - _vm->_scheduler->insertActionList(_hotspots[i].actIndex); + _vm->_scheduler->insertActionList(_hotspots[i]._actIndex); } else { // Set up route to exit spot - if (_hotspots[i].direction == Common::KEYCODE_RIGHT) + if (_hotspots[i]._direction == Common::KEYCODE_RIGHT) x -= kHeroMaxWidth; - else if (_hotspots[i].direction == Common::KEYCODE_LEFT) + else if (_hotspots[i]._direction == Common::KEYCODE_LEFT) x += kHeroMaxWidth; if (!_vm->_route->startRoute(kRouteExit, i, x, y)) Utils::notifyBox(_vm->_text->getTextMouse(kMsNoWayText)); // Can't get there @@ -328,7 +328,7 @@ void MouseHandler::mouseHandler() { // Process cursor over an exit hotspot if (objId == -1) { int i = findExit(cx, cy, *_vm->_screen_p); - if (i != -1 && _hotspots[i].viewx >= 0) { + if (i != -1 && _hotspots[i]._viewx >= 0) { objId = kExitHotspot; cursorText(_vm->_text->getTextMouse(kMsExit), cx, cy, U_FONT8, _TBRIGHTWHITE); } @@ -344,15 +344,15 @@ void MouseHandler::mouseHandler() { } void MouseHandler::readHotspot(Common::ReadStream &in, hotspot_t &hotspot) { - hotspot.screenIndex = in.readSint16BE(); - hotspot.x1 = in.readSint16BE(); - hotspot.y1 = in.readSint16BE(); - hotspot.x2 = in.readSint16BE(); - hotspot.y2 = in.readSint16BE(); - hotspot.actIndex = in.readUint16BE(); - hotspot.viewx = in.readSint16BE(); - hotspot.viewy = in.readSint16BE(); - hotspot.direction = in.readSint16BE(); + hotspot._screenIndex = in.readSint16BE(); + hotspot._x1 = in.readSint16BE(); + hotspot._y1 = in.readSint16BE(); + hotspot._x2 = in.readSint16BE(); + hotspot._y2 = in.readSint16BE(); + hotspot._actIndex = in.readUint16BE(); + hotspot._viewx = in.readSint16BE(); + hotspot._viewy = in.readSint16BE(); + hotspot._direction = in.readSint16BE(); } /** @@ -376,10 +376,10 @@ void MouseHandler::loadHotspots(Common::ReadStream &in) { * Display hotspot boundaries for the current screen */ void MouseHandler::drawHotspots() const { - for (int i = 0; _hotspots[i].screenIndex >= 0; i++) { + for (int i = 0; _hotspots[i]._screenIndex >= 0; i++) { hotspot_t *hotspot = &_hotspots[i]; - if (hotspot->screenIndex == _vm->_hero->_screenIndex) - _vm->_screen->drawRectangle(false, hotspot->x1, hotspot->y1, hotspot->x2, hotspot->y2, _TLIGHTRED); + if (hotspot->_screenIndex == _vm->_hero->_screenIndex) + _vm->_screen->drawRectangle(false, hotspot->_x1, hotspot->_y1, hotspot->_x2, hotspot->_y2, _TLIGHTRED); } } } // End of namespace Hugo diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp index b4255e607b..3b0eb1d979 100644 --- a/engines/hugo/parser.cpp +++ b/engines/hugo/parser.cpp @@ -198,7 +198,7 @@ void Parser::freeParser() { } void Parser::switchTurbo() { - _vm->_config.turboFl = !_vm->_config.turboFl; + _vm->_config._turboFl = !_vm->_config._turboFl; } /** @@ -256,7 +256,7 @@ void Parser::charHandler() { } sprintf(_vm->_statusLine, ">%s%c", _cmdLine, _cmdLineCursor); - sprintf(_vm->_scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_vm->_config.turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config.soundFl) ? "On" : "Off"); + sprintf(_vm->_scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_vm->_config._turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_vm->_config._soundFl) ? "On" : "Off"); // See if "look" button pressed if (gameStatus._lookFl) { diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 18e414420a..0e57b08f19 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -68,13 +68,13 @@ void Scheduler::initEventQueue() { // Chain next_p from first to last for (int i = kMaxEvents; --i;) - _events[i - 1].nextEvent = &_events[i]; - _events[kMaxEvents - 1].nextEvent = 0; + _events[i - 1]._nextEvent = &_events[i]; + _events[kMaxEvents - 1]._nextEvent = 0; // Chain prev_p from last to first for (int i = 1; i < kMaxEvents; i++) - _events[i].prevEvent = &_events[i - 1]; - _events[0].prevEvent = 0; + _events[i]._prevEvent = &_events[i - 1]; + _events[0]._prevEvent = 0; _headEvent = _tailEvent = 0; // Event list is empty _freeEvent = _events; // Free list is full @@ -89,8 +89,8 @@ event_t *Scheduler::getQueue() { if (!_freeEvent) // Error: no more events available error("An error has occurred: %s", "getQueue"); event_t *resEvent = _freeEvent; - _freeEvent = _freeEvent->nextEvent; - resEvent->nextEvent = 0; + _freeEvent = _freeEvent->_nextEvent; + resEvent->_nextEvent = 0; return resEvent; } @@ -101,7 +101,7 @@ void Scheduler::insertActionList(const uint16 actIndex) { debugC(1, kDebugSchedule, "insertActionList(%d)", actIndex); if (_actListArr[actIndex]) { - for (int i = 0; _actListArr[actIndex][i].a0.actType != ANULL; i++) + for (int i = 0; _actListArr[actIndex][i]._a0._actType != ANULL; i++) insertAction(&_actListArr[actIndex][i]); } } @@ -147,9 +147,9 @@ uint32 Scheduler::getDosTicks(const bool updateFl) { void Scheduler::processBonus(const int bonusIndex) { debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex); - if (!_points[bonusIndex].scoredFl) { - _vm->adjustScore(_points[bonusIndex].score); - _points[bonusIndex].scoredFl = true; + if (!_points[bonusIndex]._scoredFl) { + _vm->adjustScore(_points[bonusIndex]._score); + _points[bonusIndex]._scoredFl = true; } } @@ -178,8 +178,8 @@ void Scheduler::newScreen(const int screenIndex) { event_t *curEvent = _headEvent; // The earliest event event_t *wrkEvent; // Event ptr while (curEvent) { // While mature events found - wrkEvent = curEvent->nextEvent; // Save p (becomes undefined after Del) - if (curEvent->localActionFl) + wrkEvent = curEvent->_nextEvent; // Save p (becomes undefined after Del) + if (curEvent->_localActionFl) delQueue(curEvent); // Return event to free list curEvent = wrkEvent; } @@ -261,8 +261,8 @@ void Scheduler::loadPoints(Common::SeekableReadStream &in) { _numBonuses = numElem; _points = (point_t *)malloc(sizeof(point_t) * _numBonuses); for (int i = 0; i < _numBonuses; i++) { - _points[i].score = in.readByte(); - _points[i].scoredFl = false; + _points[i]._score = in.readByte(); + _points[i]._scoredFl = false; } } else { in.skip(numElem); @@ -273,277 +273,277 @@ void Scheduler::loadPoints(Common::SeekableReadStream &in) { void Scheduler::readAct(Common::ReadStream &in, act &curAct) { uint16 numSubAct; - curAct.a0.actType = (action_t) in.readByte(); - switch (curAct.a0.actType) { + curAct._a0._actType = (action_t) in.readByte(); + switch (curAct._a0._actType) { case ANULL: // -1 break; case ASCHEDULE: // 0 - curAct.a0.timer = in.readSint16BE(); - curAct.a0.actIndex = in.readUint16BE(); + curAct._a0._timer = in.readSint16BE(); + curAct._a0._actIndex = in.readUint16BE(); break; case START_OBJ: // 1 - curAct.a1.timer = in.readSint16BE(); - curAct.a1.objIndex = in.readSint16BE(); - curAct.a1.cycleNumb = in.readSint16BE(); - curAct.a1.cycle = (cycle_t) in.readByte(); + curAct._a1._timer = in.readSint16BE(); + curAct._a1._objIndex = in.readSint16BE(); + curAct._a1._cycleNumb = in.readSint16BE(); + curAct._a1._cycle = (cycle_t) in.readByte(); break; case INIT_OBJXY: // 2 - curAct.a2.timer = in.readSint16BE(); - curAct.a2.objIndex = in.readSint16BE(); - curAct.a2.x = in.readSint16BE(); - curAct.a2.y = in.readSint16BE(); + curAct._a2._timer = in.readSint16BE(); + curAct._a2._objIndex = in.readSint16BE(); + curAct._a2._x = in.readSint16BE(); + curAct._a2._y = in.readSint16BE(); break; case PROMPT: // 3 - curAct.a3.timer = in.readSint16BE(); - curAct.a3.promptIndex = in.readSint16BE(); + curAct._a3._timer = in.readSint16BE(); + curAct._a3._promptIndex = in.readSint16BE(); numSubAct = in.readUint16BE(); - curAct.a3.responsePtr = (int *)malloc(sizeof(int) * numSubAct); + curAct._a3._responsePtr = (int *)malloc(sizeof(int) * numSubAct); for (int k = 0; k < numSubAct; k++) - curAct.a3.responsePtr[k] = in.readSint16BE(); - curAct.a3.actPassIndex = in.readUint16BE(); - curAct.a3.actFailIndex = in.readUint16BE(); - curAct.a3.encodedFl = (in.readByte() == 1) ? true : false; + curAct._a3._responsePtr[k] = in.readSint16BE(); + curAct._a3._actPassIndex = in.readUint16BE(); + curAct._a3._actFailIndex = in.readUint16BE(); + curAct._a3._encodedFl = (in.readByte() == 1) ? true : false; break; case BKGD_COLOR: // 4 - curAct.a4.timer = in.readSint16BE(); - curAct.a4.newBackgroundColor = in.readUint32BE(); + curAct._a4._timer = in.readSint16BE(); + curAct._a4._newBackgroundColor = in.readUint32BE(); break; case INIT_OBJVXY: // 5 - curAct.a5.timer = in.readSint16BE(); - curAct.a5.objIndex = in.readSint16BE(); - curAct.a5.vx = in.readSint16BE(); - curAct.a5.vy = in.readSint16BE(); + curAct._a5._timer = in.readSint16BE(); + curAct._a5._objIndex = in.readSint16BE(); + curAct._a5._vx = in.readSint16BE(); + curAct._a5._vy = in.readSint16BE(); break; case INIT_CARRY: // 6 - curAct.a6.timer = in.readSint16BE(); - curAct.a6.objIndex = in.readSint16BE(); - curAct.a6.carriedFl = (in.readByte() == 1) ? true : false; + curAct._a6._timer = in.readSint16BE(); + curAct._a6._objIndex = in.readSint16BE(); + curAct._a6._carriedFl = (in.readByte() == 1) ? true : false; break; case INIT_HF_COORD: // 7 - curAct.a7.timer = in.readSint16BE(); - curAct.a7.objIndex = in.readSint16BE(); + curAct._a7._timer = in.readSint16BE(); + curAct._a7._objIndex = in.readSint16BE(); break; case NEW_SCREEN: // 8 - curAct.a8.timer = in.readSint16BE(); - curAct.a8.screenIndex = in.readSint16BE(); + curAct._a8._timer = in.readSint16BE(); + curAct._a8._screenIndex = in.readSint16BE(); break; case INIT_OBJSTATE: // 9 - curAct.a9.timer = in.readSint16BE(); - curAct.a9.objIndex = in.readSint16BE(); - curAct.a9.newState = in.readByte(); + curAct._a9._timer = in.readSint16BE(); + curAct._a9._objIndex = in.readSint16BE(); + curAct._a9._newState = in.readByte(); break; case INIT_PATH: // 10 - curAct.a10.timer = in.readSint16BE(); - curAct.a10.objIndex = in.readSint16BE(); - curAct.a10.newPathType = in.readSint16BE(); - curAct.a10.vxPath = in.readByte(); - curAct.a10.vyPath = in.readByte(); + curAct._a10._timer = in.readSint16BE(); + curAct._a10._objIndex = in.readSint16BE(); + curAct._a10._newPathType = in.readSint16BE(); + curAct._a10._vxPath = in.readByte(); + curAct._a10._vyPath = in.readByte(); break; case COND_R: // 11 - curAct.a11.timer = in.readSint16BE(); - curAct.a11.objIndex = in.readSint16BE(); - curAct.a11.stateReq = in.readByte(); - curAct.a11.actPassIndex = in.readUint16BE(); - curAct.a11.actFailIndex = in.readUint16BE(); + curAct._a11._timer = in.readSint16BE(); + curAct._a11._objIndex = in.readSint16BE(); + curAct._a11._stateReq = in.readByte(); + curAct._a11._actPassIndex = in.readUint16BE(); + curAct._a11._actFailIndex = in.readUint16BE(); break; case TEXT: // 12 - curAct.a12.timer = in.readSint16BE(); - curAct.a12.stringIndex = in.readSint16BE(); + curAct._a12._timer = in.readSint16BE(); + curAct._a12._stringIndex = in.readSint16BE(); break; case SWAP_IMAGES: // 13 - curAct.a13.timer = in.readSint16BE(); - curAct.a13.objIndex1 = in.readSint16BE(); - curAct.a13.objIndex2 = in.readSint16BE(); + curAct._a13._timer = in.readSint16BE(); + curAct._a13._objIndex1 = in.readSint16BE(); + curAct._a13._objIndex2 = in.readSint16BE(); break; case COND_SCR: // 14 - curAct.a14.timer = in.readSint16BE(); - curAct.a14.objIndex = in.readSint16BE(); - curAct.a14.screenReq = in.readSint16BE(); - curAct.a14.actPassIndex = in.readUint16BE(); - curAct.a14.actFailIndex = in.readUint16BE(); + curAct._a14._timer = in.readSint16BE(); + curAct._a14._objIndex = in.readSint16BE(); + curAct._a14._screenReq = in.readSint16BE(); + curAct._a14._actPassIndex = in.readUint16BE(); + curAct._a14._actFailIndex = in.readUint16BE(); break; case AUTOPILOT: // 15 - curAct.a15.timer = in.readSint16BE(); - curAct.a15.objIndex1 = in.readSint16BE(); - curAct.a15.objIndex2 = in.readSint16BE(); - curAct.a15.dx = in.readByte(); - curAct.a15.dy = in.readByte(); + curAct._a15._timer = in.readSint16BE(); + curAct._a15._objIndex1 = in.readSint16BE(); + curAct._a15._objIndex2 = in.readSint16BE(); + curAct._a15._dx = in.readByte(); + curAct._a15._dy = in.readByte(); break; case INIT_OBJ_SEQ: // 16 - curAct.a16.timer = in.readSint16BE(); - curAct.a16.objIndex = in.readSint16BE(); - curAct.a16.seqIndex = in.readSint16BE(); + curAct._a16._timer = in.readSint16BE(); + curAct._a16._objIndex = in.readSint16BE(); + curAct._a16._seqIndex = in.readSint16BE(); break; case SET_STATE_BITS: // 17 - curAct.a17.timer = in.readSint16BE(); - curAct.a17.objIndex = in.readSint16BE(); - curAct.a17.stateMask = in.readSint16BE(); + curAct._a17._timer = in.readSint16BE(); + curAct._a17._objIndex = in.readSint16BE(); + curAct._a17._stateMask = in.readSint16BE(); break; case CLEAR_STATE_BITS: // 18 - curAct.a18.timer = in.readSint16BE(); - curAct.a18.objIndex = in.readSint16BE(); - curAct.a18.stateMask = in.readSint16BE(); + curAct._a18._timer = in.readSint16BE(); + curAct._a18._objIndex = in.readSint16BE(); + curAct._a18._stateMask = in.readSint16BE(); break; case TEST_STATE_BITS: // 19 - curAct.a19.timer = in.readSint16BE(); - curAct.a19.objIndex = in.readSint16BE(); - curAct.a19.stateMask = in.readSint16BE(); - curAct.a19.actPassIndex = in.readUint16BE(); - curAct.a19.actFailIndex = in.readUint16BE(); + curAct._a19._timer = in.readSint16BE(); + curAct._a19._objIndex = in.readSint16BE(); + curAct._a19._stateMask = in.readSint16BE(); + curAct._a19._actPassIndex = in.readUint16BE(); + curAct._a19._actFailIndex = in.readUint16BE(); break; case DEL_EVENTS: // 20 - curAct.a20.timer = in.readSint16BE(); - curAct.a20.actTypeDel = (action_t) in.readByte(); + curAct._a20._timer = in.readSint16BE(); + curAct._a20._actTypeDel = (action_t) in.readByte(); break; case GAMEOVER: // 21 - curAct.a21.timer = in.readSint16BE(); + curAct._a21._timer = in.readSint16BE(); break; case INIT_HH_COORD: // 22 - curAct.a22.timer = in.readSint16BE(); - curAct.a22.objIndex = in.readSint16BE(); + curAct._a22._timer = in.readSint16BE(); + curAct._a22._objIndex = in.readSint16BE(); break; case EXIT: // 23 - curAct.a23.timer = in.readSint16BE(); + curAct._a23._timer = in.readSint16BE(); break; case BONUS: // 24 - curAct.a24.timer = in.readSint16BE(); - curAct.a24.pointIndex = in.readSint16BE(); + curAct._a24._timer = in.readSint16BE(); + curAct._a24._pointIndex = in.readSint16BE(); break; case COND_BOX: // 25 - curAct.a25.timer = in.readSint16BE(); - curAct.a25.objIndex = in.readSint16BE(); - curAct.a25.x1 = in.readSint16BE(); - curAct.a25.y1 = in.readSint16BE(); - curAct.a25.x2 = in.readSint16BE(); - curAct.a25.y2 = in.readSint16BE(); - curAct.a25.actPassIndex = in.readUint16BE(); - curAct.a25.actFailIndex = in.readUint16BE(); + curAct._a25._timer = in.readSint16BE(); + curAct._a25._objIndex = in.readSint16BE(); + curAct._a25._x1 = in.readSint16BE(); + curAct._a25._y1 = in.readSint16BE(); + curAct._a25._x2 = in.readSint16BE(); + curAct._a25._y2 = in.readSint16BE(); + curAct._a25._actPassIndex = in.readUint16BE(); + curAct._a25._actFailIndex = in.readUint16BE(); break; case SOUND: // 26 - curAct.a26.timer = in.readSint16BE(); - curAct.a26.soundIndex = in.readSint16BE(); + curAct._a26._timer = in.readSint16BE(); + curAct._a26._soundIndex = in.readSint16BE(); break; case ADD_SCORE: // 27 - curAct.a27.timer = in.readSint16BE(); - curAct.a27.objIndex = in.readSint16BE(); + curAct._a27._timer = in.readSint16BE(); + curAct._a27._objIndex = in.readSint16BE(); break; case SUB_SCORE: // 28 - curAct.a28.timer = in.readSint16BE(); - curAct.a28.objIndex = in.readSint16BE(); + curAct._a28._timer = in.readSint16BE(); + curAct._a28._objIndex = in.readSint16BE(); break; case COND_CARRY: // 29 - curAct.a29.timer = in.readSint16BE(); - curAct.a29.objIndex = in.readSint16BE(); - curAct.a29.actPassIndex = in.readUint16BE(); - curAct.a29.actFailIndex = in.readUint16BE(); + curAct._a29._timer = in.readSint16BE(); + curAct._a29._objIndex = in.readSint16BE(); + curAct._a29._actPassIndex = in.readUint16BE(); + curAct._a29._actFailIndex = in.readUint16BE(); break; case INIT_MAZE: // 30 - curAct.a30.timer = in.readSint16BE(); - curAct.a30.mazeSize = in.readByte(); - curAct.a30.x1 = in.readSint16BE(); - curAct.a30.y1 = in.readSint16BE(); - curAct.a30.x2 = in.readSint16BE(); - curAct.a30.y2 = in.readSint16BE(); - curAct.a30.x3 = in.readSint16BE(); - curAct.a30.x4 = in.readSint16BE(); - curAct.a30.firstScreenIndex = in.readByte(); + curAct._a30._timer = in.readSint16BE(); + curAct._a30._mazeSize = in.readByte(); + curAct._a30._x1 = in.readSint16BE(); + curAct._a30._y1 = in.readSint16BE(); + curAct._a30._x2 = in.readSint16BE(); + curAct._a30._y2 = in.readSint16BE(); + curAct._a30._x3 = in.readSint16BE(); + curAct._a30._x4 = in.readSint16BE(); + curAct._a30._firstScreenIndex = in.readByte(); break; case EXIT_MAZE: // 31 - curAct.a31.timer = in.readSint16BE(); + curAct._a31._timer = in.readSint16BE(); break; case INIT_PRIORITY: // 32 - curAct.a32.timer = in.readSint16BE(); - curAct.a32.objIndex = in.readSint16BE(); - curAct.a32.priority = in.readByte(); + curAct._a32._timer = in.readSint16BE(); + curAct._a32._objIndex = in.readSint16BE(); + curAct._a32._priority = in.readByte(); break; case INIT_SCREEN: // 33 - curAct.a33.timer = in.readSint16BE(); - curAct.a33.objIndex = in.readSint16BE(); - curAct.a33.screenIndex = in.readSint16BE(); + curAct._a33._timer = in.readSint16BE(); + curAct._a33._objIndex = in.readSint16BE(); + curAct._a33._screenIndex = in.readSint16BE(); break; case AGSCHEDULE: // 34 - curAct.a34.timer = in.readSint16BE(); - curAct.a34.actIndex = in.readUint16BE(); + curAct._a34._timer = in.readSint16BE(); + curAct._a34._actIndex = in.readUint16BE(); break; case REMAPPAL: // 35 - curAct.a35.timer = in.readSint16BE(); - curAct.a35.oldColorIndex = in.readSint16BE(); - curAct.a35.newColorIndex = in.readSint16BE(); + curAct._a35._timer = in.readSint16BE(); + curAct._a35._oldColorIndex = in.readSint16BE(); + curAct._a35._newColorIndex = in.readSint16BE(); break; case COND_NOUN: // 36 - curAct.a36.timer = in.readSint16BE(); - curAct.a36.nounIndex = in.readUint16BE(); - curAct.a36.actPassIndex = in.readUint16BE(); - curAct.a36.actFailIndex = in.readUint16BE(); + curAct._a36._timer = in.readSint16BE(); + curAct._a36._nounIndex = in.readUint16BE(); + curAct._a36._actPassIndex = in.readUint16BE(); + curAct._a36._actFailIndex = in.readUint16BE(); break; case SCREEN_STATE: // 37 - curAct.a37.timer = in.readSint16BE(); - curAct.a37.screenIndex = in.readSint16BE(); - curAct.a37.newState = in.readByte(); + curAct._a37._timer = in.readSint16BE(); + curAct._a37._screenIndex = in.readSint16BE(); + curAct._a37._newState = in.readByte(); break; case INIT_LIPS: // 38 - curAct.a38.timer = in.readSint16BE(); - curAct.a38.lipsObjIndex = in.readSint16BE(); - curAct.a38.objIndex = in.readSint16BE(); - curAct.a38.dxLips = in.readByte(); - curAct.a38.dyLips = in.readByte(); + curAct._a38._timer = in.readSint16BE(); + curAct._a38._lipsObjIndex = in.readSint16BE(); + curAct._a38._objIndex = in.readSint16BE(); + curAct._a38._dxLips = in.readByte(); + curAct._a38._dyLips = in.readByte(); break; case INIT_STORY_MODE: // 39 - curAct.a39.timer = in.readSint16BE(); - curAct.a39.storyModeFl = (in.readByte() == 1); + curAct._a39._timer = in.readSint16BE(); + curAct._a39._storyModeFl = (in.readByte() == 1); break; case WARN: // 40 - curAct.a40.timer = in.readSint16BE(); - curAct.a40.stringIndex = in.readSint16BE(); + curAct._a40._timer = in.readSint16BE(); + curAct._a40._stringIndex = in.readSint16BE(); break; case COND_BONUS: // 41 - curAct.a41.timer = in.readSint16BE(); - curAct.a41.BonusIndex = in.readSint16BE(); - curAct.a41.actPassIndex = in.readUint16BE(); - curAct.a41.actFailIndex = in.readUint16BE(); + curAct._a41._timer = in.readSint16BE(); + curAct._a41._bonusIndex = in.readSint16BE(); + curAct._a41._actPassIndex = in.readUint16BE(); + curAct._a41._actFailIndex = in.readUint16BE(); break; case TEXT_TAKE: // 42 - curAct.a42.timer = in.readSint16BE(); - curAct.a42.objIndex = in.readSint16BE(); + curAct._a42._timer = in.readSint16BE(); + curAct._a42._objIndex = in.readSint16BE(); break; case YESNO: // 43 - curAct.a43.timer = in.readSint16BE(); - curAct.a43.promptIndex = in.readSint16BE(); - curAct.a43.actYesIndex = in.readUint16BE(); - curAct.a43.actNoIndex = in.readUint16BE(); + curAct._a43._timer = in.readSint16BE(); + curAct._a43._promptIndex = in.readSint16BE(); + curAct._a43._actYesIndex = in.readUint16BE(); + curAct._a43._actNoIndex = in.readUint16BE(); break; case STOP_ROUTE: // 44 - curAct.a44.timer = in.readSint16BE(); + curAct._a44._timer = in.readSint16BE(); break; case COND_ROUTE: // 45 - curAct.a45.timer = in.readSint16BE(); - curAct.a45.routeIndex = in.readSint16BE(); - curAct.a45.actPassIndex = in.readUint16BE(); - curAct.a45.actFailIndex = in.readUint16BE(); + curAct._a45._timer = in.readSint16BE(); + curAct._a45._routeIndex = in.readSint16BE(); + curAct._a45._actPassIndex = in.readUint16BE(); + curAct._a45._actFailIndex = in.readUint16BE(); break; case INIT_JUMPEXIT: // 46 - curAct.a46.timer = in.readSint16BE(); - curAct.a46.jumpExitFl = (in.readByte() == 1); + curAct._a46._timer = in.readSint16BE(); + curAct._a46._jumpExitFl = (in.readByte() == 1); break; case INIT_VIEW: // 47 - curAct.a47.timer = in.readSint16BE(); - curAct.a47.objIndex = in.readSint16BE(); - curAct.a47.viewx = in.readSint16BE(); - curAct.a47.viewy = in.readSint16BE(); - curAct.a47.direction = in.readSint16BE(); + curAct._a47._timer = in.readSint16BE(); + curAct._a47._objIndex = in.readSint16BE(); + curAct._a47._viewx = in.readSint16BE(); + curAct._a47._viewy = in.readSint16BE(); + curAct._a47._direction = in.readSint16BE(); break; case INIT_OBJ_FRAME: // 48 - curAct.a48.timer = in.readSint16BE(); - curAct.a48.objIndex = in.readSint16BE(); - curAct.a48.seqIndex = in.readSint16BE(); - curAct.a48.frameIndex = in.readSint16BE(); + curAct._a48._timer = in.readSint16BE(); + curAct._a48._objIndex = in.readSint16BE(); + curAct._a48._seqIndex = in.readSint16BE(); + curAct._a48._frameIndex = in.readSint16BE(); break; case OLD_SONG: //49 - curAct.a49.timer = in.readSint16BE(); - curAct.a49.songIndex = in.readUint16BE(); + curAct._a49._timer = in.readSint16BE(); + curAct._a49._songIndex = in.readUint16BE(); break; default: - error("Engine - Unknown action type encountered: %d", curAct.a0.actType); + error("Engine - Unknown action type encountered: %d", curAct._a0._actType); } } @@ -572,13 +572,13 @@ void Scheduler::loadActListArr(Common::ReadStream &in) { readAct(in, _actListArr[i][j]); } else { readAct(in, tmpAct); - if (tmpAct.a0.actType == PROMPT) - free(tmpAct.a3.responsePtr); + if (tmpAct._a0._actType == PROMPT) + free(tmpAct._a3._responsePtr); } } if (varnt == _vm->_gameVariant) - _actListArr[i][numSubElem].a0.actType = ANULL; + _actListArr[i][numSubElem]._a0._actType = ANULL; } } } @@ -626,9 +626,9 @@ void Scheduler::freeScheduler() { if (_actListArr) { for (int i = 0; i < _actListArrSize; i++) { - for (int j = 0; _actListArr[i][j].a0.actType != ANULL; j++) { - if (_actListArr[i][j].a0.actType == PROMPT) - free(_actListArr[i][j].a3.responsePtr); + for (int j = 0; _actListArr[i][j]._a0._actType != ANULL; j++) { + if (_actListArr[i][j]._a0._actType == PROMPT) + free(_actListArr[i][j]._a3._responsePtr); } free(_actListArr[i]); } @@ -658,30 +658,30 @@ void Scheduler::processMaze(const int x1, const int x2, const int y1, const int if (x1 < _vm->_maze._x1) { // Exit west - _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - 1; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x2 - kShiftSize - (x2 - x1); - _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->_y; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p - 1; + _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x2 - kShiftSize - (x2 - x1); + _actListArr[_alNewscrIndex][0]._a2._y = _vm->_hero->_y; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } else if (x2 > _vm->_maze._x2) { // Exit east - _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + 1; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x1 + kShiftSize; - _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->_y; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p + 1; + _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x1 + kShiftSize; + _actListArr[_alNewscrIndex][0]._a2._y = _vm->_hero->_y; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } else if (y1 < _vm->_maze._y1 - kShiftSize) { // Exit north - _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - _vm->_maze._size; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x3; - _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze._y2 - kShiftSize - (y2 - y1); + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p - _vm->_maze._size; + _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x3; + _actListArr[_alNewscrIndex][0]._a2._y = _vm->_maze._y2 - kShiftSize - (y2 - y1); _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } else if (y2 > _vm->_maze._y2 - kShiftSize / 2) { // Exit south - _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + _vm->_maze._size; - _actListArr[_alNewscrIndex][0].a2.x = _vm->_maze._x4; - _actListArr[_alNewscrIndex][0].a2.y = _vm->_maze._y1 + kShiftSize; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p + _vm->_maze._size; + _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x4; + _actListArr[_alNewscrIndex][0]._a2._y = _vm->_maze._y1 + kShiftSize; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } @@ -712,13 +712,13 @@ void Scheduler::saveEvents(Common::WriteStream *f) { // fix up action pointer (to do better) int16 index, subElem; - findAction(wrkEvent->action, &index, &subElem); + findAction(wrkEvent->_action, &index, &subElem); f->writeSint16BE(index); f->writeSint16BE(subElem); - f->writeByte((wrkEvent->localActionFl) ? 1 : 0); - f->writeUint32BE(wrkEvent->time); - f->writeSint16BE((wrkEvent->prevEvent == 0) ? -1 : (wrkEvent->prevEvent - _events)); - f->writeSint16BE((wrkEvent->nextEvent == 0) ? -1 : (wrkEvent->nextEvent - _events)); + f->writeByte((wrkEvent->_localActionFl) ? 1 : 0); + f->writeUint32BE(wrkEvent->_time); + f->writeSint16BE((wrkEvent->_prevEvent == 0) ? -1 : (wrkEvent->_prevEvent - _events)); + f->writeSint16BE((wrkEvent->_nextEvent == 0) ? -1 : (wrkEvent->_nextEvent - _events)); } } @@ -738,7 +738,7 @@ void Scheduler::restoreActions(Common::ReadStream *f) { int16 Scheduler::calcMaxPoints() const { int16 tmpScore = 0; for (int i = 0; i < _numBonuses; i++) - tmpScore += _points[i].score; + tmpScore += _points[i]._score; return tmpScore; } @@ -752,282 +752,282 @@ void Scheduler::saveActions(Common::WriteStream *f) const { for (int i = 0; i < _actListArrSize; i++) { // write all the sub elems data - for (nbrSubElem = 1; _actListArr[i][nbrSubElem - 1].a0.actType != ANULL; nbrSubElem++) + for (nbrSubElem = 1; _actListArr[i][nbrSubElem - 1]._a0._actType != ANULL; nbrSubElem++) ; f->writeUint16BE(nbrSubElem); for (int j = 0; j < nbrSubElem; j++) { - subElemType = _actListArr[i][j].a0.actType; + subElemType = _actListArr[i][j]._a0._actType; f->writeByte(subElemType); switch (subElemType) { case ANULL: // -1 break; case ASCHEDULE: // 0 - f->writeSint16BE(_actListArr[i][j].a0.timer); - f->writeUint16BE(_actListArr[i][j].a0.actIndex); + f->writeSint16BE(_actListArr[i][j]._a0._timer); + f->writeUint16BE(_actListArr[i][j]._a0._actIndex); break; case START_OBJ: // 1 - f->writeSint16BE(_actListArr[i][j].a1.timer); - f->writeSint16BE(_actListArr[i][j].a1.objIndex); - f->writeSint16BE(_actListArr[i][j].a1.cycleNumb); - f->writeByte(_actListArr[i][j].a1.cycle); + f->writeSint16BE(_actListArr[i][j]._a1._timer); + f->writeSint16BE(_actListArr[i][j]._a1._objIndex); + f->writeSint16BE(_actListArr[i][j]._a1._cycleNumb); + f->writeByte(_actListArr[i][j]._a1._cycle); break; case INIT_OBJXY: // 2 - f->writeSint16BE(_actListArr[i][j].a2.timer); - f->writeSint16BE(_actListArr[i][j].a2.objIndex); - f->writeSint16BE(_actListArr[i][j].a2.x); - f->writeSint16BE(_actListArr[i][j].a2.y); + f->writeSint16BE(_actListArr[i][j]._a2._timer); + f->writeSint16BE(_actListArr[i][j]._a2._objIndex); + f->writeSint16BE(_actListArr[i][j]._a2._x); + f->writeSint16BE(_actListArr[i][j]._a2._y); break; case PROMPT: // 3 - f->writeSint16BE(_actListArr[i][j].a3.timer); - f->writeSint16BE(_actListArr[i][j].a3.promptIndex); - for (nbrCpt = 0; _actListArr[i][j].a3.responsePtr[nbrCpt] != -1; nbrCpt++) + f->writeSint16BE(_actListArr[i][j]._a3._timer); + f->writeSint16BE(_actListArr[i][j]._a3._promptIndex); + for (nbrCpt = 0; _actListArr[i][j]._a3._responsePtr[nbrCpt] != -1; nbrCpt++) ; nbrCpt++; f->writeUint16BE(nbrCpt); for (int k = 0; k < nbrCpt; k++) - f->writeSint16BE(_actListArr[i][j].a3.responsePtr[k]); - f->writeUint16BE(_actListArr[i][j].a3.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a3.actFailIndex); - f->writeByte((_actListArr[i][j].a3.encodedFl) ? 1 : 0); + f->writeSint16BE(_actListArr[i][j]._a3._responsePtr[k]); + f->writeUint16BE(_actListArr[i][j]._a3._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a3._actFailIndex); + f->writeByte((_actListArr[i][j]._a3._encodedFl) ? 1 : 0); break; case BKGD_COLOR: // 4 - f->writeSint16BE(_actListArr[i][j].a4.timer); - f->writeUint32BE(_actListArr[i][j].a4.newBackgroundColor); + f->writeSint16BE(_actListArr[i][j]._a4._timer); + f->writeUint32BE(_actListArr[i][j]._a4._newBackgroundColor); break; case INIT_OBJVXY: // 5 - f->writeSint16BE(_actListArr[i][j].a5.timer); - f->writeSint16BE(_actListArr[i][j].a5.objIndex); - f->writeSint16BE(_actListArr[i][j].a5.vx); - f->writeSint16BE(_actListArr[i][j].a5.vy); + f->writeSint16BE(_actListArr[i][j]._a5._timer); + f->writeSint16BE(_actListArr[i][j]._a5._objIndex); + f->writeSint16BE(_actListArr[i][j]._a5._vx); + f->writeSint16BE(_actListArr[i][j]._a5._vy); break; case INIT_CARRY: // 6 - f->writeSint16BE(_actListArr[i][j].a6.timer); - f->writeSint16BE(_actListArr[i][j].a6.objIndex); - f->writeByte((_actListArr[i][j].a6.carriedFl) ? 1 : 0); + f->writeSint16BE(_actListArr[i][j]._a6._timer); + f->writeSint16BE(_actListArr[i][j]._a6._objIndex); + f->writeByte((_actListArr[i][j]._a6._carriedFl) ? 1 : 0); break; case INIT_HF_COORD: // 7 - f->writeSint16BE(_actListArr[i][j].a7.timer); - f->writeSint16BE(_actListArr[i][j].a7.objIndex); + f->writeSint16BE(_actListArr[i][j]._a7._timer); + f->writeSint16BE(_actListArr[i][j]._a7._objIndex); break; case NEW_SCREEN: // 8 - f->writeSint16BE(_actListArr[i][j].a8.timer); - f->writeSint16BE(_actListArr[i][j].a8.screenIndex); + f->writeSint16BE(_actListArr[i][j]._a8._timer); + f->writeSint16BE(_actListArr[i][j]._a8._screenIndex); break; case INIT_OBJSTATE: // 9 - f->writeSint16BE(_actListArr[i][j].a9.timer); - f->writeSint16BE(_actListArr[i][j].a9.objIndex); - f->writeByte(_actListArr[i][j].a9.newState); + f->writeSint16BE(_actListArr[i][j]._a9._timer); + f->writeSint16BE(_actListArr[i][j]._a9._objIndex); + f->writeByte(_actListArr[i][j]._a9._newState); break; case INIT_PATH: // 10 - f->writeSint16BE(_actListArr[i][j].a10.timer); - f->writeSint16BE(_actListArr[i][j].a10.objIndex); - f->writeSint16BE(_actListArr[i][j].a10.newPathType); - f->writeByte(_actListArr[i][j].a10.vxPath); - f->writeByte(_actListArr[i][j].a10.vyPath); + f->writeSint16BE(_actListArr[i][j]._a10._timer); + f->writeSint16BE(_actListArr[i][j]._a10._objIndex); + f->writeSint16BE(_actListArr[i][j]._a10._newPathType); + f->writeByte(_actListArr[i][j]._a10._vxPath); + f->writeByte(_actListArr[i][j]._a10._vyPath); break; case COND_R: // 11 - f->writeSint16BE(_actListArr[i][j].a11.timer); - f->writeSint16BE(_actListArr[i][j].a11.objIndex); - f->writeByte(_actListArr[i][j].a11.stateReq); - f->writeUint16BE(_actListArr[i][j].a11.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a11.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a11._timer); + f->writeSint16BE(_actListArr[i][j]._a11._objIndex); + f->writeByte(_actListArr[i][j]._a11._stateReq); + f->writeUint16BE(_actListArr[i][j]._a11._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a11._actFailIndex); break; case TEXT: // 12 - f->writeSint16BE(_actListArr[i][j].a12.timer); - f->writeSint16BE(_actListArr[i][j].a12.stringIndex); + f->writeSint16BE(_actListArr[i][j]._a12._timer); + f->writeSint16BE(_actListArr[i][j]._a12._stringIndex); break; case SWAP_IMAGES: // 13 - f->writeSint16BE(_actListArr[i][j].a13.timer); - f->writeSint16BE(_actListArr[i][j].a13.objIndex1); - f->writeSint16BE(_actListArr[i][j].a13.objIndex2); + f->writeSint16BE(_actListArr[i][j]._a13._timer); + f->writeSint16BE(_actListArr[i][j]._a13._objIndex1); + f->writeSint16BE(_actListArr[i][j]._a13._objIndex2); break; case COND_SCR: // 14 - f->writeSint16BE(_actListArr[i][j].a14.timer); - f->writeSint16BE(_actListArr[i][j].a14.objIndex); - f->writeSint16BE(_actListArr[i][j].a14.screenReq); - f->writeUint16BE(_actListArr[i][j].a14.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a14.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a14._timer); + f->writeSint16BE(_actListArr[i][j]._a14._objIndex); + f->writeSint16BE(_actListArr[i][j]._a14._screenReq); + f->writeUint16BE(_actListArr[i][j]._a14._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a14._actFailIndex); break; case AUTOPILOT: // 15 - f->writeSint16BE(_actListArr[i][j].a15.timer); - f->writeSint16BE(_actListArr[i][j].a15.objIndex1); - f->writeSint16BE(_actListArr[i][j].a15.objIndex2); - f->writeByte(_actListArr[i][j].a15.dx); - f->writeByte(_actListArr[i][j].a15.dy); + f->writeSint16BE(_actListArr[i][j]._a15._timer); + f->writeSint16BE(_actListArr[i][j]._a15._objIndex1); + f->writeSint16BE(_actListArr[i][j]._a15._objIndex2); + f->writeByte(_actListArr[i][j]._a15._dx); + f->writeByte(_actListArr[i][j]._a15._dy); break; case INIT_OBJ_SEQ: // 16 - f->writeSint16BE(_actListArr[i][j].a16.timer); - f->writeSint16BE(_actListArr[i][j].a16.objIndex); - f->writeSint16BE(_actListArr[i][j].a16.seqIndex); + f->writeSint16BE(_actListArr[i][j]._a16._timer); + f->writeSint16BE(_actListArr[i][j]._a16._objIndex); + f->writeSint16BE(_actListArr[i][j]._a16._seqIndex); break; case SET_STATE_BITS: // 17 - f->writeSint16BE(_actListArr[i][j].a17.timer); - f->writeSint16BE(_actListArr[i][j].a17.objIndex); - f->writeSint16BE(_actListArr[i][j].a17.stateMask); + f->writeSint16BE(_actListArr[i][j]._a17._timer); + f->writeSint16BE(_actListArr[i][j]._a17._objIndex); + f->writeSint16BE(_actListArr[i][j]._a17._stateMask); break; case CLEAR_STATE_BITS: // 18 - f->writeSint16BE(_actListArr[i][j].a18.timer); - f->writeSint16BE(_actListArr[i][j].a18.objIndex); - f->writeSint16BE(_actListArr[i][j].a18.stateMask); + f->writeSint16BE(_actListArr[i][j]._a18._timer); + f->writeSint16BE(_actListArr[i][j]._a18._objIndex); + f->writeSint16BE(_actListArr[i][j]._a18._stateMask); break; case TEST_STATE_BITS: // 19 - f->writeSint16BE(_actListArr[i][j].a19.timer); - f->writeSint16BE(_actListArr[i][j].a19.objIndex); - f->writeSint16BE(_actListArr[i][j].a19.stateMask); - f->writeUint16BE(_actListArr[i][j].a19.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a19.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a19._timer); + f->writeSint16BE(_actListArr[i][j]._a19._objIndex); + f->writeSint16BE(_actListArr[i][j]._a19._stateMask); + f->writeUint16BE(_actListArr[i][j]._a19._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a19._actFailIndex); break; case DEL_EVENTS: // 20 - f->writeSint16BE(_actListArr[i][j].a20.timer); - f->writeByte(_actListArr[i][j].a20.actTypeDel); + f->writeSint16BE(_actListArr[i][j]._a20._timer); + f->writeByte(_actListArr[i][j]._a20._actTypeDel); break; case GAMEOVER: // 21 - f->writeSint16BE(_actListArr[i][j].a21.timer); + f->writeSint16BE(_actListArr[i][j]._a21._timer); break; case INIT_HH_COORD: // 22 - f->writeSint16BE(_actListArr[i][j].a22.timer); - f->writeSint16BE(_actListArr[i][j].a22.objIndex); + f->writeSint16BE(_actListArr[i][j]._a22._timer); + f->writeSint16BE(_actListArr[i][j]._a22._objIndex); break; case EXIT: // 23 - f->writeSint16BE(_actListArr[i][j].a23.timer); + f->writeSint16BE(_actListArr[i][j]._a23._timer); break; case BONUS: // 24 - f->writeSint16BE(_actListArr[i][j].a24.timer); - f->writeSint16BE(_actListArr[i][j].a24.pointIndex); + f->writeSint16BE(_actListArr[i][j]._a24._timer); + f->writeSint16BE(_actListArr[i][j]._a24._pointIndex); break; case COND_BOX: // 25 - f->writeSint16BE(_actListArr[i][j].a25.timer); - f->writeSint16BE(_actListArr[i][j].a25.objIndex); - f->writeSint16BE(_actListArr[i][j].a25.x1); - f->writeSint16BE(_actListArr[i][j].a25.y1); - f->writeSint16BE(_actListArr[i][j].a25.x2); - f->writeSint16BE(_actListArr[i][j].a25.y2); - f->writeUint16BE(_actListArr[i][j].a25.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a25.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a25._timer); + f->writeSint16BE(_actListArr[i][j]._a25._objIndex); + f->writeSint16BE(_actListArr[i][j]._a25._x1); + f->writeSint16BE(_actListArr[i][j]._a25._y1); + f->writeSint16BE(_actListArr[i][j]._a25._x2); + f->writeSint16BE(_actListArr[i][j]._a25._y2); + f->writeUint16BE(_actListArr[i][j]._a25._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a25._actFailIndex); break; case SOUND: // 26 - f->writeSint16BE(_actListArr[i][j].a26.timer); - f->writeSint16BE(_actListArr[i][j].a26.soundIndex); + f->writeSint16BE(_actListArr[i][j]._a26._timer); + f->writeSint16BE(_actListArr[i][j]._a26._soundIndex); break; case ADD_SCORE: // 27 - f->writeSint16BE(_actListArr[i][j].a27.timer); - f->writeSint16BE(_actListArr[i][j].a27.objIndex); + f->writeSint16BE(_actListArr[i][j]._a27._timer); + f->writeSint16BE(_actListArr[i][j]._a27._objIndex); break; case SUB_SCORE: // 28 - f->writeSint16BE(_actListArr[i][j].a28.timer); - f->writeSint16BE(_actListArr[i][j].a28.objIndex); + f->writeSint16BE(_actListArr[i][j]._a28._timer); + f->writeSint16BE(_actListArr[i][j]._a28._objIndex); break; case COND_CARRY: // 29 - f->writeSint16BE(_actListArr[i][j].a29.timer); - f->writeSint16BE(_actListArr[i][j].a29.objIndex); - f->writeUint16BE(_actListArr[i][j].a29.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a29.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a29._timer); + f->writeSint16BE(_actListArr[i][j]._a29._objIndex); + f->writeUint16BE(_actListArr[i][j]._a29._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a29._actFailIndex); break; case INIT_MAZE: // 30 - f->writeSint16BE(_actListArr[i][j].a30.timer); - f->writeByte(_actListArr[i][j].a30.mazeSize); - f->writeSint16BE(_actListArr[i][j].a30.x1); - f->writeSint16BE(_actListArr[i][j].a30.y1); - f->writeSint16BE(_actListArr[i][j].a30.x2); - f->writeSint16BE(_actListArr[i][j].a30.y2); - f->writeSint16BE(_actListArr[i][j].a30.x3); - f->writeSint16BE(_actListArr[i][j].a30.x4); - f->writeByte(_actListArr[i][j].a30.firstScreenIndex); + f->writeSint16BE(_actListArr[i][j]._a30._timer); + f->writeByte(_actListArr[i][j]._a30._mazeSize); + f->writeSint16BE(_actListArr[i][j]._a30._x1); + f->writeSint16BE(_actListArr[i][j]._a30._y1); + f->writeSint16BE(_actListArr[i][j]._a30._x2); + f->writeSint16BE(_actListArr[i][j]._a30._y2); + f->writeSint16BE(_actListArr[i][j]._a30._x3); + f->writeSint16BE(_actListArr[i][j]._a30._x4); + f->writeByte(_actListArr[i][j]._a30._firstScreenIndex); break; case EXIT_MAZE: // 31 - f->writeSint16BE(_actListArr[i][j].a31.timer); + f->writeSint16BE(_actListArr[i][j]._a31._timer); break; case INIT_PRIORITY: // 32 - f->writeSint16BE(_actListArr[i][j].a32.timer); - f->writeSint16BE(_actListArr[i][j].a32.objIndex); - f->writeByte(_actListArr[i][j].a32.priority); + f->writeSint16BE(_actListArr[i][j]._a32._timer); + f->writeSint16BE(_actListArr[i][j]._a32._objIndex); + f->writeByte(_actListArr[i][j]._a32._priority); break; case INIT_SCREEN: // 33 - f->writeSint16BE(_actListArr[i][j].a33.timer); - f->writeSint16BE(_actListArr[i][j].a33.objIndex); - f->writeSint16BE(_actListArr[i][j].a33.screenIndex); + f->writeSint16BE(_actListArr[i][j]._a33._timer); + f->writeSint16BE(_actListArr[i][j]._a33._objIndex); + f->writeSint16BE(_actListArr[i][j]._a33._screenIndex); break; case AGSCHEDULE: // 34 - f->writeSint16BE(_actListArr[i][j].a34.timer); - f->writeUint16BE(_actListArr[i][j].a34.actIndex); + f->writeSint16BE(_actListArr[i][j]._a34._timer); + f->writeUint16BE(_actListArr[i][j]._a34._actIndex); break; case REMAPPAL: // 35 - f->writeSint16BE(_actListArr[i][j].a35.timer); - f->writeSint16BE(_actListArr[i][j].a35.oldColorIndex); - f->writeSint16BE(_actListArr[i][j].a35.newColorIndex); + f->writeSint16BE(_actListArr[i][j]._a35._timer); + f->writeSint16BE(_actListArr[i][j]._a35._oldColorIndex); + f->writeSint16BE(_actListArr[i][j]._a35._newColorIndex); break; case COND_NOUN: // 36 - f->writeSint16BE(_actListArr[i][j].a36.timer); - f->writeUint16BE(_actListArr[i][j].a36.nounIndex); - f->writeUint16BE(_actListArr[i][j].a36.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a36.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a36._timer); + f->writeUint16BE(_actListArr[i][j]._a36._nounIndex); + f->writeUint16BE(_actListArr[i][j]._a36._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a36._actFailIndex); break; case SCREEN_STATE: // 37 - f->writeSint16BE(_actListArr[i][j].a37.timer); - f->writeSint16BE(_actListArr[i][j].a37.screenIndex); - f->writeByte(_actListArr[i][j].a37.newState); + f->writeSint16BE(_actListArr[i][j]._a37._timer); + f->writeSint16BE(_actListArr[i][j]._a37._screenIndex); + f->writeByte(_actListArr[i][j]._a37._newState); break; case INIT_LIPS: // 38 - f->writeSint16BE(_actListArr[i][j].a38.timer); - f->writeSint16BE(_actListArr[i][j].a38.lipsObjIndex); - f->writeSint16BE(_actListArr[i][j].a38.objIndex); - f->writeByte(_actListArr[i][j].a38.dxLips); - f->writeByte(_actListArr[i][j].a38.dyLips); + f->writeSint16BE(_actListArr[i][j]._a38._timer); + f->writeSint16BE(_actListArr[i][j]._a38._lipsObjIndex); + f->writeSint16BE(_actListArr[i][j]._a38._objIndex); + f->writeByte(_actListArr[i][j]._a38._dxLips); + f->writeByte(_actListArr[i][j]._a38._dyLips); break; case INIT_STORY_MODE: // 39 - f->writeSint16BE(_actListArr[i][j].a39.timer); - f->writeByte((_actListArr[i][j].a39.storyModeFl) ? 1 : 0); + f->writeSint16BE(_actListArr[i][j]._a39._timer); + f->writeByte((_actListArr[i][j]._a39._storyModeFl) ? 1 : 0); break; case WARN: // 40 - f->writeSint16BE(_actListArr[i][j].a40.timer); - f->writeSint16BE(_actListArr[i][j].a40.stringIndex); + f->writeSint16BE(_actListArr[i][j]._a40._timer); + f->writeSint16BE(_actListArr[i][j]._a40._stringIndex); break; case COND_BONUS: // 41 - f->writeSint16BE(_actListArr[i][j].a41.timer); - f->writeSint16BE(_actListArr[i][j].a41.BonusIndex); - f->writeUint16BE(_actListArr[i][j].a41.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a41.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a41._timer); + f->writeSint16BE(_actListArr[i][j]._a41._bonusIndex); + f->writeUint16BE(_actListArr[i][j]._a41._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a41._actFailIndex); break; case TEXT_TAKE: // 42 - f->writeSint16BE(_actListArr[i][j].a42.timer); - f->writeSint16BE(_actListArr[i][j].a42.objIndex); + f->writeSint16BE(_actListArr[i][j]._a42._timer); + f->writeSint16BE(_actListArr[i][j]._a42._objIndex); break; case YESNO: // 43 - f->writeSint16BE(_actListArr[i][j].a43.timer); - f->writeSint16BE(_actListArr[i][j].a43.promptIndex); - f->writeUint16BE(_actListArr[i][j].a43.actYesIndex); - f->writeUint16BE(_actListArr[i][j].a43.actNoIndex); + f->writeSint16BE(_actListArr[i][j]._a43._timer); + f->writeSint16BE(_actListArr[i][j]._a43._promptIndex); + f->writeUint16BE(_actListArr[i][j]._a43._actYesIndex); + f->writeUint16BE(_actListArr[i][j]._a43._actNoIndex); break; case STOP_ROUTE: // 44 - f->writeSint16BE(_actListArr[i][j].a44.timer); + f->writeSint16BE(_actListArr[i][j]._a44._timer); break; case COND_ROUTE: // 45 - f->writeSint16BE(_actListArr[i][j].a45.timer); - f->writeSint16BE(_actListArr[i][j].a45.routeIndex); - f->writeUint16BE(_actListArr[i][j].a45.actPassIndex); - f->writeUint16BE(_actListArr[i][j].a45.actFailIndex); + f->writeSint16BE(_actListArr[i][j]._a45._timer); + f->writeSint16BE(_actListArr[i][j]._a45._routeIndex); + f->writeUint16BE(_actListArr[i][j]._a45._actPassIndex); + f->writeUint16BE(_actListArr[i][j]._a45._actFailIndex); break; case INIT_JUMPEXIT: // 46 - f->writeSint16BE(_actListArr[i][j].a46.timer); - f->writeByte((_actListArr[i][j].a46.jumpExitFl) ? 1 : 0); + f->writeSint16BE(_actListArr[i][j]._a46._timer); + f->writeByte((_actListArr[i][j]._a46._jumpExitFl) ? 1 : 0); break; case INIT_VIEW: // 47 - f->writeSint16BE(_actListArr[i][j].a47.timer); - f->writeSint16BE(_actListArr[i][j].a47.objIndex); - f->writeSint16BE(_actListArr[i][j].a47.viewx); - f->writeSint16BE(_actListArr[i][j].a47.viewy); - f->writeSint16BE(_actListArr[i][j].a47.direction); + f->writeSint16BE(_actListArr[i][j]._a47._timer); + f->writeSint16BE(_actListArr[i][j]._a47._objIndex); + f->writeSint16BE(_actListArr[i][j]._a47._viewx); + f->writeSint16BE(_actListArr[i][j]._a47._viewy); + f->writeSint16BE(_actListArr[i][j]._a47._direction); break; case INIT_OBJ_FRAME: // 48 - f->writeSint16BE(_actListArr[i][j].a48.timer); - f->writeSint16BE(_actListArr[i][j].a48.objIndex); - f->writeSint16BE(_actListArr[i][j].a48.seqIndex); - f->writeSint16BE(_actListArr[i][j].a48.frameIndex); + f->writeSint16BE(_actListArr[i][j]._a48._timer); + f->writeSint16BE(_actListArr[i][j]._a48._objIndex); + f->writeSint16BE(_actListArr[i][j]._a48._seqIndex); + f->writeSint16BE(_actListArr[i][j]._a48._frameIndex); break; case OLD_SONG: // 49, Added by Strangerke for DOS versions - f->writeSint16BE(_actListArr[i][j].a49.timer); - f->writeUint16BE(_actListArr[i][j].a49.songIndex); + f->writeSint16BE(_actListArr[i][j]._a49._timer); + f->writeUint16BE(_actListArr[i][j]._a49._songIndex); break; default: error("Unknown action %d", subElemType); @@ -1057,7 +1057,7 @@ void Scheduler::findAction(const act* action, int16* index, int16* subElem) { return; } j++; - } while (_actListArr[i][j-1].a0.actType != ANULL); + } while (_actListArr[i][j-1]._a0._actType != ANULL); } // action not found ?? assert(0); @@ -1102,18 +1102,18 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { // fix up action pointer (to do better) if ((index == -1) && (subElem == -1)) - _events[i].action = 0; + _events[i]._action = 0; else - _events[i].action = (act *)&_actListArr[index][subElem]; + _events[i]._action = (act *)&_actListArr[index][subElem]; - _events[i].localActionFl = (f->readByte() == 1) ? true : false; - _events[i].time = f->readUint32BE(); + _events[i]._localActionFl = (f->readByte() == 1) ? true : false; + _events[i]._time = f->readUint32BE(); int16 prevIndex = f->readSint16BE(); int16 nextIndex = f->readSint16BE(); - _events[i].prevEvent = (prevIndex == -1) ? (event_t *)0 : &_events[prevIndex]; - _events[i].nextEvent = (nextIndex == -1) ? (event_t *)0 : &_events[nextIndex]; + _events[i]._prevEvent = (prevIndex == -1) ? (event_t *)0 : &_events[prevIndex]; + _events[i]._nextEvent = (nextIndex == -1) ? (event_t *)0 : &_events[nextIndex]; } _freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex]; _headEvent = (headIndex == -1) ? 0 : &_events[headIndex]; @@ -1123,8 +1123,8 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { uint32 curTime = getTicks(); event_t *wrkEvent = _headEvent; // The earliest event while (wrkEvent) { // While mature events found - wrkEvent->time = wrkEvent->time - saveTime + curTime; - wrkEvent = wrkEvent->nextEvent; + wrkEvent->_time = wrkEvent->_time - saveTime + curTime; + wrkEvent = wrkEvent->_nextEvent; } } @@ -1133,52 +1133,52 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { * The queue goes from head (earliest) to tail (latest) timewise */ void Scheduler::insertAction(act *action) { - debugC(1, kDebugSchedule, "insertAction() - Action type A%d", action->a0.actType); + debugC(1, kDebugSchedule, "insertAction() - Action type A%d", action->_a0._actType); // First, get and initialize the event structure event_t *curEvent = getQueue(); - curEvent->action = action; - switch (action->a0.actType) { // Assign whether local or global + curEvent->_action = action; + switch (action->_a0._actType) { // Assign whether local or global case AGSCHEDULE: - curEvent->localActionFl = false; // Lasts over a new screen + curEvent->_localActionFl = false; // Lasts over a new screen break; // Workaround: When dying, switch to storyMode in order to block the keyboard. case GAMEOVER: _vm->getGameStatus()._storyModeFl = true; // No break on purpose default: - curEvent->localActionFl = true; // Rest are for current screen only + curEvent->_localActionFl = true; // Rest are for current screen only break; } - curEvent->time = action->a0.timer + getTicks(); // Convert rel to abs time + curEvent->_time = action->_a0._timer + getTicks(); // Convert rel to abs time // Now find the place to insert the event if (!_tailEvent) { // Empty queue _tailEvent = _headEvent = curEvent; - curEvent->nextEvent = curEvent->prevEvent = 0; + curEvent->_nextEvent = curEvent->_prevEvent = 0; } else { event_t *wrkEvent = _tailEvent; // Search from latest time back bool found = false; while (wrkEvent && !found) { - if (wrkEvent->time <= curEvent->time) { // Found if new event later + if (wrkEvent->_time <= curEvent->_time) { // Found if new event later found = true; if (wrkEvent == _tailEvent) // New latest in list _tailEvent = curEvent; else - wrkEvent->nextEvent->prevEvent = curEvent; - curEvent->nextEvent = wrkEvent->nextEvent; - wrkEvent->nextEvent = curEvent; - curEvent->prevEvent = wrkEvent; + wrkEvent->_nextEvent->_prevEvent = curEvent; + curEvent->_nextEvent = wrkEvent->_nextEvent; + wrkEvent->_nextEvent = curEvent; + curEvent->_prevEvent = wrkEvent; } - wrkEvent = wrkEvent->prevEvent; + wrkEvent = wrkEvent->_prevEvent; } if (!found) { // Must be earliest in list - _headEvent->prevEvent = curEvent; // So insert as new head - curEvent->nextEvent = _headEvent; - curEvent->prevEvent = 0; + _headEvent->_prevEvent = curEvent; // So insert as new head + curEvent->_nextEvent = _headEvent; + curEvent->_prevEvent = 0; _headEvent = curEvent; } } @@ -1190,94 +1190,94 @@ void Scheduler::insertAction(act *action) { * to the next action in the list, except special case of NEW_SCREEN */ event_t *Scheduler::doAction(event_t *curEvent) { - debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType); + debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->_action->_a0._actType); status_t &gameStatus = _vm->getGameStatus(); - act *action = curEvent->action; + act *action = curEvent->_action; object_t *obj1; int dx, dy; event_t *wrkEvent; // Save ev_p->next_p for return - switch (action->a0.actType) { + switch (action->_a0._actType) { case ANULL: // Big NOP from DEL_EVENTS break; case ASCHEDULE: // act0: Schedule an action list - insertActionList(action->a0.actIndex); + insertActionList(action->_a0._actIndex); break; case START_OBJ: // act1: Start an object cycling - _vm->_object->_objects[action->a1.objIndex]._cycleNumb = action->a1.cycleNumb; - _vm->_object->_objects[action->a1.objIndex]._cycling = action->a1.cycle; + _vm->_object->_objects[action->_a1._objIndex]._cycleNumb = action->_a1._cycleNumb; + _vm->_object->_objects[action->_a1._objIndex]._cycling = action->_a1._cycle; break; case INIT_OBJXY: // act2: Initialize an object - _vm->_object->_objects[action->a2.objIndex]._x = action->a2.x; // Coordinates - _vm->_object->_objects[action->a2.objIndex]._y = action->a2.y; + _vm->_object->_objects[action->_a2._objIndex]._x = action->_a2._x; // Coordinates + _vm->_object->_objects[action->_a2._objIndex]._y = action->_a2._y; break; case PROMPT: // act3: Prompt user for key phrase promptAction(action); break; case BKGD_COLOR: // act4: Set new background color - _vm->_screen->setBackgroundColor(action->a4.newBackgroundColor); + _vm->_screen->setBackgroundColor(action->_a4._newBackgroundColor); break; case INIT_OBJVXY: // act5: Initialize an object velocity - _vm->_object->setVelocity(action->a5.objIndex, action->a5.vx, action->a5.vy); + _vm->_object->setVelocity(action->_a5._objIndex, action->_a5._vx, action->_a5._vy); break; case INIT_CARRY: // act6: Initialize an object - _vm->_object->setCarry(action->a6.objIndex, action->a6.carriedFl); // carried status + _vm->_object->setCarry(action->_a6._objIndex, action->_a6._carriedFl); // carried status break; case INIT_HF_COORD: // act7: Initialize an object to hero's "feet" coords - _vm->_object->_objects[action->a7.objIndex]._x = _vm->_hero->_x - 1; - _vm->_object->_objects[action->a7.objIndex]._y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1; - _vm->_object->_objects[action->a7.objIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! + _vm->_object->_objects[action->_a7._objIndex]._x = _vm->_hero->_x - 1; + _vm->_object->_objects[action->_a7._objIndex]._y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1; + _vm->_object->_objects[action->_a7._objIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! break; case NEW_SCREEN: // act8: Start new screen - newScreen(action->a8.screenIndex); + newScreen(action->_a8._screenIndex); break; case INIT_OBJSTATE: // act9: Initialize an object state - _vm->_object->_objects[action->a9.objIndex]._state = action->a9.newState; + _vm->_object->_objects[action->_a9._objIndex]._state = action->_a9._newState; break; case INIT_PATH: // act10: Initialize an object path and velocity - _vm->_object->setPath(action->a10.objIndex, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath); + _vm->_object->setPath(action->_a10._objIndex, (path_t) action->_a10._newPathType, action->_a10._vxPath, action->_a10._vyPath); break; case COND_R: // act11: action lists conditional on object state - if (_vm->_object->_objects[action->a11.objIndex]._state == action->a11.stateReq) - insertActionList(action->a11.actPassIndex); + if (_vm->_object->_objects[action->_a11._objIndex]._state == action->_a11._stateReq) + insertActionList(action->_a11._actPassIndex); else - insertActionList(action->a11.actFailIndex); + insertActionList(action->_a11._actFailIndex); break; case TEXT: // act12: Text box (CF WARN) - Utils::notifyBox(_vm->_file->fetchString(action->a12.stringIndex)); // Fetch string from file + Utils::notifyBox(_vm->_file->fetchString(action->_a12._stringIndex)); // Fetch string from file break; case SWAP_IMAGES: // act13: Swap 2 object images - _vm->_object->swapImages(action->a13.objIndex1, action->a13.objIndex2); + _vm->_object->swapImages(action->_a13._objIndex1, action->_a13._objIndex2); break; case COND_SCR: // act14: Conditional on current screen - if (_vm->_object->_objects[action->a14.objIndex]._screenIndex == action->a14.screenReq) - insertActionList(action->a14.actPassIndex); + if (_vm->_object->_objects[action->_a14._objIndex]._screenIndex == action->_a14._screenReq) + insertActionList(action->_a14._actPassIndex); else - insertActionList(action->a14.actFailIndex); + insertActionList(action->_a14._actFailIndex); break; case AUTOPILOT: // act15: Home in on a (stationary) object - _vm->_object->homeIn(action->a15.objIndex1, action->a15.objIndex2, action->a15.dx, action->a15.dy); + _vm->_object->homeIn(action->_a15._objIndex1, action->_a15._objIndex2, action->_a15._dx, action->_a15._dy); break; case INIT_OBJ_SEQ: // act16: Set sequence number to use // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! t>0 is safe - _vm->_object->_objects[action->a16.objIndex]._currImagePtr = _vm->_object->_objects[action->a16.objIndex]._seqList[action->a16.seqIndex]._seqPtr; + _vm->_object->_objects[action->_a16._objIndex]._currImagePtr = _vm->_object->_objects[action->_a16._objIndex]._seqList[action->_a16._seqIndex]._seqPtr; break; case SET_STATE_BITS: // act17: OR mask with curr obj state - _vm->_object->_objects[action->a17.objIndex]._state |= action->a17.stateMask; + _vm->_object->_objects[action->_a17._objIndex]._state |= action->_a17._stateMask; break; case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state - _vm->_object->_objects[action->a18.objIndex]._state &= ~action->a18.stateMask; + _vm->_object->_objects[action->_a18._objIndex]._state &= ~action->_a18._stateMask; break; case TEST_STATE_BITS: // act19: If all bits set, do apass else afail - if ((_vm->_object->_objects[action->a19.objIndex]._state & action->a19.stateMask) == action->a19.stateMask) - insertActionList(action->a19.actPassIndex); + if ((_vm->_object->_objects[action->_a19._objIndex]._state & action->_a19._stateMask) == action->_a19._stateMask) + insertActionList(action->_a19._actPassIndex); else - insertActionList(action->a19.actFailIndex); + insertActionList(action->_a19._actFailIndex); break; case DEL_EVENTS: // act20: Remove all events of this action type - delEventType(action->a20.actTypeDel); + delEventType(action->_a20._actTypeDel); break; case GAMEOVER: // act21: Game over! // NOTE: Must wait at least 1 tick before issuing this action if @@ -1285,148 +1285,148 @@ event_t *Scheduler::doAction(event_t *curEvent) { gameStatus._gameOverFl = true; break; case INIT_HH_COORD: // act22: Initialize an object to hero's actual coords - _vm->_object->_objects[action->a22.objIndex]._x = _vm->_hero->_x; - _vm->_object->_objects[action->a22.objIndex]._y = _vm->_hero->_y; - _vm->_object->_objects[action->a22.objIndex]._screenIndex = *_vm->_screen_p;// Don't forget screen! + _vm->_object->_objects[action->_a22._objIndex]._x = _vm->_hero->_x; + _vm->_object->_objects[action->_a22._objIndex]._y = _vm->_hero->_y; + _vm->_object->_objects[action->_a22._objIndex]._screenIndex = *_vm->_screen_p;// Don't forget screen! break; case EXIT: // act23: Exit game back to DOS _vm->endGame(); break; case BONUS: // act24: Get bonus score for action - processBonus(action->a24.pointIndex); + processBonus(action->_a24._pointIndex); break; case COND_BOX: // act25: Conditional on bounding box - obj1 = &_vm->_object->_objects[action->a25.objIndex]; + obj1 = &_vm->_object->_objects[action->_a25._objIndex]; dx = obj1->_x + obj1->_currImagePtr->_x1; dy = obj1->_y + obj1->_currImagePtr->_y2; - if ((dx >= action->a25.x1) && (dx <= action->a25.x2) && - (dy >= action->a25.y1) && (dy <= action->a25.y2)) - insertActionList(action->a25.actPassIndex); + if ((dx >= action->_a25._x1) && (dx <= action->_a25._x2) && + (dy >= action->_a25._y1) && (dy <= action->_a25._y2)) + insertActionList(action->_a25._actPassIndex); else - insertActionList(action->a25.actFailIndex); + insertActionList(action->_a25._actFailIndex); break; case SOUND: // act26: Play a sound (or tune) - if (action->a26.soundIndex < _vm->_tunesNbr) - _vm->_sound->playMusic(action->a26.soundIndex); + if (action->_a26._soundIndex < _vm->_tunesNbr) + _vm->_sound->playMusic(action->_a26._soundIndex); else - _vm->_sound->playSound(action->a26.soundIndex, kSoundPriorityMedium); + _vm->_sound->playSound(action->_a26._soundIndex, kSoundPriorityMedium); break; case ADD_SCORE: // act27: Add object's value to score - _vm->adjustScore(_vm->_object->_objects[action->a27.objIndex]._objValue); + _vm->adjustScore(_vm->_object->_objects[action->_a27._objIndex]._objValue); break; case SUB_SCORE: // act28: Subtract object's value from score - _vm->adjustScore(-_vm->_object->_objects[action->a28.objIndex]._objValue); + _vm->adjustScore(-_vm->_object->_objects[action->_a28._objIndex]._objValue); break; case COND_CARRY: // act29: Conditional on object being carried - if (_vm->_object->isCarried(action->a29.objIndex)) - insertActionList(action->a29.actPassIndex); + if (_vm->_object->isCarried(action->_a29._objIndex)) + insertActionList(action->_a29._actPassIndex); else - insertActionList(action->a29.actFailIndex); + insertActionList(action->_a29._actFailIndex); break; case INIT_MAZE: // act30: Enable and init maze structure _vm->_maze._enabledFl = true; - _vm->_maze._size = action->a30.mazeSize; - _vm->_maze._x1 = action->a30.x1; - _vm->_maze._y1 = action->a30.y1; - _vm->_maze._x2 = action->a30.x2; - _vm->_maze._y2 = action->a30.y2; - _vm->_maze._x3 = action->a30.x3; - _vm->_maze._x4 = action->a30.x4; - _vm->_maze._firstScreenIndex = action->a30.firstScreenIndex; + _vm->_maze._size = action->_a30._mazeSize; + _vm->_maze._x1 = action->_a30._x1; + _vm->_maze._y1 = action->_a30._y1; + _vm->_maze._x2 = action->_a30._x2; + _vm->_maze._y2 = action->_a30._y2; + _vm->_maze._x3 = action->_a30._x3; + _vm->_maze._x4 = action->_a30._x4; + _vm->_maze._firstScreenIndex = action->_a30._firstScreenIndex; break; case EXIT_MAZE: // act31: Disable maze mode _vm->_maze._enabledFl = false; break; case INIT_PRIORITY: - _vm->_object->_objects[action->a32.objIndex]._priority = action->a32.priority; + _vm->_object->_objects[action->_a32._objIndex]._priority = action->_a32._priority; break; case INIT_SCREEN: - _vm->_object->_objects[action->a33.objIndex]._screenIndex = action->a33.screenIndex; + _vm->_object->_objects[action->_a33._objIndex]._screenIndex = action->_a33._screenIndex; break; case AGSCHEDULE: // act34: Schedule a (global) action list - insertActionList(action->a34.actIndex); + insertActionList(action->_a34._actIndex); break; case REMAPPAL: // act35: Remap a palette color - _vm->_screen->remapPal(action->a35.oldColorIndex, action->a35.newColorIndex); + _vm->_screen->remapPal(action->_a35._oldColorIndex, action->_a35._newColorIndex); break; case COND_NOUN: // act36: Conditional on noun mentioned - if (_vm->_parser->isWordPresent(_vm->_text->getNounArray(action->a36.nounIndex))) - insertActionList(action->a36.actPassIndex); + if (_vm->_parser->isWordPresent(_vm->_text->getNounArray(action->_a36._nounIndex))) + insertActionList(action->_a36._actPassIndex); else - insertActionList(action->a36.actFailIndex); + insertActionList(action->_a36._actFailIndex); break; case SCREEN_STATE: // act37: Set new screen state - _vm->_screenStates[action->a37.screenIndex] = action->a37.newState; + _vm->_screenStates[action->_a37._screenIndex] = action->_a37._newState; break; case INIT_LIPS: // act38: Position lips on object - _vm->_object->_objects[action->a38.lipsObjIndex]._x = _vm->_object->_objects[action->a38.objIndex]._x + action->a38.dxLips; - _vm->_object->_objects[action->a38.lipsObjIndex]._y = _vm->_object->_objects[action->a38.objIndex]._y + action->a38.dyLips; - _vm->_object->_objects[action->a38.lipsObjIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! - _vm->_object->_objects[action->a38.lipsObjIndex]._cycling = kCycleForward; + _vm->_object->_objects[action->_a38._lipsObjIndex]._x = _vm->_object->_objects[action->_a38._objIndex]._x + action->_a38._dxLips; + _vm->_object->_objects[action->_a38._lipsObjIndex]._y = _vm->_object->_objects[action->_a38._objIndex]._y + action->_a38._dyLips; + _vm->_object->_objects[action->_a38._lipsObjIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! + _vm->_object->_objects[action->_a38._lipsObjIndex]._cycling = kCycleForward; break; case INIT_STORY_MODE: // act39: Init story_mode flag // This is similar to the QUIET path mode, except that it is // independant of it and it additionally disables the ">" prompt - gameStatus._storyModeFl = action->a39.storyModeFl; + gameStatus._storyModeFl = action->_a39._storyModeFl; break; case WARN: // act40: Text box (CF TEXT) - Utils::notifyBox(_vm->_file->fetchString(action->a40.stringIndex)); + Utils::notifyBox(_vm->_file->fetchString(action->_a40._stringIndex)); break; case COND_BONUS: // act41: Perform action if got bonus - if (_points[action->a41.BonusIndex].scoredFl) - insertActionList(action->a41.actPassIndex); + if (_points[action->_a41._bonusIndex]._scoredFl) + insertActionList(action->_a41._actPassIndex); else - insertActionList(action->a41.actFailIndex); + insertActionList(action->_a41._actFailIndex); break; case TEXT_TAKE: // act42: Text box with "take" message - Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->a42.objIndex]._nounIndex, TAKE_NAME))); + Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->_a42._objIndex]._nounIndex, TAKE_NAME))); break; case YESNO: // act43: Prompt user for Yes or No - if (Utils::yesNoBox(_vm->_file->fetchString(action->a43.promptIndex))) - insertActionList(action->a43.actYesIndex); + if (Utils::yesNoBox(_vm->_file->fetchString(action->_a43._promptIndex))) + insertActionList(action->_a43._actYesIndex); else - insertActionList(action->a43.actNoIndex); + insertActionList(action->_a43._actNoIndex); break; case STOP_ROUTE: // act44: Stop any route in progress _vm->_route->resetRoute(); break; case COND_ROUTE: // act45: Conditional on route in progress - if (_vm->_route->getRouteIndex() >= action->a45.routeIndex) - insertActionList(action->a45.actPassIndex); + if (_vm->_route->getRouteIndex() >= action->_a45._routeIndex) + insertActionList(action->_a45._actPassIndex); else - insertActionList(action->a45.actFailIndex); + insertActionList(action->_a45._actFailIndex); break; case INIT_JUMPEXIT: // act46: Init status.jumpexit flag // This is to allow left click on exit to get there immediately // For example the plane crash in Hugo2 where hero is invisible // Couldn't use INVISIBLE flag since conflicts with boat in Hugo1 - _vm->_mouse->setJumpExitFl(action->a46.jumpExitFl); + _vm->_mouse->setJumpExitFl(action->_a46._jumpExitFl); break; - case INIT_VIEW: // act47: Init object.viewx, viewy, dir - _vm->_object->_objects[action->a47.objIndex]._viewx = action->a47.viewx; - _vm->_object->_objects[action->a47.objIndex]._viewy = action->a47.viewy; - _vm->_object->_objects[action->a47.objIndex]._direction = action->a47.direction; + case INIT_VIEW: // act47: Init object._viewx, viewy, dir + _vm->_object->_objects[action->_a47._objIndex]._viewx = action->_a47._viewx; + _vm->_object->_objects[action->_a47._objIndex]._viewy = action->_a47._viewy; + _vm->_object->_objects[action->_a47._objIndex]._direction = action->_a47._direction; break; case INIT_OBJ_FRAME: // act48: Set seq,frame number to use // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! t>0 is safe - _vm->_object->_objects[action->a48.objIndex]._currImagePtr = _vm->_object->_objects[action->a48.objIndex]._seqList[action->a48.seqIndex]._seqPtr; - for (dx = 0; dx < action->a48.frameIndex; dx++) - _vm->_object->_objects[action->a48.objIndex]._currImagePtr = _vm->_object->_objects[action->a48.objIndex]._currImagePtr->_nextSeqPtr; + _vm->_object->_objects[action->_a48._objIndex]._currImagePtr = _vm->_object->_objects[action->_a48._objIndex]._seqList[action->_a48._seqIndex]._seqPtr; + for (dx = 0; dx < action->_a48._frameIndex; dx++) + _vm->_object->_objects[action->_a48._objIndex]._currImagePtr = _vm->_object->_objects[action->_a48._objIndex]._currImagePtr->_nextSeqPtr; break; case OLD_SONG: // Replaces ACT26 for DOS games. - _vm->_sound->_DOSSongPtr = _vm->_text->getTextData(action->a49.songIndex); + _vm->_sound->_DOSSongPtr = _vm->_text->getTextData(action->_a49._songIndex); break; default: error("An error has occurred: %s", "doAction"); break; } - if (action->a0.actType == NEW_SCREEN) { // New_screen() deletes entire list + if (action->_a0._actType == NEW_SCREEN) { // New_screen() deletes entire list return 0; // next_p = 0 since list now empty } else { - wrkEvent = curEvent->nextEvent; + wrkEvent = curEvent->_nextEvent; delQueue(curEvent); // Return event to free list return wrkEvent; // Return next event ptr } @@ -1445,37 +1445,37 @@ void Scheduler::delQueue(event_t *curEvent) { debugC(4, kDebugSchedule, "delQueue()"); if (curEvent == _headEvent) { // If p was the head ptr - _headEvent = curEvent->nextEvent; // then make new head_p + _headEvent = curEvent->_nextEvent; // then make new head_p } else { // Unlink p - curEvent->prevEvent->nextEvent = curEvent->nextEvent; - if (curEvent->nextEvent) - curEvent->nextEvent->prevEvent = curEvent->prevEvent; + curEvent->_prevEvent->_nextEvent = curEvent->_nextEvent; + if (curEvent->_nextEvent) + curEvent->_nextEvent->_prevEvent = curEvent->_prevEvent; else - _tailEvent = curEvent->prevEvent; + _tailEvent = curEvent->_prevEvent; } if (_headEvent) - _headEvent->prevEvent = 0; // Mark end of list + _headEvent->_prevEvent = 0; // Mark end of list else _tailEvent = 0; // Empty queue - curEvent->nextEvent = _freeEvent; // Return p to free list + curEvent->_nextEvent = _freeEvent; // Return p to free list if (_freeEvent) // Special case, if free list was empty - _freeEvent->prevEvent = curEvent; + _freeEvent->_prevEvent = curEvent; _freeEvent = curEvent; } /** * Delete all the active events of a given type */ -void Scheduler::delEventType(const action_t actTypeDel) { +void Scheduler::delEventType(const action_t _actTypeDel) { // Note: actions are not deleted here, simply turned into NOPs! event_t *wrkEvent = _headEvent; // The earliest event event_t *saveEvent; while (wrkEvent) { // While events found in list - saveEvent = wrkEvent->nextEvent; - if (wrkEvent->action->a20.actType == actTypeDel) + saveEvent = wrkEvent->_nextEvent; + if (wrkEvent->_action->_a20._actType == _actTypeDel) delQueue(wrkEvent); wrkEvent = saveEvent; } @@ -1486,8 +1486,8 @@ void Scheduler::delEventType(const action_t actTypeDel) { */ void Scheduler::savePoints(Common::WriteStream *out) const { for (int i = 0; i < _numBonuses; i++) { - out->writeByte(_points[i].score); - out->writeByte((_points[i].scoredFl) ? 1 : 0); + out->writeByte(_points[i]._score); + out->writeByte((_points[i]._scoredFl) ? 1 : 0); } } @@ -1497,8 +1497,8 @@ void Scheduler::savePoints(Common::WriteStream *out) const { void Scheduler::restorePoints(Common::ReadStream *in) { // Restore points table for (int i = 0; i < _numBonuses; i++) { - _points[i].score = in->readByte(); - _points[i].scoredFl = (in->readByte() == 1); + _points[i]._score = in->readByte(); + _points[i]._scoredFl = (in->readByte() == 1); } } @@ -1527,27 +1527,27 @@ void Scheduler_v1d::runScheduler() { uint32 ticker = getTicks(); // The time now, in ticks event_t *curEvent = _headEvent; // The earliest event - while (curEvent && (curEvent->time <= ticker)) // While mature events found + while (curEvent && (curEvent->_time <= ticker)) // While mature events found curEvent = doAction(curEvent); // Perform the action (returns next_p) } void Scheduler_v1d::promptAction(act *action) { Common::String response; - response = Utils::promptBox(_vm->_file->fetchString(action->a3.promptIndex)); + response = Utils::promptBox(_vm->_file->fetchString(action->_a3._promptIndex)); response.toLowercase(); char resp[256]; Common::strlcpy(resp, response.c_str(), 256); - if (action->a3.encodedFl) + if (action->_a3._encodedFl) decodeString(resp); - if (strstr(resp, _vm->_file->fetchString(action->a3.responsePtr[0]))) - insertActionList(action->a3.actPassIndex); + if (strstr(resp, _vm->_file->fetchString(action->_a3._responsePtr[0]))) + insertActionList(action->_a3._actPassIndex); else - insertActionList(action->a3.actFailIndex); + insertActionList(action->_a3._actFailIndex); } /** @@ -1577,24 +1577,24 @@ const char *Scheduler_v2d::getCypher() const { void Scheduler_v2d::promptAction(act *action) { Common::String response; - response = Utils::promptBox(_vm->_file->fetchString(action->a3.promptIndex)); + response = Utils::promptBox(_vm->_file->fetchString(action->_a3._promptIndex)); response.toLowercase(); - debug(1, "doAction(act3), expecting answer %s", _vm->_file->fetchString(action->a3.responsePtr[0])); + debug(1, "doAction(act3), expecting answer %s", _vm->_file->fetchString(action->_a3._responsePtr[0])); bool found = false; const char *tmpStr; // General purpose string ptr - for (int dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) { - tmpStr = _vm->_file->fetchString(action->a3.responsePtr[dx]); + for (int dx = 0; !found && (action->_a3._responsePtr[dx] != -1); dx++) { + tmpStr = _vm->_file->fetchString(action->_a3._responsePtr[dx]); if (response.contains(tmpStr)) found = true; } if (found) - insertActionList(action->a3.actPassIndex); + insertActionList(action->_a3._actPassIndex); else - insertActionList(action->a3.actFailIndex); + insertActionList(action->_a3._actFailIndex); } /** @@ -1641,9 +1641,9 @@ void Scheduler_v1w::runScheduler() { uint32 ticker = getTicks(); // The time now, in ticks event_t *curEvent = _headEvent; // The earliest event - while (curEvent && (curEvent->time <= ticker)) // While mature events found + while (curEvent && (curEvent->_time <= ticker)) // While mature events found curEvent = doAction(curEvent); // Perform the action (returns next_p) - _vm->getGameStatus()._tick++; // Accessed elsewhere via getTicks() + _vm->getGameStatus()._tick++; // Accessed elsewhere via getTicks() } } // End of namespace Hugo diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h index 60d51f0673..74a65a5c64 100644 --- a/engines/hugo/schedule.h +++ b/engines/hugo/schedule.h @@ -93,424 +93,425 @@ enum action_t { // Parameters: }; struct act0 { // Type 0 - Schedule - action_t actType; // The type of action - int timer; // Time to set off the action - uint16 actIndex; // Ptr to an action list + action_t _actType; // The type of action + int _timer; // Time to set off the action + uint16 _actIndex; // Ptr to an action list }; struct act1 { // Type 1 - Start an object - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int cycleNumb; // Number of times to cycle - cycle_t cycle; // Direction to start cycling + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _cycleNumb; // Number of times to cycle + cycle_t _cycle; // Direction to start cycling }; struct act2 { // Type 2 - Initialize an object coords - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int x, y; // Coordinates + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _x, _y; // Coordinates }; struct act3 { // Type 3 - Prompt user for text - action_t actType; // The type of action - int timer; // Time to set off the action - uint16 promptIndex; // Index of prompt string - int *responsePtr; // Array of indexes to valid response string(s) (terminate list with -1) - uint16 actPassIndex; // Ptr to action list if success - uint16 actFailIndex; // Ptr to action list if failure - bool encodedFl; // (HUGO 1 DOS ONLY) Whether response is encoded or not + action_t _actType; // The type of action + int _timer; // Time to set off the action + uint16 _promptIndex; // Index of prompt string + int *_responsePtr; // Array of indexes to valid response string(s) (terminate list with -1) + uint16 _actPassIndex; // Ptr to action list if success + uint16 _actFailIndex; // Ptr to action list if failure + bool _encodedFl; // (HUGO 1 DOS ONLY) Whether response is encoded or not }; struct act4 { // Type 4 - Set new background color - action_t actType; // The type of action - int timer; // Time to set off the action - long newBackgroundColor; // New color + action_t _actType; // The type of action + int _timer; // Time to set off the action + long _newBackgroundColor; // New color }; struct act5 { // Type 5 - Initialize an object velocity - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int vx, vy; // velocity + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _vx, _vy; // velocity }; struct act6 { // Type 6 - Initialize an object carrying - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - bool carriedFl; // carrying + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + bool _carriedFl; // carrying }; struct act7 { // Type 7 - Initialize an object to hero's coords - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number }; struct act8 { // Type 8 - switch to new screen - action_t actType; // The type of action - int timer; // Time to set off the action - int screenIndex; // The new screen number + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _screenIndex; // The new screen number }; struct act9 { // Type 9 - Initialize an object state - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - byte newState; // New state + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + byte _newState; // New state }; struct act10 { // Type 10 - Initialize an object path type - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int newPathType; // New path type - int8 vxPath, vyPath; // Max delta velocities e.g. for CHASE + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _newPathType; // New path type + int8 _vxPath, _vyPath; // Max delta velocities e.g. for CHASE }; struct act11 { // Type 11 - Conditional on object's state - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - byte stateReq; // Required state - uint16 actPassIndex; // Ptr to action list if success - uint16 actFailIndex; // Ptr to action list if failure + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + byte _stateReq; // Required state + uint16 _actPassIndex; // Ptr to action list if success + uint16 _actFailIndex; // Ptr to action list if failure }; struct act12 { // Type 12 - Simple text box - action_t actType; // The type of action - int timer; // Time to set off the action - int stringIndex; // Index (enum) of string in strings.dat + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _stringIndex; // Index (enum) of string in strings.dat }; struct act13 { // Type 13 - Swap first object image with second - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex1; // Index of first object - int objIndex2; // 2nd + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex1; // Index of first object + int _objIndex2; // 2nd }; struct act14 { // Type 14 - Conditional on current screen - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The required object - int screenReq; // The required screen number - uint16 actPassIndex; // Ptr to action list if success - uint16 actFailIndex; // Ptr to action list if failure + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The required object + int _screenReq; // The required screen number + uint16 _actPassIndex; // Ptr to action list if success + uint16 _actFailIndex; // Ptr to action list if failure }; struct act15 { // Type 15 - Home in on an object - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex1; // The object number homing in - int objIndex2; // The object number to home in on - int8 dx, dy; // Max delta velocities + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex1; // The object number homing in + int _objIndex2; // The object number to home in on + int8 _dx, _dy; // Max delta velocities }; + // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! timer > 0 is safe struct act16 { // Type 16 - Set curr_seq_p to seq - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int seqIndex; // The index of seq array to set to + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _seqIndex; // The index of seq array to set to }; struct act17 { // Type 17 - SET obj individual state bits - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int stateMask; // The mask to OR with current obj state + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _stateMask; // The mask to OR with current obj state }; struct act18 { // Type 18 - CLEAR obj individual state bits - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int stateMask; // The mask to ~AND with current obj state + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _stateMask; // The mask to ~AND with current obj state }; struct act19 { // Type 19 - TEST obj individual state bits - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int stateMask; // The mask to AND with current obj state - uint16 actPassIndex; // Ptr to action list (all bits set) - uint16 actFailIndex; // Ptr to action list (not all set) + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _stateMask; // The mask to AND with current obj state + uint16 _actPassIndex; // Ptr to action list (all bits set) + uint16 _actFailIndex; // Ptr to action list (not all set) }; struct act20 { // Type 20 - Remove all events with this type of action - action_t actType; // The type of action - int timer; // Time to set off the action - action_t actTypeDel; // The action type to remove + action_t _actType; // The type of action + int _timer; // Time to set off the action + action_t _actTypeDel; // The action type to remove }; struct act21 { // Type 21 - Gameover. Disable hero & commands - action_t actType; // The type of action - int timer; // Time to set off the action + action_t _actType; // The type of action + int _timer; // Time to set off the action }; struct act22 { // Type 22 - Initialize an object to hero's coords - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number }; struct act23 { // Type 23 - Exit game back to DOS - action_t actType; // The type of action - int timer; // Time to set off the action + action_t _actType; // The type of action + int _timer; // Time to set off the action }; struct act24 { // Type 24 - Get bonus score - action_t actType; // The type of action - int timer; // Time to set off the action - int pointIndex; // Index into points array + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _pointIndex; // Index into points array }; struct act25 { // Type 25 - Conditional on bounding box - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The required object number - int x1, y1, x2, y2; // The bounding box - uint16 actPassIndex; // Ptr to action list if success - uint16 actFailIndex; // Ptr to action list if failure + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The required object number + int _x1, _y1, _x2, _y2; // The bounding box + uint16 _actPassIndex; // Ptr to action list if success + uint16 _actFailIndex; // Ptr to action list if failure }; struct act26 { // Type 26 - Play a sound - action_t actType; // The type of action - int timer; // Time to set off the action - int16 soundIndex; // Sound index in data file + action_t _actType; // The type of action + int _timer; // Time to set off the action + int16 _soundIndex; // Sound index in data file }; struct act27 { // Type 27 - Add object's value to score - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // object number + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // object number }; struct act28 { // Type 28 - Subtract object's value from score - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // object number + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // object number }; struct act29 { // Type 29 - Conditional on object carried - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The required object number - uint16 actPassIndex; // Ptr to action list if success - uint16 actFailIndex; // Ptr to action list if failure + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The required object number + uint16 _actPassIndex; // Ptr to action list if success + uint16 _actFailIndex; // Ptr to action list if failure }; struct act30 { // Type 30 - Start special maze processing - action_t actType; // The type of action - int timer; // Time to set off the action - byte mazeSize; // Size of (square) maze - int x1, y1, x2, y2; // Bounding box of maze - int x3, x4; // Extra x points for perspective correction - byte firstScreenIndex; // First (top left) screen of maze + action_t _actType; // The type of action + int _timer; // Time to set off the action + byte _mazeSize; // Size of (square) maze + int _x1, _y1, _x2, _y2; // Bounding box of maze + int _x3, _x4; // Extra x points for perspective correction + byte _firstScreenIndex; // First (top left) screen of maze }; struct act31 { // Type 31 - Exit special maze processing - action_t actType; // The type of action - int timer; // Time to set off the action + action_t _actType; // The type of action + int _timer; // Time to set off the action }; struct act32 { // Type 32 - Init fbg field of object - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - byte priority; // Value of foreground/background field + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + byte _priority; // Value of foreground/background field }; struct act33 { // Type 33 - Init screen field of object - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int screenIndex; // Screen number + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _screenIndex; // Screen number }; struct act34 { // Type 34 - Global Schedule - action_t actType; // The type of action - int timer; // Time to set off the action - uint16 actIndex; // Ptr to an action list + action_t _actType; // The type of action + int _timer; // Time to set off the action + uint16 _actIndex; // Ptr to an action list }; struct act35 { // Type 35 - Remappe palette - action_t actType; // The type of action - int timer; // Time to set off the action - int16 oldColorIndex; // Old color index, 0..15 - int16 newColorIndex; // New color index, 0..15 + action_t _actType; // The type of action + int _timer; // Time to set off the action + int16 _oldColorIndex; // Old color index, 0..15 + int16 _newColorIndex; // New color index, 0..15 }; struct act36 { // Type 36 - Conditional on noun mentioned - action_t actType; // The type of action - int timer; // Time to set off the action - uint16 nounIndex; // The required noun (list) - uint16 actPassIndex; // Ptr to action list if success - uint16 actFailIndex; // Ptr to action list if failure + action_t _actType; // The type of action + int _timer; // Time to set off the action + uint16 _nounIndex; // The required noun (list) + uint16 _actPassIndex; // Ptr to action list if success + uint16 _actFailIndex; // Ptr to action list if failure }; struct act37 { // Type 37 - Set new screen state - action_t actType; // The type of action - int timer; // Time to set off the action - int screenIndex; // The screen number - byte newState; // The new state + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _screenIndex; // The screen number + byte _newState; // The new state }; struct act38 { // Type 38 - Position lips - action_t actType; // The type of action - int timer; // Time to set off the action - int lipsObjIndex; // The LIPS object - int objIndex; // The object to speak - byte dxLips; // Relative offset of x - byte dyLips; // Relative offset of y + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _lipsObjIndex; // The LIPS object + int _objIndex; // The object to speak + byte _dxLips; // Relative offset of x + byte _dyLips; // Relative offset of y }; struct act39 { // Type 39 - Init story mode - action_t actType; // The type of action - int timer; // Time to set off the action - bool storyModeFl; // New state of story_mode flag + action_t _actType; // The type of action + int _timer; // Time to set off the action + bool _storyModeFl; // New state of story_mode flag }; struct act40 { // Type 40 - Unsolicited text box - action_t actType; // The type of action - int timer; // Time to set off the action - int stringIndex; // Index (enum) of string in strings.dat + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _stringIndex; // Index (enum) of string in strings.dat }; struct act41 { // Type 41 - Conditional on bonus scored - action_t actType; // The type of action - int timer; // Time to set off the action - int BonusIndex; // Index into bonus list - uint16 actPassIndex; // Index of the action list if scored for the first time - uint16 actFailIndex; // Index of the action list if already scored + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _bonusIndex; // Index into bonus list + uint16 _actPassIndex; // Index of the action list if scored for the first time + uint16 _actFailIndex; // Index of the action list if already scored }; struct act42 { // Type 42 - Text box with "take" string - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object taken + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object taken }; struct act43 { // Type 43 - Prompt user for Yes or No - action_t actType; // The type of action - int timer; // Time to set off the action - int promptIndex; // index of prompt string - uint16 actYesIndex; // Ptr to action list if YES - uint16 actNoIndex; // Ptr to action list if NO + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _promptIndex; // index of prompt string + uint16 _actYesIndex; // Ptr to action list if YES + uint16 _actNoIndex; // Ptr to action list if NO }; struct act44 { // Type 44 - Stop any route in progress - action_t actType; // The type of action - int timer; // Time to set off the action + action_t _actType; // The type of action + int _timer; // Time to set off the action }; struct act45 { // Type 45 - Conditional on route in progress - action_t actType; // The type of action - int timer; // Time to set off the action - int routeIndex; // Must be >= current status.rindex - uint16 actPassIndex; // Ptr to action list if en-route - uint16 actFailIndex; // Ptr to action list if not + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _routeIndex; // Must be >= current status.rindex + uint16 _actPassIndex; // Ptr to action list if en-route + uint16 _actFailIndex; // Ptr to action list if not }; struct act46 { // Type 46 - Init status.jumpexit - action_t actType; // The type of action - int timer; // Time to set off the action - bool jumpExitFl; // New state of jumpexit flag + action_t _actType; // The type of action + int _timer; // Time to set off the action + bool _jumpExitFl; // New state of jumpexit flag }; struct act47 { // Type 47 - Init viewx,viewy,dir - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object - int16 viewx; // object.viewx - int16 viewy; // object.viewy - int16 direction; // object.dir + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object + int16 _viewx; // object.viewx + int16 _viewy; // object.viewy + int16 _direction; // object.dir }; struct act48 { // Type 48 - Set curr_seq_p to frame n - action_t actType; // The type of action - int timer; // Time to set off the action - int objIndex; // The object number - int seqIndex; // The index of seq array to set to - int frameIndex; // The index of frame to set to + action_t _actType; // The type of action + int _timer; // Time to set off the action + int _objIndex; // The object number + int _seqIndex; // The index of seq array to set to + int _frameIndex; // The index of frame to set to }; -struct act49 { // Added by Strangerke - Type 79 - Play a song (DOS way) - action_t actType; // The type of action - int timer; // Time to set off the action - uint16 songIndex; // Song index in string array +struct act49 { // Added by Strangerke - Type 49 - Play a song (DOS way) + action_t _actType; // The type of action + int _timer; // Time to set off the action + uint16 _songIndex; // Song index in string array }; union act { - act0 a0; - act1 a1; - act2 a2; - act3 a3; - act4 a4; - act5 a5; - act6 a6; - act7 a7; - act8 a8; - act9 a9; - act10 a10; - act11 a11; - act12 a12; - act13 a13; - act14 a14; - act15 a15; - act16 a16; - act17 a17; - act18 a18; - act19 a19; - act20 a20; - act21 a21; - act22 a22; - act23 a23; - act24 a24; - act25 a25; - act26 a26; - act27 a27; - act28 a28; - act29 a29; - act30 a30; - act31 a31; - act32 a32; - act33 a33; - act34 a34; - act35 a35; - act36 a36; - act37 a37; - act38 a38; - act39 a39; - act40 a40; - act41 a41; - act42 a42; - act43 a43; - act44 a44; - act45 a45; - act46 a46; - act47 a47; - act48 a48; - act49 a49; + act0 _a0; + act1 _a1; + act2 _a2; + act3 _a3; + act4 _a4; + act5 _a5; + act6 _a6; + act7 _a7; + act8 _a8; + act9 _a9; + act10 _a10; + act11 _a11; + act12 _a12; + act13 _a13; + act14 _a14; + act15 _a15; + act16 _a16; + act17 _a17; + act18 _a18; + act19 _a19; + act20 _a20; + act21 _a21; + act22 _a22; + act23 _a23; + act24 _a24; + act25 _a25; + act26 _a26; + act27 _a27; + act28 _a28; + act29 _a29; + act30 _a30; + act31 _a31; + act32 _a32; + act33 _a33; + act34 _a34; + act35 _a35; + act36 _a36; + act37 _a37; + act38 _a38; + act39 _a39; + act40 _a40; + act41 _a41; + act42 _a42; + act43 _a43; + act44 _a44; + act45 _a45; + act46 _a46; + act47 _a47; + act48 _a48; + act49 _a49; }; struct event_t { - act *action; // Ptr to action to perform - bool localActionFl; // true if action is only for this screen - uint32 time; // (absolute) time to perform action - struct event_t *prevEvent; // Chain to previous event - struct event_t *nextEvent; // Chain to next event + act *_action; // Ptr to action to perform + bool _localActionFl; // true if action is only for this screen + uint32 _time; // (absolute) time to perform action + struct event_t *_prevEvent; // Chain to previous event + struct event_t *_nextEvent; // Chain to next event }; /** * Following are points for achieving certain actions. */ struct point_t { - byte score; // The value of the point - bool scoredFl; // Whether scored yet + byte _score; // The value of the point + bool _scoredFl; // Whether scored yet }; class Scheduler { diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp index eed4164d5e..463a19ae8c 100644 --- a/engines/hugo/sound.cpp +++ b/engines/hugo/sound.cpp @@ -162,16 +162,16 @@ void SoundHandler::stopMusic() { * Turn music on and off */ void SoundHandler::toggleMusic() { - _vm->_config.musicFl = !_vm->_config.musicFl; + _vm->_config._musicFl = !_vm->_config._musicFl; - _midiPlayer->pause(!_vm->_config.musicFl); + _midiPlayer->pause(!_vm->_config._musicFl); } /** * Turn digitized sound on and off */ void SoundHandler::toggleSound() { - _vm->_config.soundFl = !_vm->_config.soundFl; + _vm->_config._soundFl = !_vm->_config._soundFl; } void SoundHandler::playMIDI(sound_pt seq_p, uint16 size) { @@ -185,7 +185,7 @@ void SoundHandler::playMusic(int16 tune) { sound_pt seqPtr; // Sequence data from file uint16 size; // Size of sequence data - if (_vm->_config.musicFl) { + if (_vm->_config._musicFl) { _vm->getGameStatus()._song = tune; seqPtr = _vm->_file->getSound(tune, &size); playMIDI(seqPtr, size); @@ -203,7 +203,7 @@ void SoundHandler::playSound(int16 sound, const byte priority) { uint16 size; // Size of data // Sound disabled - if (!_vm->_config.soundFl || !_vm->_mixer->isReady()) + if (!_vm->_config._soundFl || !_vm->_mixer->isReady()) return; syncVolume(); @@ -270,7 +270,7 @@ void SoundHandler::pcspkr_player() { static const uint16 pcspkrFlats[8] = {1435, 1279, 2342, 2150, 1916, 1755, 1611}; // The flats, Ab to Bb // Does the user not want any sound? - if (!_vm->_config.soundFl || !_vm->_mixer->isReady()) + if (!_vm->_config._soundFl || !_vm->_mixer->isReady()) return; // Is there no song? -- cgit v1.2.3 From 999ae29de43444118b5990a272a98031c4707ee0 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 20:58:01 +0200 Subject: HUGO: Rename structs and enums --- engines/hugo/display.cpp | 48 ++++++------- engines/hugo/display.h | 52 +++++++------- engines/hugo/file.cpp | 36 +++++----- engines/hugo/file.h | 32 ++++----- engines/hugo/file_v1d.cpp | 10 +-- engines/hugo/file_v1w.cpp | 8 +-- engines/hugo/file_v2d.cpp | 14 ++-- engines/hugo/file_v3d.cpp | 14 ++-- engines/hugo/game.h | 38 +++++----- engines/hugo/hugo.cpp | 12 ++-- engines/hugo/hugo.h | 68 +++++++++--------- engines/hugo/inventory.cpp | 10 +-- engines/hugo/inventory.h | 10 +-- engines/hugo/mouse.cpp | 24 +++---- engines/hugo/mouse.h | 6 +- engines/hugo/object.cpp | 74 ++++++++++---------- engines/hugo/object.h | 38 +++++----- engines/hugo/object_v1d.cpp | 42 +++++------ engines/hugo/object_v1w.cpp | 38 +++++----- engines/hugo/object_v2d.cpp | 38 +++++----- engines/hugo/object_v3d.cpp | 18 ++--- engines/hugo/parser.cpp | 20 +++--- engines/hugo/parser.h | 42 +++++------ engines/hugo/parser_v1d.cpp | 28 ++++---- engines/hugo/parser_v1w.cpp | 10 +-- engines/hugo/parser_v2d.cpp | 4 +- engines/hugo/parser_v3d.cpp | 30 ++++---- engines/hugo/route.cpp | 30 ++++---- engines/hugo/route.h | 18 ++--- engines/hugo/schedule.cpp | 72 +++++++++---------- engines/hugo/schedule.h | 166 ++++++++++++++++++++++---------------------- engines/hugo/sound.cpp | 4 +- 32 files changed, 527 insertions(+), 527 deletions(-) diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp index 12a9edfbb7..34b0303eee 100644 --- a/engines/hugo/display.cpp +++ b/engines/hugo/display.cpp @@ -105,23 +105,23 @@ Screen::Screen(HugoEngine *vm) : _vm(vm) { Screen::~Screen() { } -icondib_t &Screen::getIconBuffer() { +Icondib &Screen::getIconBuffer() { return _iconBuffer; } -viewdib_t &Screen::getBackBuffer() { +Viewdib &Screen::getBackBuffer() { return _backBuffer; } -viewdib_t &Screen::getBackBufferBackup() { +Viewdib &Screen::getBackBufferBackup() { return _backBufferBackup; } -viewdib_t &Screen::getFrontBuffer() { +Viewdib &Screen::getFrontBuffer() { return _frontBuffer; } -viewdib_t &Screen::getGUIBuffer() { +Viewdib &Screen::getGUIBuffer() { return _GUIBuffer; } @@ -149,7 +149,7 @@ void Screen::initDisplay() { /** * Move an image from source to destination */ -void Screen::moveImage(image_pt srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, image_pt dstImage, const int16 x2, const int16 y2, const int16 width2) { +void Screen::moveImage(ImagePtr srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, ImagePtr dstImage, const int16 x2, const int16 y2, const int16 width2) { debugC(3, kDebugDisplay, "moveImage(srcImage, %d, %d, %d, %d, %d, dstImage, %d, %d, %d)", x1, y1, dx, dy, width1, x2, y2, width2); int16 wrap_src = width1 - dx; // Wrap to next src row @@ -236,14 +236,14 @@ void Screen::setBackgroundColor(const uint16 color) { * Merge an object frame into _frontBuffer at sx, sy and update rectangle list. * If fore TRUE, force object above any overlay */ -void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool foreFl) { +void Screen::displayFrame(const int sx, const int sy, Seq *seq, const bool foreFl) { debugC(3, kDebugDisplay, "displayFrame(%d, %d, seq, %d)", sx, sy, (foreFl) ? 1 : 0); - image_pt image = seq->_imagePtr; // Ptr to object image data - image_pt subFrontBuffer = &_frontBuffer[sy * kXPix + sx]; // Ptr to offset in _frontBuffer + ImagePtr image = seq->_imagePtr; // Ptr to object image data + ImagePtr subFrontBuffer = &_frontBuffer[sy * kXPix + sx]; // Ptr to offset in _frontBuffer int16 frontBufferwrap = kXPix - seq->_x2 - 1; // Wraps dest_p after each line int16 imageWrap = seq->_bytesPerLine8 - seq->_x2 - 1; - overlayState_t overlayState = (foreFl) ? kOvlForeground : kOvlUndef; // Overlay state of object + OverlayState overlayState = (foreFl) ? kOvlForeground : kOvlUndef; // Overlay state of object for (uint16 y = 0; y < seq->_lines; y++) { // Each line in object for (uint16 x = 0; x <= seq->_x2; x++) { if (*image) { // Non-transparent @@ -271,7 +271,7 @@ void Screen::displayFrame(const int sx, const int sy, seq_t *seq, const bool for /** * Merge rectangles A,B leaving result in B */ -void Screen::merge(const rect_t *rectA, rect_t *rectB) { +void Screen::merge(const Rect *rectA, Rect *rectB) { debugC(6, kDebugDisplay, "merge()"); int16 xa = rectA->_x + rectA->_dx; // Find x2,y2 for each rectangle @@ -291,7 +291,7 @@ void Screen::merge(const rect_t *rectA, rect_t *rectB) { * of blist. bmax is the max size of the blist. Note that blist can * have holes, in which case dx = 0. Returns used length of blist. */ -int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 blen) { +int16 Screen::mergeLists(Rect *list, Rect *blist, const int16 len, int16 blen) { debugC(4, kDebugDisplay, "mergeLists()"); int16 coalesce[kBlitListSize]; // List of overlapping rects @@ -299,7 +299,7 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble for (int16 a = 0; a < len; a++, list++) { // Compile list of overlapping rectangles in blit list int16 c = 0; - rect_t *bp = blist; + Rect *bp = blist; for (int16 b = 0; b < blen; b++, bp++) { if (bp->_dx) // blist entry used if (isOverlapping(list, bp)) @@ -316,7 +316,7 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble // Merge any more blist entries while (--c) { - rect_t *cp = &blist[coalesce[c]]; + Rect *cp = &blist[coalesce[c]]; merge(cp, bp); cp->_dx = 0; // Delete entry } @@ -329,12 +329,12 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 ble * Process the display list * Trailing args are int16 x,y,dx,dy for the D_ADD operation */ -void Screen::displayList(dupdate_t update, ...) { +void Screen::displayList(Dupdate update, ...) { debugC(6, kDebugDisplay, "displayList()"); int16 blitLength = 0; // Length of blit list va_list marker; // Args used for D_ADD operation - rect_t *p; // Ptr to dlist entry + Rect *p; // Ptr to dlist entry switch (update) { case kDisplayInit: // Init lists, restore whole screen @@ -627,18 +627,18 @@ void Screen::hideCursor() { CursorMan.showMouse(false); } -bool Screen::isInX(const int16 x, const rect_t *rect) const { +bool Screen::isInX(const int16 x, const Rect *rect) const { return (x >= rect->_x) && (x <= rect->_x + rect->_dx); } -bool Screen::isInY(const int16 y, const rect_t *rect) const { +bool Screen::isInY(const int16 y, const Rect *rect) const { return (y >= rect->_y) && (y <= rect->_y + rect->_dy); } /** * Check if two rectangles are overlapping */ -bool Screen::isOverlapping(const rect_t *rectA, const rect_t *rectB) const { +bool Screen::isOverlapping(const Rect *rectA, const Rect *rectB) const { return (isInX(rectA->_x, rectB) || isInX(rectA->_x + rectA->_dx, rectB) || isInX(rectB->_x, rectA) || isInX(rectB->_x + rectB->_dx, rectA)) && (isInY(rectA->_y, rectB) || isInY(rectA->_y + rectA->_dy, rectB) || isInY(rectB->_y, rectA) || isInY(rectB->_y + rectB->_dy, rectA)); } @@ -656,7 +656,7 @@ void Screen::drawBoundaries() { _vm->_mouse->drawHotspots(); for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; // Get pointer to object + Object *obj = &_vm->_object->_objects[i]; // Get pointer to object if (obj->_screenIndex == *_vm->_screen_p) { if ((obj->_currImagePtr != 0) && (obj->_cycling != kCycleInvisible)) drawRectangle(false, obj->_x + obj->_currImagePtr->_x1, obj->_y + obj->_currImagePtr->_y1, @@ -730,12 +730,12 @@ void Screen_v1d::loadFontArr(Common::ReadStream &in) { * processed object by looking down the current column for an overlay * base byte set (in which case the object is foreground). */ -overlayState_t Screen_v1d::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) { +OverlayState Screen_v1d::findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y) { debugC(4, kDebugDisplay, "findOvl()"); uint16 index = (uint16)(dst_p - _frontBuffer) >> 3; - for (int i = 0; i < seq_p->_lines-y; i++) { // Each line in object + for (int i = 0; i < seqPtr->_lines-y; i++) { // Each line in object if (_vm->_object->getBaseBoundary(index)) // If any overlay base byte is non-zero then the object is foreground, else back. return kOvlForeground; index += kCompLineSize; @@ -799,10 +799,10 @@ void Screen_v1w::loadFontArr(Common::ReadStream &in) { * processed object by looking down the current column for an overlay * base bit set (in which case the object is foreground). */ -overlayState_t Screen_v1w::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) { +OverlayState Screen_v1w::findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y) { debugC(4, kDebugDisplay, "findOvl()"); - for (; y < seq_p->_lines; y++) { // Each line in object + for (; y < seqPtr->_lines; y++) { // Each line in object byte ovb = _vm->_object->getBaseBoundary((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits if (ovb & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set return kOvlForeground; // Found a bit - must be foreground diff --git a/engines/hugo/display.h b/engines/hugo/display.h index 0d8120e916..5fab2f18cc 100644 --- a/engines/hugo/display.h +++ b/engines/hugo/display.h @@ -31,14 +31,14 @@ #define HUGO_DISPLAY_H namespace Hugo { -enum overlayState_t {kOvlUndef, kOvlForeground, kOvlBackground}; // Overlay state +enum OverlayState {kOvlUndef, kOvlForeground, kOvlBackground}; // Overlay state static const int kCenter = -1; // Used to center text in x class Screen { public: - struct rect_t { // Rectangle used in Display list + struct Rect { // Rectangle used in Display list int16 _x; // Position in dib int16 _y; // Position in dib int16 _dx; // width @@ -55,8 +55,8 @@ public: int16 stringLength(const char *s) const; void displayBackground(); - void displayFrame(const int sx, const int sy, seq_t *seq, const bool foreFl); - void displayList(dupdate_t update, ...); + void displayFrame(const int sx, const int sy, Seq *seq, const bool foreFl); + void displayList(Dupdate update, ...); void displayRect(const int16 x, const int16 y, const int16 dx, const int16 dy); void drawBoundaries(); void drawRectangle(const bool filledFl, const int16 x1, const int16 y1, const int16 x2, const int16 y2, const int color); @@ -67,7 +67,7 @@ public: void initDisplay(); void initNewScreenDisplay(); void loadPalette(Common::ReadStream &in); - void moveImage(image_pt srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, image_pt dstImage, const int16 x2, const int16 y2, const int16 width2); + void moveImage(ImagePtr srcImage, const int16 x1, const int16 y1, const int16 dx, int16 dy, const int16 width1, ImagePtr dstImage, const int16 x2, const int16 y2, const int16 width2); void remapPal(uint16 oldIndex, uint16 newIndex); void resetInventoryObjId(); void restorePal(Common::ReadStream *f); @@ -80,11 +80,11 @@ public: void userHelp() const; void writeStr(int16 sx, const int16 sy, const char *s, const byte color); - icondib_t &getIconBuffer(); - viewdib_t &getBackBuffer(); - viewdib_t &getBackBufferBackup(); - viewdib_t &getFrontBuffer(); - viewdib_t &getGUIBuffer(); + Icondib &getIconBuffer(); + Viewdib &getBackBuffer(); + Viewdib &getBackBufferBackup(); + Viewdib &getFrontBuffer(); + Viewdib &getGUIBuffer(); protected: HugoEngine *_vm; @@ -108,37 +108,37 @@ protected: byte *_mainPalette; int16 _arrayFontSize[kNumFonts]; - viewdib_t _frontBuffer; + Viewdib _frontBuffer; - inline bool isInX(const int16 x, const rect_t *rect) const; - inline bool isInY(const int16 y, const rect_t *rect) const; - inline bool isOverlapping(const rect_t *rectA, const rect_t *rectB) const; + inline bool isInX(const int16 x, const Rect *rect) const; + inline bool isInY(const int16 y, const Rect *rect) const; + inline bool isOverlapping(const Rect *rectA, const Rect *rectB) const; - virtual overlayState_t findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) = 0; + virtual OverlayState findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y) = 0; private: byte *_curPalette; byte _iconImage[kInvDx * kInvDy]; byte _paletteSize; - icondib_t _iconBuffer; // Inventory icon DIB + Icondib _iconBuffer; // Inventory icon DIB - int16 mergeLists(rect_t *list, rect_t *blist, const int16 len, int16 blen); + int16 mergeLists(Rect *list, Rect *blist, const int16 len, int16 blen); int16 center(const char *s) const; - viewdib_t _backBuffer; - viewdib_t _GUIBuffer; // User interface images - viewdib_t _backBufferBackup; // Backup _backBuffer during inventory + Viewdib _backBuffer; + Viewdib _GUIBuffer; // User interface images + Viewdib _backBufferBackup; // Backup _backBuffer during inventory // Formerly static variables used by displayList() int16 _dlAddIndex, _dlRestoreIndex; // Index into add/restore lists - rect_t _dlRestoreList[kRectListSize]; // The restore list - rect_t _dlAddList[kRectListSize]; // The add list - rect_t _dlBlistList[kBlitListSize]; // The blit list + Rect _dlRestoreList[kRectListSize]; // The restore list + Rect _dlAddList[kRectListSize]; // The add list + Rect _dlBlistList[kBlitListSize]; // The blit list // void createPal(); - void merge(const rect_t *rectA, rect_t *rectB); + void merge(const Rect *rectA, Rect *rectB); void writeChr(const int sx, const int sy, const byte color, const char *local_fontdata); }; @@ -150,7 +150,7 @@ public: void loadFont(int16 fontId); void loadFontArr(Common::ReadStream &in); protected: - overlayState_t findOvl(seq_t *seq_p, image_pt dst_p, uint16 y); + OverlayState findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y); }; class Screen_v1w : public Screen { @@ -161,7 +161,7 @@ public: void loadFont(int16 fontId); void loadFontArr(Common::ReadStream &in); protected: - overlayState_t findOvl(seq_t *seq_p, image_pt dst_p, uint16 y); + OverlayState findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y); }; } // End of namespace Hugo diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index 219e29a25a..b78a26241b 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -91,8 +91,8 @@ const char *FileManager::getUifFilename() const { * Convert 4 planes (RGBI) data to 8-bit DIB format * Return original plane data ptr */ -byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, image_pt dataPtr) const { - debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, image_pt data_p)", y, bpl); +byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const { + debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, ImagePtr data_p)", y, bpl); dataPtr += y * bpl * 8; // Point to correct DIB line for (int16 r = 0, g = bpl, b = g + bpl, i = b + bpl; r < bpl; r++, g++, b++, i++) { // Each byte in all planes @@ -107,11 +107,11 @@ byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, image_p } /** - * Read a pcx file of length len. Use supplied seq_p and image_p or - * allocate space if NULL. Name used for errors. Returns address of seq_p + * Read a pcx file of length len. Use supplied seqPtr and image_p or + * allocate space if NULL. Name used for errors. Returns address of seqPtr * Set first TRUE to initialize b_index (i.e. not reading a sequential image in file). */ -seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr, const bool firstFl, const char *name) { +Seq *FileManager::readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name) { debugC(1, kDebugFile, "readPCX(..., %s)", name); // Read in the PCC header and check consistency @@ -134,9 +134,9 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr if (_PCCHeader._mfctr != 10) error("Bad data file format: %s", name); - // Allocate memory for seq_t if 0 + // Allocate memory for Seq if 0 if (seqPtr == 0) { - if ((seqPtr = (seq_t *)malloc(sizeof(seq_t))) == 0) + if ((seqPtr = (Seq *)malloc(sizeof(Seq))) == 0) error("Insufficient memory to run game."); } @@ -182,8 +182,8 @@ seq_t *FileManager::readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr /** * Read object file of PCC images into object supplied */ -void FileManager::readImage(const int objNum, object_t *objPtr) { - debugC(1, kDebugFile, "readImage(%d, object_t *objPtr)", objNum); +void FileManager::readImage(const int objNum, Object *objPtr) { + debugC(1, kDebugFile, "readImage(%d, Object *objPtr)", objNum); /** * Structure of object file lookup entry @@ -215,7 +215,7 @@ void FileManager::readImage(const int objNum, object_t *objPtr) { } bool firstImgFl = true; // Initializes pcx read function - seq_t *seqPtr = 0; // Ptr to sequence structure + Seq *seqPtr = 0; // Ptr to sequence structure // Now read the images into an images list for (int j = 0; j < objPtr->_seqNumb; j++) { // for each sequence @@ -239,7 +239,7 @@ void FileManager::readImage(const int objNum, object_t *objPtr) { seqPtr->_y1 = seqPtr->_lines; seqPtr->_y2 = 0; - image_pt dibPtr = seqPtr->_imagePtr; + ImagePtr dibPtr = seqPtr->_imagePtr; for (int y = 0; y < seqPtr->_lines; y++, dibPtr += seqPtr->_bytesPerLine8 - x2) { for (int x = 0; x < x2; x++) { if (*dibPtr++) { // Some data found @@ -382,7 +382,7 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) { _vm->_object->saveObjects(out); - const status_t &gameStatus = _vm->getGameStatus(); + const Status &gameStatus = _vm->getGameStatus(); // Save whether hero image is swapped out->writeByte(_vm->_heroImage); @@ -486,7 +486,7 @@ bool FileManager::restoreGame(const int16 slot) { _vm->_object->swapImages(kHeroIndex, _vm->_heroImage); _vm->_heroImage = heroImg; - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); int score = in->readSint16BE(); _vm->setScore(score); @@ -514,7 +514,7 @@ bool FileManager::restoreGame(const int16 slot) { _vm->_maze._firstScreenIndex = in->readByte(); _vm->_scheduler->restoreScreen(*_vm->_screen_p); - if ((_vm->getGameStatus()._viewState = (vstate_t) in->readByte()) != kViewPlay) + if ((_vm->getGameStatus()._viewState = (Vstate) in->readByte()) != kViewPlay) _vm->_screen->hideCursor(); @@ -624,8 +624,8 @@ void FileManager::readBootFile() { * This file contains, between others, the bitmaps of the fonts used in the application * UIF means User interface database (Windows Only) */ -uif_hdr_t *FileManager::get_UIFHeader(const uif_t id) { - debugC(1, kDebugFile, "get_UIFHeader(%d)", id); +UifHdr *FileManager::getUIFHeader(const Uif id) { + debugC(1, kDebugFile, "getUIFHeader(%d)", id); // Initialize offset lookup if not read yet if (_firstUIFFl) { @@ -660,11 +660,11 @@ void FileManager::readUIFItem(const int16 id, byte *buf) { error("File not found: %s", getUifFilename()); // Seek to data - uif_hdr_t *_UIFHeaderPtr = get_UIFHeader((uif_t)id); + UifHdr *_UIFHeaderPtr = getUIFHeader((Uif)id); ip.seek(_UIFHeaderPtr->_offset, SEEK_SET); // We support pcx images and straight data - seq_t *dummySeq; // Dummy seq_t for image data + Seq *dummySeq; // Dummy Seq for image data switch (id) { case UIF_IMAGES: // Read uif images file dummySeq = readPCX(ip, 0, buf, true, getUifFilename()); diff --git a/engines/hugo/file.h b/engines/hugo/file.h index e7c467a315..151b749ce7 100644 --- a/engines/hugo/file.h +++ b/engines/hugo/file.h @@ -34,9 +34,9 @@ namespace Hugo { /** * Enumerate overlay file types */ -enum ovl_t {kOvlBoundary, kOvlOverlay, kOvlBase}; +enum OvlType {kOvlBoundary, kOvlOverlay, kOvlBase}; -struct uif_hdr_t { // UIF font/image look up +struct UifHdr { // UIF font/image look up uint16 _size; // Size of uif item uint32 _offset; // Offset of item in file }; @@ -50,7 +50,7 @@ public: sound_pt getSound(const int16 sound, uint16 *size); void readBootFile(); - void readImage(const int objNum, object_t *objPtr); + void readImage(const int objNum, Object *objPtr); void readUIFImages(); void readUIFItem(const int16 id, byte *buf); bool restoreGame(const int16 slot); @@ -69,7 +69,7 @@ public: virtual void instructions() const = 0; virtual void readBackground(const int screenIndex) = 0; - virtual void readOverlay(const int screenNum, image_pt image, ovl_t overlayType) = 0; + virtual void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) = 0; virtual const char *fetchString(const int index) = 0; @@ -84,7 +84,7 @@ protected: /** * Structure of scenery file lookup entry */ - struct sceneBlock_t { + struct SceneBlock { uint32 _sceneOffset; uint32 _sceneLength; uint32 _boundaryOffset; @@ -95,7 +95,7 @@ protected: uint32 _baseLength; }; - struct _PCCHeader_t { // Structure of PCX file header + struct PCCHeader { // Structure of PCX file header byte _mfctr, _vers, _enc, _bpx; uint16 _x1, _y1, _x2, _y2; // bounding box uint16 _xres, _yres; @@ -106,23 +106,23 @@ protected: }; // Header of a PCC file bool _firstUIFFl; - uif_hdr_t _UIFHeader[kMaxUifs]; // Lookup for uif fonts/images + UifHdr _UIFHeader[kMaxUifs]; // Lookup for uif fonts/images Common::File _stringArchive; // Handle for string file Common::File _sceneryArchive1; // Handle for scenery file Common::File _objectsArchive; // Handle for objects file - _PCCHeader_t _PCCHeader; + PCCHeader _PCCHeader; - seq_t *readPCX(Common::ReadStream &f, seq_t *seqPtr, byte *imagePtr, const bool firstFl, const char *name); + Seq *readPCX(Common::ReadStream &f, Seq *seqPtr, byte *imagePtr, const bool firstFl, const char *name); // If this is the first call, read the lookup table bool _hasReadHeader; - sound_hdr_t _s_hdr[kMaxSounds]; // Sound lookup table + SoundHdr _s_hdr[kMaxSounds]; // Sound lookup table private: - byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, image_pt dataPtr) const; - uif_hdr_t *get_UIFHeader(const uif_t id); + byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const; + UifHdr *getUIFHeader(const Uif id); //Strangerke : Not used? void printBootText(); @@ -137,7 +137,7 @@ public: virtual void instructions() const; virtual void openDatabaseFiles(); virtual void readBackground(const int screenIndex); - virtual void readOverlay(const int screenNum, image_pt image, ovl_t overlayType); + virtual void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType); virtual const char *fetchString(const int index); }; @@ -149,7 +149,7 @@ public: virtual void closeDatabaseFiles(); virtual void openDatabaseFiles(); virtual void readBackground(const int screenIndex); - virtual void readOverlay(const int screenNum, image_pt image, ovl_t overlayType); + virtual void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType); const char *fetchString(const int index); private: char *_fetchStringBuf; @@ -163,7 +163,7 @@ public: void closeDatabaseFiles(); void openDatabaseFiles(); void readBackground(const int screenIndex); - void readOverlay(const int screenNum, image_pt image, ovl_t overlayType); + void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType); private: Common::File _sceneryArchive2; // Handle for scenery file }; @@ -181,7 +181,7 @@ public: FileManager_v1w(HugoEngine *vm); ~FileManager_v1w(); - void readOverlay(const int screenNum, image_pt image, ovl_t overlayType); + void readOverlay(const int screenNum, ImagePtr image, OvlType overlayType); }; } // End of namespace Hugo diff --git a/engines/hugo/file_v1d.cpp b/engines/hugo/file_v1d.cpp index c3bb0e275f..e42223fb13 100644 --- a/engines/hugo/file_v1d.cpp +++ b/engines/hugo/file_v1d.cpp @@ -55,11 +55,11 @@ void FileManager_v1d::closeDatabaseFiles() { /** * Open and read in an overlay file, close file */ -void FileManager_v1d::readOverlay(const int screenNum, image_pt image, const ovl_t overlayType) { +void FileManager_v1d::readOverlay(const int screenNum, ImagePtr image, const OvlType overlayType) { debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); - const char *ovl_ext[] = {".b", ".o", ".ob"}; - Common::String buf = Common::String(_vm->_text->getScreenNames(screenNum)) + Common::String(ovl_ext[overlayType]); + const char *ovlExt[] = {".b", ".o", ".ob"}; + Common::String buf = Common::String(_vm->_text->getScreenNames(screenNum)) + Common::String(ovlExt[overlayType]); if (!Common::File::exists(buf)) { memset(image, 0, kOvlSize); @@ -70,7 +70,7 @@ void FileManager_v1d::readOverlay(const int screenNum, image_pt image, const ovl if (!_sceneryArchive1.open(buf)) error("File not found: %s", buf.c_str()); - image_pt tmpImage = image; // temp ptr to overlay file + ImagePtr tmpImage = image; // temp ptr to overlay file _sceneryArchive1.read(tmpImage, kOvlSize); _sceneryArchive1.close(); @@ -87,7 +87,7 @@ void FileManager_v1d::readBackground(const int screenIndex) { if (!_sceneryArchive1.open(buf)) error("File not found: %s", buf.c_str()); // Read the image into dummy seq and static dib_a - seq_t *dummySeq; // Image sequence structure for Read_pcx + Seq *dummySeq; // Image sequence structure for Read_pcx dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); free(dummySeq); _sceneryArchive1.close(); diff --git a/engines/hugo/file_v1w.cpp b/engines/hugo/file_v1w.cpp index fba13d6915..002a1dc103 100644 --- a/engines/hugo/file_v1w.cpp +++ b/engines/hugo/file_v1w.cpp @@ -45,13 +45,13 @@ FileManager_v1w::~FileManager_v1w() { /** * Open and read in an overlay file, close file */ -void FileManager_v1w::readOverlay(const int screenNum, image_pt image, ovl_t overlayType) { +void FileManager_v1w::readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) { debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); - image_pt tmpImage = image; // temp ptr to overlay file - _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); + ImagePtr tmpImage = image; // temp ptr to overlay file + _sceneryArchive1.seek((uint32)screenNum * sizeof(SceneBlock), SEEK_SET); - sceneBlock_t sceneBlock; // Database header entry + SceneBlock sceneBlock; // Database header entry sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp index 7239e5174a..19c90980b0 100644 --- a/engines/hugo/file_v2d.cpp +++ b/engines/hugo/file_v2d.cpp @@ -78,9 +78,9 @@ void FileManager_v2d::closeDatabaseFiles() { void FileManager_v2d::readBackground(const int screenIndex) { debugC(1, kDebugFile, "readBackground(%d)", screenIndex); - _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); + _sceneryArchive1.seek((uint32) screenIndex * sizeof(SceneBlock), SEEK_SET); - sceneBlock_t sceneBlock; // Read a database header entry + SceneBlock sceneBlock; // Read a database header entry sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); @@ -93,7 +93,7 @@ void FileManager_v2d::readBackground(const int screenIndex) { _sceneryArchive1.seek(sceneBlock._sceneOffset, SEEK_SET); // Read the image into dummy seq and static dib_a - seq_t *dummySeq; // Image sequence structure for Read_pcx + Seq *dummySeq; // Image sequence structure for Read_pcx dummySeq = readPCX(_sceneryArchive1, 0, _vm->_screen->getFrontBuffer(), true, _vm->_text->getScreenNames(screenIndex)); free(dummySeq); } @@ -101,13 +101,13 @@ void FileManager_v2d::readBackground(const int screenIndex) { /** * Open and read in an overlay file, close file */ -void FileManager_v2d::readOverlay(const int screenNum, image_pt image, ovl_t overlayType) { +void FileManager_v2d::readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) { debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); - image_pt tmpImage = image; // temp ptr to overlay file - _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); + ImagePtr tmpImage = image; // temp ptr to overlay file + _sceneryArchive1.seek((uint32)screenNum * sizeof(SceneBlock), SEEK_SET); - sceneBlock_t sceneBlock; // Database header entry + SceneBlock sceneBlock; // Database header entry sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp index 34c745efb6..5eb0cfc2c8 100644 --- a/engines/hugo/file_v3d.cpp +++ b/engines/hugo/file_v3d.cpp @@ -50,9 +50,9 @@ FileManager_v3d::~FileManager_v3d() { void FileManager_v3d::readBackground(const int screenIndex) { debugC(1, kDebugFile, "readBackground(%d)", screenIndex); - _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); + _sceneryArchive1.seek((uint32) screenIndex * sizeof(SceneBlock), SEEK_SET); - sceneBlock_t sceneBlock; // Read a database header entry + SceneBlock sceneBlock; // Read a database header entry sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); @@ -62,7 +62,7 @@ void FileManager_v3d::readBackground(const int screenIndex) { sceneBlock._baseOffset = _sceneryArchive1.readUint32LE(); sceneBlock._baseLength = _sceneryArchive1.readUint32LE(); - seq_t *dummySeq; // Image sequence structure for Read_pcx + Seq *dummySeq; // Image sequence structure for Read_pcx if (screenIndex < 20) { _sceneryArchive1.seek(sceneBlock._sceneOffset, SEEK_SET); // Read the image into dummy seq and static dib_a @@ -106,13 +106,13 @@ void FileManager_v3d::closeDatabaseFiles() { /** * Open and read in an overlay file, close file */ -void FileManager_v3d::readOverlay(const int screenNum, image_pt image, ovl_t overlayType) { +void FileManager_v3d::readOverlay(const int screenNum, ImagePtr image, OvlType overlayType) { debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); - image_pt tmpImage = image; // temp ptr to overlay file - _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); + ImagePtr tmpImage = image; // temp ptr to overlay file + _sceneryArchive1.seek((uint32)screenNum * sizeof(SceneBlock), SEEK_SET); - sceneBlock_t sceneBlock; // Database header entry + SceneBlock sceneBlock; // Database header entry sceneBlock._sceneOffset = _sceneryArchive1.readUint32LE(); sceneBlock._sceneLength = _sceneryArchive1.readUint32LE(); sceneBlock._boundaryOffset = _sceneryArchive1.readUint32LE(); diff --git a/engines/hugo/game.h b/engines/hugo/game.h index ab5e2dff56..29e3bf9b55 100644 --- a/engines/hugo/game.h +++ b/engines/hugo/game.h @@ -45,7 +45,7 @@ namespace Hugo { enum {LOOK_NAME = 1, TAKE_NAME}; // Index of name used in showing takeables and in confirming take // Definitions of 'generic' commands: Max # depends on size of gencmd in -// the object_t record since each requires 1 bit. Currently up to 16 +// the Object record since each requires 1 bit. Currently up to 16 enum {LOOK = 1, TAKE = 2, DROP = 4, LOOK_S = 8}; enum TEXTCOLORS { @@ -55,25 +55,25 @@ enum TEXTCOLORS { _TLIGHTRED, _TLIGHTMAGENTA, _TLIGHTYELLOW, _TBRIGHTWHITE }; -enum uif_t {U_FONT5, U_FONT6, U_FONT8, UIF_IMAGES, NUM_UIF_ITEMS}; +enum Uif {U_FONT5, U_FONT6, U_FONT8, UIF_IMAGES, NUM_UIF_ITEMS}; static const int kFirstFont = U_FONT5; /** * Enumerate ways of cycling a sequence of frames */ -enum cycle_t {kCycleInvisible, kCycleAlmostInvisible, kCycleNotCycling, kCycleForward, kCycleBackward}; +enum Cycle {kCycleInvisible, kCycleAlmostInvisible, kCycleNotCycling, kCycleForward, kCycleBackward}; /** * Enumerate sequence index matching direction of travel */ enum {SEQ_RIGHT, SEQ_LEFT, SEQ_DOWN, SEQ_UP}; -enum font_t {LARGE_ROMAN, MED_ROMAN, NUM_GDI_FONTS, INIT_FONTS, DEL_FONTS}; +enum Font {LARGE_ROMAN, MED_ROMAN, NUM_GDI_FONTS, INIT_FONTS, DEL_FONTS}; /** * Enumerate the different path types for an object */ -enum path_t { +enum Path { kPathUser, // User has control of object via cursor keys kPathAuto, // Computer has control, controlled by action lists kPathQuiet, // Computer has control and no commands allowed @@ -83,7 +83,7 @@ enum path_t { kPathWander2 // Same as WANDER, except keeps cycling when stationary }; -struct hugo_boot_t { // Common HUGO boot file +struct hugoBoot { // Common HUGO boot file char _checksum; // Checksum for boot structure (not exit text) char _registered; // TRUE if registered version, else FALSE char _pbswitch[8]; // Playback switch string @@ -94,13 +94,13 @@ struct hugo_boot_t { // Common HUGO boot file /** * Game specific type definitions */ -typedef byte *image_pt; // ptr to an object image (sprite) +typedef byte *ImagePtr; // ptr to an object image (sprite) typedef byte *sound_pt; // ptr to sound (or music) data /** * Structure for initializing maze processing */ -struct maze_t { +struct Maze { bool _enabledFl; // TRUE when maze processing enabled byte _size; // Size of (square) maze matrix int _x1, _y1, _x2, _y2; // maze hotspot bounding box @@ -112,24 +112,24 @@ struct maze_t { * The following is a linked list of images in an animation sequence * The image data is in 8-bit DIB format, i.e. 1 byte = 1 pixel */ -struct seq_t { // Linked list of images +struct Seq { // Linked list of images byte *_imagePtr; // ptr to image uint16 _bytesPerLine8; // bytes per line (8bits) uint16 _lines; // lines uint16 _x1, _x2, _y1, _y2; // Offsets from x,y: data bounding box - seq_t *_nextSeqPtr; // ptr to next record + Seq *_nextSeqPtr; // ptr to next record }; /** * The following is an array of structures of above sequences */ -struct seqList_t { +struct SeqList { uint16 _imageNbr; // Number of images in sequence - seq_t *_seqPtr; // Ptr to sequence structure + Seq *_seqPtr; // Ptr to sequence structure }; #include "common/pack-start.h" // START STRUCT PACKING -struct sound_hdr_t { // Sound file lookup entry +struct SoundHdr { // Sound file lookup entry uint16 _size; // Size of sound data in bytes uint32 _offset; // Offset of sound data in file } PACKED_STRUCT; @@ -140,17 +140,17 @@ static const int kMaxSeqNumb = 4; // Number of sequences of im /** * Following is definition of object attributes */ -struct object_t { +struct Object { uint16 _nounIndex; // String identifying object uint16 _dataIndex; // String describing the object - uint16 *_stateDataIndex; // Added by Strangerke to handle the LOOK_S state-dependant descriptions - path_t _pathType; // Describe path object follows + uint16 *_stateDataIndex; // Added by Strangerke to handle the LOOK_S state-dependant descriptions + Path _pathType; // Describe path object follows int _vxPath, _vyPath; // Delta velocities (e.g. for CHASE) uint16 _actIndex; // Action list to do on collision with hero byte _seqNumb; // Number of sequences in list - seq_t *_currImagePtr; // Sequence image currently in use - seqList_t _seqList[kMaxSeqNumb]; // Array of sequence structure ptrs and lengths - cycle_t _cycling; // Whether cycling, forward or backward + Seq *_currImagePtr; // Sequence image currently in use + SeqList _seqList[kMaxSeqNumb]; // Array of sequence structure ptrs and lengths + Cycle _cycling; // Whether cycling, forward or backward byte _cycleNumb; // No. of times to cycle byte _frameInterval; // Interval (in ticks) between frames byte _frameTimer; // Decrementing timer for above diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index 7462da0df8..5ae43b8b5a 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -106,7 +106,7 @@ GUI::Debugger *HugoEngine::getDebugger() { return _console; } -status_t &HugoEngine::getGameStatus() { +Status &HugoEngine::getGameStatus() { return _status; } @@ -323,7 +323,7 @@ void HugoEngine::initMachine() { * Hugo game state machine - called during onIdle */ void HugoEngine::runMachine() { - status_t &gameStatus = getGameStatus(); + Status &gameStatus = getGameStatus(); // Don't process if gameover if (gameStatus._gameOverFl) @@ -639,10 +639,10 @@ void HugoEngine::readScreenFiles(const int screenNum) { memcpy(_screen->getBackBuffer(), _screen->getFrontBuffer(), sizeof(_screen->getFrontBuffer())); // Make a copy // Workaround for graphic glitches in DOS versions. Cleaning the overlays fix the problem - memset(_object->_objBound, '\0', sizeof(overlay_t)); - memset(_object->_boundary, '\0', sizeof(overlay_t)); - memset(_object->_overlay, '\0', sizeof(overlay_t)); - memset(_object->_ovlBase, '\0', sizeof(overlay_t)); + memset(_object->_objBound, '\0', sizeof(Overlay)); + memset(_object->_boundary, '\0', sizeof(Overlay)); + memset(_object->_overlay, '\0', sizeof(Overlay)); + memset(_object->_ovlBase, '\0', sizeof(Overlay)); _file->readOverlay(screenNum, _object->_boundary, kOvlBoundary); // Boundary file _file->readOverlay(screenNum, _object->_overlay, kOvlOverlay); // Overlay file diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 68b771faa4..312f2272db 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -80,18 +80,18 @@ static const int kMaxPath = 256; // Max length of a full path static const int kHeroMaxWidth = 24; // Maximum width of hero static const int kHeroMinWidth = 16; // Minimum width of hero -typedef char command_t[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor) +typedef char Command[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor) -struct config_t { // User's config (saved) - bool _musicFl; // State of Music button/menu item - bool _soundFl; // State of Sound button/menu item - bool _turboFl; // State of Turbo button/menu item - bool _playlist[kMaxTunes]; // Tune playlist +struct Config { // User's config (saved) + bool _musicFl; // State of Music button/menu item + bool _soundFl; // State of Sound button/menu item + bool _turboFl; // State of Turbo button/menu item + bool _playlist[kMaxTunes]; // Tune playlist }; -typedef byte icondib_t[kXPix * kInvDy]; // Icon bar dib -typedef byte viewdib_t[(long)kXPix * kYPix]; // Viewport dib -typedef byte overlay_t[kOvlSize]; // Overlay file +typedef byte Icondib[kXPix * kInvDy]; // Icon bar dib +typedef byte Viewdib[(long)kXPix * kYPix]; // Viewport dib +typedef byte Overlay[kOvlSize]; // Overlay file enum GameType { kGameTypeNone = 0, @@ -131,12 +131,12 @@ enum HugoRegistered { /** * Inventory icon bar states */ -enum istate_t {kInventoryOff, kInventoryUp, kInventoryDown, kInventoryActive}; +enum Istate {kInventoryOff, kInventoryUp, kInventoryDown, kInventoryActive}; /** * Game view state machine */ -enum vstate_t {kViewIdle, kViewIntroInit, kViewIntro, kViewPlay, kViewInvent, kViewExit}; +enum Vstate {kViewIdle, kViewIntroInit, kViewIntro, kViewPlay, kViewInvent, kViewExit}; /** * Enumerate whether object is foreground, background or 'floating' @@ -152,12 +152,12 @@ enum {kPriorityForeground, kPriorityBackground, kPriorityFloating, kPriorityOver /** * Display list functions */ -enum dupdate_t {kDisplayInit, kDisplayAdd, kDisplayDisplay, kDisplayRestore}; +enum Dupdate {kDisplayInit, kDisplayAdd, kDisplayDisplay, kDisplayRestore}; /** * Priority for sound effect */ -enum priority_t {kSoundPriorityLow, kSoundPriorityMedium, kSoundPriorityHigh}; +enum Priority {kSoundPriorityLow, kSoundPriorityMedium, kSoundPriorityHigh}; enum HugoGameFeatures { GF_PACKED = (1 << 0) // Database @@ -170,27 +170,27 @@ enum seqTextEngine { struct HugoGameDescription; -struct status_t { // Game status (not saved) - bool _storyModeFl; // Game is telling story - no commands - bool _gameOverFl; // Game is over - hero knobbled - bool _lookFl; // Toolbar "look" button pressed - bool _recallFl; // Toolbar "recall" button pressed - bool _newScreenFl; // New screen just loaded in dib_a - bool _godModeFl; // Allow DEBUG features in live version - bool _showBoundariesFl; // Flag used to show and hide boundaries, +struct Status { // Game status (not saved) + bool _storyModeFl; // Game is telling story - no commands + bool _gameOverFl; // Game is over - hero knobbled + bool _lookFl; // Toolbar "look" button pressed + bool _recallFl; // Toolbar "recall" button pressed + bool _newScreenFl; // New screen just loaded in dib_a + bool _godModeFl; // Allow DEBUG features in live version + bool _showBoundariesFl; // Flag used to show and hide boundaries, // used by the console bool _doQuitFl; bool _skipIntroFl; bool _helpFl; - uint32 _tick; // Current time in ticks - vstate_t _viewState; // View state machine - int16 _song; // Current song + uint32 _tick; // Current time in ticks + Vstate _viewState; // View state machine + int16 _song; // Current song }; /** * Structure to define an EXIT or other collision-activated hotspot */ -struct hotspot_t { +struct Hotspot { int _screenIndex; // Screen in which hotspot appears int _x1, _y1, _x2, _y2; // Bounding box of hotspot uint16 _actIndex; // Actions to carry out if a 'hit' @@ -225,19 +225,19 @@ public: uint16 _numStates; int8 _normalTPS; // Number of ticks (frames) per second. // 8 for Win versions, 9 for DOS versions - object_t *_hero; + Object *_hero; byte *_screen_p; byte _heroImage; byte *_screenStates; - command_t _line; // Line of user text input - config_t _config; // User's config + Command _line; // Line of user text input + Config _config; // User's config int16 *_defltTunes; uint16 _look; uint16 _take; uint16 _drop; - maze_t _maze; // Maze control structure - hugo_boot_t _boot; // Boot info structure + Maze _maze; // Maze control structure + hugoBoot _boot; // Boot info structure GUI::Debugger *getDebugger(); @@ -246,8 +246,8 @@ public: const char *_episode; Common::String _picDir; - command_t _statusLine; - command_t _scoreLine; + Command _statusLine; + Command _scoreLine; const HugoGameDescription *_gameDescription; uint32 getFeatures() const; @@ -279,7 +279,7 @@ public: void shutdown(); void syncSoundSettings(); - status_t &getGameStatus(); + Status &getGameStatus(); int getScore() const; void setScore(const int newScore); void adjustScore(const int adjustment); @@ -314,7 +314,7 @@ protected: private: static const int kTurboTps = 16; // This many in turbo mode - status_t _status; // Game status structure + Status _status; // Game status structure uint32 _lastTime; uint32 _curTime; diff --git a/engines/hugo/inventory.cpp b/engines/hugo/inventory.cpp index 151fe0ee13..c2495beadb 100644 --- a/engines/hugo/inventory.cpp +++ b/engines/hugo/inventory.cpp @@ -56,7 +56,7 @@ void InventoryHandler::setInventoryObjId(int16 objId) { _inventoryObjId = objId; } -void InventoryHandler::setInventoryState(istate_t state) { +void InventoryHandler::setInventoryState(Istate state) { _inventoryState = state; } @@ -68,7 +68,7 @@ int16 InventoryHandler::getInventoryObjId() const { return _inventoryObjId; } -istate_t InventoryHandler::getInventoryState() const { +Istate InventoryHandler::getInventoryState() const { return _inventoryState; } @@ -137,8 +137,8 @@ void InventoryHandler::constructInventory(const int16 imageTotNumb, int displayN * Process required action for inventory * Returns objId under cursor (or -1) for INV_GET */ -int16 InventoryHandler::processInventory(const invact_t action, ...) { - debugC(1, kDebugInventory, "processInventory(invact_t action, ...)"); +int16 InventoryHandler::processInventory(const InvAct action, ...) { + debugC(1, kDebugInventory, "processInventory(InvAct action, ...)"); int16 imageNumb; // Total number of inventory items int displayNumb; // Total number displayed/carried @@ -208,7 +208,7 @@ int16 InventoryHandler::processInventory(const invact_t action, ...) { * Process inventory state machine */ void InventoryHandler::runInventory() { - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); debugC(1, kDebugInventory, "runInventory"); diff --git a/engines/hugo/inventory.h b/engines/hugo/inventory.h index 666cc37b51..5b55c3ec94 100644 --- a/engines/hugo/inventory.h +++ b/engines/hugo/inventory.h @@ -34,22 +34,22 @@ namespace Hugo { /** * Actions for Process_inventory() */ -enum invact_t {kInventoryActionInit, kInventoryActionLeft, kInventoryActionRight, kInventoryActionGet}; +enum InvAct {kInventoryActionInit, kInventoryActionLeft, kInventoryActionRight, kInventoryActionGet}; class InventoryHandler { public: InventoryHandler(HugoEngine *vm); void setInventoryObjId(int16 objId); - void setInventoryState(istate_t state); + void setInventoryState(Istate state); void freeInvent(); int16 getInventoryObjId() const; - istate_t getInventoryState() const; + Istate getInventoryState() const; int16 findIconId(int16 objId); void loadInvent(Common::SeekableReadStream &in); - int16 processInventory(const invact_t action, ...); + int16 processInventory(const InvAct action, ...); void runInventory(); private: @@ -59,7 +59,7 @@ private: int16 _firstIconId; // Index of first icon to display int16 *_invent; - istate_t _inventoryState; // Inventory icon bar state + Istate _inventoryState; // Inventory icon bar state int16 _inventoryHeight; // Inventory icon bar height int16 _inventoryObjId; // Inventory object selected, or -1 byte _maxInvent; diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index 864934a0d3..fef3cca608 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -108,7 +108,7 @@ int16 MouseHandler::getHotspotActIndex(const int16 hotspotId) const { /** * Shadow-blit supplied string into dib_a at cx,cy and add to display list */ -void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color) { +void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy, const Uif fontId, const int16 color) { debugC(1, kDebugMouse, "cursorText(%s, %d, %d, %d, %d)", buffer, cx, cy, fontId, color); _vm->_screen->loadFont(fontId); @@ -152,7 +152,7 @@ int16 MouseHandler::findExit(const int16 cx, const int16 cy, byte screenId) { void MouseHandler::processRightClick(const int16 objId, const int16 cx, const int16 cy) { debugC(1, kDebugMouse, "ProcessRightClick(%d, %d, %d)", objId, cx, cy); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control return; @@ -168,7 +168,7 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in else _vm->_object->useObject(objId); // Use status.objid on object } else { // Clicked over viewport object - object_t *obj = &_vm->_object->_objects[objId]; + Object *obj = &_vm->_object->_objects[objId]; int16 x, y; switch (obj->_viewx) { // Where to walk to case -1: // Walk to object position @@ -203,9 +203,9 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int debugC(1, kDebugMouse, "ProcessLeftClick(%d, %d, %d)", objId, cx, cy); int16 i, x, y; - object_t *obj; + Object *obj; - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); if (gameStatus._storyModeFl || _vm->_hero->_pathType == kPathQuiet) // Make sure user has control return; @@ -284,8 +284,8 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int void MouseHandler::mouseHandler() { debugC(2, kDebugMouse, "mouseHandler"); - status_t &gameStatus = _vm->getGameStatus(); - istate_t inventState = _vm->_inventory->getInventoryState(); + Status &gameStatus = _vm->getGameStatus(); + Istate inventState = _vm->_inventory->getInventoryState(); if ((gameStatus._viewState != kViewPlay) && (inventState != kInventoryActive)) return; @@ -343,7 +343,7 @@ void MouseHandler::mouseHandler() { resetRightButton(); } -void MouseHandler::readHotspot(Common::ReadStream &in, hotspot_t &hotspot) { +void MouseHandler::readHotspot(Common::ReadStream &in, Hotspot &hotspot) { hotspot._screenIndex = in.readSint16BE(); hotspot._x1 = in.readSint16BE(); hotspot._y1 = in.readSint16BE(); @@ -359,13 +359,13 @@ void MouseHandler::readHotspot(Common::ReadStream &in, hotspot_t &hotspot) { * Load hotspots data from hugo.dat */ void MouseHandler::loadHotspots(Common::ReadStream &in) { - hotspot_t *wrkHotspots = 0; - hotspot_t tmp; + Hotspot *wrkHotspots = 0; + Hotspot tmp; memset(&tmp, 0, sizeof(tmp)); for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { int numRows = in.readUint16BE(); if (varnt == _vm->_gameVariant) - _hotspots = wrkHotspots = (hotspot_t *)malloc(sizeof(hotspot_t) * numRows); + _hotspots = wrkHotspots = (Hotspot *)malloc(sizeof(Hotspot) * numRows); for (int i = 0; i < numRows; i++) readHotspot(in, (varnt == _vm->_gameVariant) ? wrkHotspots[i] : tmp); @@ -377,7 +377,7 @@ void MouseHandler::loadHotspots(Common::ReadStream &in) { */ void MouseHandler::drawHotspots() const { for (int i = 0; _hotspots[i]._screenIndex >= 0; i++) { - hotspot_t *hotspot = &_hotspots[i]; + Hotspot *hotspot = &_hotspots[i]; if (hotspot->_screenIndex == _vm->_hero->_screenIndex) _vm->_screen->drawRectangle(false, hotspot->_x1, hotspot->_y1, hotspot->_x2, hotspot->_y2, _TLIGHTRED); } diff --git a/engines/hugo/mouse.h b/engines/hugo/mouse.h index 35f9e4e87e..e20716f72c 100644 --- a/engines/hugo/mouse.h +++ b/engines/hugo/mouse.h @@ -70,17 +70,17 @@ private: kMsExit = 1 }; - hotspot_t *_hotspots; + Hotspot *_hotspots; bool _leftButtonFl; // Left mouse button pressed bool _rightButtonFl; // Right button pressed int _mouseX; int _mouseY; bool _jumpExitFl; // Allowed to jump to a screen exit - void cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color); + void cursorText(const char *buffer, const int16 cx, const int16 cy, const Uif fontId, const int16 color); void processRightClick(const int16 objId, const int16 cx, const int16 cy); void processLeftClick(const int16 objId, const int16 cx, const int16 cy); - void readHotspot(Common::ReadStream &in, hotspot_t &hotspot); + void readHotspot(Common::ReadStream &in, Hotspot &hotspot); }; } // End of namespace Hugo diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp index 92a04227d6..e0dd0abd49 100644 --- a/engines/hugo/object.cpp +++ b/engines/hugo/object.cpp @@ -48,10 +48,10 @@ ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0), _uses(0) { _numObj = 0; _objCount = 0; _usesSize = 0; - memset(_objBound, '\0', sizeof(overlay_t)); - memset(_boundary, '\0', sizeof(overlay_t)); - memset(_overlay, '\0', sizeof(overlay_t)); - memset(_ovlBase, '\0', sizeof(overlay_t)); + memset(_objBound, '\0', sizeof(Overlay)); + memset(_boundary, '\0', sizeof(Overlay)); + memset(_overlay, '\0', sizeof(Overlay)); + memset(_ovlBase, '\0', sizeof(Overlay)); } ObjectHandler::~ObjectHandler() { @@ -86,7 +86,7 @@ void ObjectHandler::setVelocity(int objIndex, int8 vx, int8 vy) { _objects[objIndex]._vy = vy; } -void ObjectHandler::setPath(int objIndex, path_t pathType, int16 vxPath, int16 vyPath) { +void ObjectHandler::setPath(int objIndex, Path pathType, int16 vxPath, int16 vyPath) { _objects[objIndex]._pathType = pathType; _objects[objIndex]._vxPath = vxPath; _objects[objIndex]._vyPath = vyPath; @@ -95,12 +95,12 @@ void ObjectHandler::setPath(int objIndex, path_t pathType, int16 vxPath, int16 v /** * Save sequence number and image number in given object */ -void ObjectHandler::saveSeq(object_t *obj) { +void ObjectHandler::saveSeq(Object *obj) { debugC(1, kDebugObject, "saveSeq"); bool found = false; for (int i = 0; !found && (i < obj->_seqNumb); i++) { - seq_t *q = obj->_seqList[i]._seqPtr; + Seq *q = obj->_seqList[i]._seqPtr; for (int j = 0; !found && (j < obj->_seqList[i]._imageNbr); j++) { if (obj->_currImagePtr == q) { found = true; @@ -114,12 +114,12 @@ void ObjectHandler::saveSeq(object_t *obj) { } /** - * Set up cur_seq_p from stored sequence and image number in object + * Set up cur_seqPtr from stored sequence and image number in object */ -void ObjectHandler::restoreSeq(object_t *obj) { +void ObjectHandler::restoreSeq(Object *obj) { debugC(1, kDebugObject, "restoreSeq"); - seq_t *q = obj->_seqList[obj->_curSeqNum]._seqPtr; + Seq *q = obj->_seqList[obj->_curSeqNum]._seqPtr; for (int j = 0; j < obj->_curImageNum; j++) q = q->_nextSeqPtr; obj->_currImagePtr = q; @@ -134,7 +134,7 @@ void ObjectHandler::useObject(int16 objId) { const char *verb; // Background verb to use directly int16 inventObjId = _vm->_inventory->getInventoryObjId(); - object_t *obj = &_objects[objId]; // Ptr to object + Object *obj = &_objects[objId]; // Ptr to object if (inventObjId == -1) { // Get or use objid directly if ((obj->_genericCmd & TAKE) || obj->_objValue) // Get collectible item @@ -153,12 +153,12 @@ void ObjectHandler::useObject(int16 objId) { _vm->_text->getNoun(obj->_nounIndex, 0)); // Check valid use of objects and override verb if necessary - for (uses_t *use = _uses; use->_objId != _numObj; use++) { + for (Uses *use = _uses; use->_objId != _numObj; use++) { if (inventObjId == use->_objId) { // Look for secondary object, if found use matching verb bool foundFl = false; - for (target_t *target = use->_targets; target->_nounIndex != 0; target++) + for (Target *target = use->_targets; target->_nounIndex != 0; target++) if (target->_nounIndex == obj->_nounIndex) { foundFl = true; sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->_verbIndex, 0), @@ -195,12 +195,12 @@ int16 ObjectHandler::findObject(uint16 x, uint16 y) { int16 objIndex = -1; // Index of found object uint16 y2Max = 0; // Greatest y2 - object_t *obj = _objects; + Object *obj = _objects; // Check objects on screen for (int i = 0; i < _numObj; i++, obj++) { // Object must be in current screen and "useful" if (obj->_screenIndex == *_vm->_screen_p && (obj->_genericCmd || obj->_objValue || obj->_cmdIndex)) { - seq_t *curImage = obj->_currImagePtr; + Seq *curImage = obj->_currImagePtr; // Object must have a visible image... if (curImage != 0 && obj->_cycling != kCycleInvisible) { // If cursor inside object @@ -233,7 +233,7 @@ int16 ObjectHandler::findObject(uint16 x, uint16 y) { * Issue "Look at " command * Note special case of swapped hero image */ -void ObjectHandler::lookObject(object_t *obj) { +void ObjectHandler::lookObject(Object *obj) { debugC(1, kDebugObject, "lookObject"); if (obj == _vm->_hero) @@ -252,10 +252,10 @@ void ObjectHandler::freeObjects() { if (_vm->_hero != 0 && _vm->_hero->_seqList[0]._seqPtr != 0) { // Free all sequence lists and image data for (int16 i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; + Object *obj = &_objects[i]; for (int16 j = 0; j < obj->_seqNumb; j++) { - seq_t *seq = obj->_seqList[j]._seqPtr; - seq_t *next; + Seq *seq = obj->_seqList[j]._seqPtr; + Seq *next; if (seq == 0) // Failure during database load break; if (seq->_imagePtr != 0) { @@ -300,8 +300,8 @@ void ObjectHandler::freeObjects() { int ObjectHandler::y2comp(const void *a, const void *b) { debugC(6, kDebugObject, "y2comp"); - const object_t *p1 = &HugoEngine::get()._object->_objects[*(const byte *)a]; - const object_t *p2 = &HugoEngine::get()._object->_objects[*(const byte *)b]; + const Object *p1 = &HugoEngine::get()._object->_objects[*(const byte *)a]; + const Object *p2 = &HugoEngine::get()._object->_objects[*(const byte *)b]; if (p1 == p2) // Why does qsort try the same indexes? @@ -345,7 +345,7 @@ void ObjectHandler::showTakeables() { debugC(1, kDebugObject, "showTakeables"); for (int j = 0; j < _numObj; j++) { - object_t *obj = &_objects[j]; + Object *obj = &_objects[j]; if ((obj->_cycling != kCycleInvisible) && (obj->_screenIndex == *_vm->_screen_p) && (((TAKE & obj->_genericCmd) == TAKE) || obj->_objValue)) { @@ -357,10 +357,10 @@ void ObjectHandler::showTakeables() { /** * Find a clear space around supplied object that hero can walk to */ -bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { +bool ObjectHandler::findObjectSpace(Object *obj, int16 *destx, int16 *desty) { debugC(1, kDebugObject, "findObjectSpace(obj, %d, %d)", *destx, *desty); - seq_t *curImage = obj->_currImagePtr; + Seq *curImage = obj->_currImagePtr; int16 y = obj->_y + curImage->_y2 - 1; bool foundFl = true; @@ -399,11 +399,11 @@ bool ObjectHandler::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { return foundFl; } -void ObjectHandler::readUse(Common::ReadStream &in, uses_t &curUse) { +void ObjectHandler::readUse(Common::ReadStream &in, Uses &curUse) { curUse._objId = in.readSint16BE(); curUse._dataIndex = in.readUint16BE(); uint16 numSubElem = in.readUint16BE(); - curUse._targets = (target_t *)malloc(sizeof(target_t) * numSubElem); + curUse._targets = (Target *)malloc(sizeof(Target) * numSubElem); for (int j = 0; j < numSubElem; j++) { curUse._targets[j]._nounIndex = in.readUint16BE(); curUse._targets[j]._verbIndex = in.readUint16BE(); @@ -413,7 +413,7 @@ void ObjectHandler::readUse(Common::ReadStream &in, uses_t &curUse) { * Load _uses from Hugo.dat */ void ObjectHandler::loadObjectUses(Common::ReadStream &in) { - uses_t tmpUse; + Uses tmpUse; tmpUse._targets = 0; //Read _uses @@ -421,7 +421,7 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) { uint16 numElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) { _usesSize = numElem; - _uses = (uses_t *)malloc(sizeof(uses_t) * numElem); + _uses = (Uses *)malloc(sizeof(Uses) * numElem); } for (int i = 0; i < numElem; i++) { @@ -436,7 +436,7 @@ void ObjectHandler::loadObjectUses(Common::ReadStream &in) { } } -void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) { +void ObjectHandler::readObject(Common::ReadStream &in, Object &curObject) { curObject._nounIndex = in.readUint16BE(); curObject._dataIndex = in.readUint16BE(); uint16 numSubElem = in.readUint16BE(); @@ -448,7 +448,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) { for (int j = 0; j < numSubElem; j++) curObject._stateDataIndex[j] = in.readUint16BE(); - curObject._pathType = (path_t) in.readSint16BE(); + curObject._pathType = (Path) in.readSint16BE(); curObject._vxPath = in.readSint16BE(); curObject._vyPath = in.readSint16BE(); curObject._actIndex = in.readUint16BE(); @@ -465,7 +465,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) { curObject._seqList[j]._seqPtr = 0; } - curObject._cycling = (cycle_t)in.readByte(); + curObject._cycling = (Cycle)in.readByte(); curObject._cycleNumb = in.readByte(); curObject._frameInterval = in.readByte(); curObject._frameTimer = in.readByte(); @@ -497,7 +497,7 @@ void ObjectHandler::readObject(Common::ReadStream &in, object_t &curObject) { */ void ObjectHandler::loadObjectArr(Common::ReadStream &in) { debugC(6, kDebugObject, "loadObject(&in)"); - object_t tmpObject; + Object tmpObject; tmpObject._stateDataIndex = 0; for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { @@ -505,7 +505,7 @@ void ObjectHandler::loadObjectArr(Common::ReadStream &in) { if (varnt == _vm->_gameVariant) { _objCount = numElem; - _objects = (object_t *)malloc(sizeof(object_t) * numElem); + _objects = (Object *)malloc(sizeof(Object) * numElem); } for (int i = 0; i < numElem; i++) { @@ -559,7 +559,7 @@ void ObjectHandler::restoreAllSeq() { */ void ObjectHandler::saveObjects(Common::WriteStream *out) { for (int i = 0; i < _numObj; i++) { - // Save where curr_seq_p is pointing to + // Save where curr_seqPtr is pointing to saveSeq(&_objects[i]); out->writeByte(_objects[i]._pathType); @@ -594,10 +594,10 @@ void ObjectHandler::saveObjects(Common::WriteStream *out) { */ void ObjectHandler::restoreObjects(Common::SeekableReadStream *in) { for (int i = 0; i < _numObj; i++) { - _objects[i]._pathType = (path_t) in->readByte(); + _objects[i]._pathType = (Path) in->readByte(); _objects[i]._vxPath = in->readSint16BE(); _objects[i]._vyPath = in->readSint16BE(); - _objects[i]._cycling = (cycle_t) in->readByte(); + _objects[i]._cycling = (Cycle) in->readByte(); _objects[i]._cycleNumb = in->readByte(); _objects[i]._frameTimer = in->readByte(); _objects[i]._screenIndex = in->readByte(); @@ -782,7 +782,7 @@ void ObjectHandler::clearScreenBoundary(const int x1, const int x2, const int y) /** * An object has collided with a boundary. See if any actions are required */ -void ObjectHandler::boundaryCollision(object_t *obj) { +void ObjectHandler::boundaryCollision(Object *obj) { debugC(1, kDebugEngine, "boundaryCollision"); if (obj == _vm->_hero) { diff --git a/engines/hugo/object.h b/engines/hugo/object.h index 8f8043dbbc..fd0d731a98 100644 --- a/engines/hugo/object.h +++ b/engines/hugo/object.h @@ -34,15 +34,15 @@ namespace Hugo { -struct target_t { // Secondary target for action +struct Target { // Secondary target for action uint16 _nounIndex; // Secondary object uint16 _verbIndex; // Action on secondary object }; -struct uses_t { // Define uses of certain objects +struct Uses { // Define uses of certain objects int16 _objId; // Primary object uint16 _dataIndex; // String if no secondary object matches - target_t *_targets; // List of secondary targets + Target *_targets; // List of secondary targets }; class ObjectHandler { @@ -50,12 +50,12 @@ public: ObjectHandler(HugoEngine *vm); virtual ~ObjectHandler(); - overlay_t _objBound; - overlay_t _boundary; // Boundary overlay file - overlay_t _overlay; // First overlay file - overlay_t _ovlBase; // First overlay base file + Overlay _objBound; + Overlay _boundary; // Boundary overlay file + Overlay _overlay; // First overlay file + Overlay _ovlBase; // First overlay base file - object_t *_objects; + Object *_objects; uint16 _numObj; byte getBoundaryOverlay(uint16 index) const; @@ -65,7 +65,7 @@ public: int deltaX(const int x1, const int x2, const int vx, int y) const; int deltaY(const int x1, const int x2, const int vy, const int y) const; - void boundaryCollision(object_t *obj); + void boundaryCollision(Object *obj); void clearBoundary(const int x1, const int x2, const int y); void clearScreenBoundary(const int x1, const int x2, const int y); void storeBoundary(const int x1, const int x2, const int y); @@ -76,7 +76,7 @@ public: virtual void swapImages(int objIndex1, int objIndex2) = 0; bool isCarrying(uint16 wordIndex); - bool findObjectSpace(object_t *obj, int16 *destx, int16 *desty); + bool findObjectSpace(Object *obj, int16 *destx, int16 *desty); int calcMaxScore(); int16 findObject(uint16 x, uint16 y); @@ -84,14 +84,14 @@ public: void loadObjectArr(Common::ReadStream &in); void loadObjectUses(Common::ReadStream &in); void loadNumObj(Common::ReadStream &in); - void lookObject(object_t *obj); + void lookObject(Object *obj); void readObjectImages(); - void readObject(Common::ReadStream &in, object_t &curObject); - void readUse(Common::ReadStream &in, uses_t &curUse); + void readObject(Common::ReadStream &in, Object &curObject); + void readUse(Common::ReadStream &in, Uses &curUse); void restoreAllSeq(); void restoreObjects(Common::SeekableReadStream *in); void saveObjects(Common::WriteStream *out); - void saveSeq(object_t *obj); + void saveSeq(Object *obj); void setCarriedScreen(int screenNum); void showTakeables(); void useObject(int16 objId); @@ -101,7 +101,7 @@ public: bool isCarried(int objIndex) const; void setCarry(int objIndex, bool val); void setVelocity(int objIndex, int8 vx, int8 vy); - void setPath(int objIndex, path_t pathType, int16 vxPath, int16 vyPath); + void setPath(int objIndex, Path pathType, int16 vxPath, int16 vyPath); protected: HugoEngine *_vm; @@ -110,11 +110,11 @@ protected: static const int kEdge2 = kEdge * 2; // Push object further back on edge collision static const int kMaxObjNumb = 128; // Used in Update_images() - uint16 _objCount; - uses_t *_uses; - uint16 _usesSize; + uint16 _objCount; + Uses *_uses; + uint16 _usesSize; - void restoreSeq(object_t *obj); + void restoreSeq(Object *obj); inline bool checkBoundary(int16 x, int16 y); template diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp index 7b8f90e189..e5fedb3b2a 100644 --- a/engines/hugo/object_v1d.cpp +++ b/engines/hugo/object_v1d.cpp @@ -59,21 +59,21 @@ void ObjectHandler_v1d::updateImages() { debugC(5, kDebugObject, "updateImages"); // Initialize the index array to visible objects in current screen - int num_objs = 0; + int objNumb = 0; byte objindex[kMaxObjNumb]; // Array of indeces to objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; + Object *obj = &_objects[i]; if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) - objindex[num_objs++] = i; + objindex[objNumb++] = i; } // Sort the objects into increasing y+y2 (painter's algorithm) - qsort(objindex, num_objs, sizeof(objindex[0]), y2comp); + qsort(objindex, objNumb, sizeof(objindex[0]), y2comp); // Add each visible object to display list - for (int i = 0; i < num_objs; i++) { - object_t *obj = &_objects[objindex[i]]; + for (int i = 0; i < objNumb; i++) { + Object *obj = &_objects[objindex[i]]; // Count down inter-frame timer if (obj->_frameTimer) obj->_frameTimer--; @@ -90,7 +90,7 @@ void ObjectHandler_v1d::updateImages() { _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, false); break; case kCycleBackward: { - seq_t *seqPtr = obj->_currImagePtr; + Seq *seqPtr = obj->_currImagePtr; if (!obj->_frameTimer) { // Show next frame while (seqPtr->_nextSeqPtr != obj->_currImagePtr) seqPtr = seqPtr->_nextSeqPtr; @@ -107,8 +107,8 @@ void ObjectHandler_v1d::updateImages() { _vm->_scheduler->waitForRefresh(); // Cycle any animating objects - for (int i = 0; i < num_objs; i++) { - object_t *obj = &_objects[objindex[i]]; + for (int i = 0; i < objNumb; i++) { + Object *obj = &_objects[objindex[i]]; if (obj->_cycling != kCycleInvisible) { // Only if it's visible if (obj->_cycling == kCycleAlmostInvisible) @@ -140,7 +140,7 @@ void ObjectHandler_v1d::updateImages() { case kCycleBackward: { if (!obj->_frameTimer) { // Time to step to prev frame - seq_t *seqPtr = obj->_currImagePtr; + Seq *seqPtr = obj->_currImagePtr; while (obj->_currImagePtr->_nextSeqPtr != seqPtr) obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is first frame of sequence @@ -183,8 +183,8 @@ void ObjectHandler_v1d::moveObjects() { // and store all (visible) object baselines into the boundary file. // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if (obj->_screenIndex == *_vm->_screen_p) { switch (obj->_pathType) { case kPathChase: { @@ -271,13 +271,13 @@ void ObjectHandler_v1d::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object + Object *obj = &_objects[i]; // Get pointer to object if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Seq *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates int x1 = obj->_x + currImage->_x1; // Left edge of object int x2 = obj->_x + currImage->_x2; // Right edge @@ -325,15 +325,15 @@ void ObjectHandler_v1d::moveObjects() { // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing if (_vm->_maze._enabledFl) { - seq_t *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image + Seq *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image // hero coordinates int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object int x2 = _vm->_hero->_x + currImage->_x2; // Right edge @@ -352,8 +352,8 @@ void ObjectHandler_v1d::moveObjects() { void ObjectHandler_v1d::swapImages(int objIndex1, int objIndex2) { debugC(1, kDebugObject, "swapImages(%d, %d)", objIndex1, objIndex2); - seqList_t tmpSeqList[kMaxSeqNumb]; - int seqListSize = sizeof(seqList_t) * kMaxSeqNumb; + SeqList tmpSeqList[kMaxSeqNumb]; + int seqListSize = sizeof(SeqList) * kMaxSeqNumb; memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize); memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize); @@ -365,8 +365,8 @@ void ObjectHandler_v1d::swapImages(int objIndex1, int objIndex2) { void ObjectHandler_v1d::homeIn(int objIndex1, const int objIndex2, const int8 objDx, const int8 objDy) { // object obj1 will home in on object obj2 - object_t *obj1 = &_objects[objIndex1]; - object_t *obj2 = &_objects[objIndex2]; + Object *obj1 = &_objects[objIndex1]; + Object *obj2 = &_objects[objIndex2]; obj1->_pathType = kPathAuto; int dx = obj1->_x + obj1->_currImagePtr->_x1 - obj2->_x - obj2->_currImagePtr->_x1; int dy = obj1->_y + obj1->_currImagePtr->_y1 - obj2->_y - obj2->_currImagePtr->_y1; diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp index dd3de5fe40..e1e8496d9d 100644 --- a/engines/hugo/object_v1w.cpp +++ b/engines/hugo/object_v1w.cpp @@ -59,21 +59,21 @@ void ObjectHandler_v1w::updateImages() { debugC(5, kDebugObject, "updateImages"); // Initialize the index array to visible objects in current screen - int num_objs = 0; + int objNumb = 0; byte objindex[kMaxObjNumb]; // Array of indeces to objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; + Object *obj = &_objects[i]; if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) - objindex[num_objs++] = i; + objindex[objNumb++] = i; } // Sort the objects into increasing y+y2 (painter's algorithm) - qsort(objindex, num_objs, sizeof(objindex[0]), y2comp); + qsort(objindex, objNumb, sizeof(objindex[0]), y2comp); // Add each visible object to display list - for (int i = 0; i < num_objs; i++) { - object_t *obj = &_objects[objindex[i]]; + for (int i = 0; i < objNumb; i++) { + Object *obj = &_objects[objindex[i]]; // Count down inter-frame timer if (obj->_frameTimer) obj->_frameTimer--; @@ -90,7 +90,7 @@ void ObjectHandler_v1w::updateImages() { _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, obj->_priority == kPriorityOverOverlay); break; case kCycleBackward: { - seq_t *seqPtr = obj->_currImagePtr; + Seq *seqPtr = obj->_currImagePtr; if (!obj->_frameTimer) { // Show next frame while (seqPtr->_nextSeqPtr != obj->_currImagePtr) seqPtr = seqPtr->_nextSeqPtr; @@ -105,8 +105,8 @@ void ObjectHandler_v1w::updateImages() { } // Cycle any animating objects - for (int i = 0; i < num_objs; i++) { - object_t *obj = &_objects[objindex[i]]; + for (int i = 0; i < objNumb; i++) { + Object *obj = &_objects[objindex[i]]; if (obj->_cycling != kCycleInvisible) { // Only if it's visible if (obj->_cycling == kCycleAlmostInvisible) @@ -138,7 +138,7 @@ void ObjectHandler_v1w::updateImages() { case kCycleBackward: { if (!obj->_frameTimer) { // Time to step to prev frame - seq_t *seqPtr = obj->_currImagePtr; + Seq *seqPtr = obj->_currImagePtr; while (obj->_currImagePtr->_nextSeqPtr != seqPtr) obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is first frame of sequence @@ -180,8 +180,8 @@ void ObjectHandler_v1w::moveObjects() { // and store all (visible) object baselines into the boundary file. // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if (obj->_screenIndex == *_vm->_screen_p) { switch (obj->_pathType) { case kPathChase: @@ -281,13 +281,13 @@ void ObjectHandler_v1w::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object + Object *obj = &_objects[i]; // Get pointer to object if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Seq *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates int x1 = obj->_x + currImage->_x1; // Left edge of object int x2 = obj->_x + currImage->_x2; // Right edge @@ -335,15 +335,15 @@ void ObjectHandler_v1w::moveObjects() { // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing if (_vm->_maze._enabledFl) { - seq_t *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image + Seq *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image // hero coordinates int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object int x2 = _vm->_hero->_x + currImage->_x2; // Right edge @@ -364,8 +364,8 @@ void ObjectHandler_v1w::swapImages(int objIndex1, int objIndex2) { saveSeq(&_objects[objIndex1]); - seqList_t tmpSeqList[kMaxSeqNumb]; - int seqListSize = sizeof(seqList_t) * kMaxSeqNumb; + SeqList tmpSeqList[kMaxSeqNumb]; + int seqListSize = sizeof(SeqList) * kMaxSeqNumb; memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize); memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize); diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp index 025374521c..f0d83269d5 100644 --- a/engines/hugo/object_v2d.cpp +++ b/engines/hugo/object_v2d.cpp @@ -59,21 +59,21 @@ void ObjectHandler_v2d::updateImages() { debugC(5, kDebugObject, "updateImages"); // Initialize the index array to visible objects in current screen - int num_objs = 0; + int objNumb = 0; byte objindex[kMaxObjNumb]; // Array of indeces to objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; + Object *obj = &_objects[i]; if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) - objindex[num_objs++] = i; + objindex[objNumb++] = i; } // Sort the objects into increasing y+y2 (painter's algorithm) - qsort(objindex, num_objs, sizeof(objindex[0]), y2comp); + qsort(objindex, objNumb, sizeof(objindex[0]), y2comp); // Add each visible object to display list - for (int i = 0; i < num_objs; i++) { - object_t *obj = &_objects[objindex[i]]; + for (int i = 0; i < objNumb; i++) { + Object *obj = &_objects[objindex[i]]; // Count down inter-frame timer if (obj->_frameTimer) obj->_frameTimer--; @@ -90,7 +90,7 @@ void ObjectHandler_v2d::updateImages() { _vm->_screen->displayFrame(obj->_x, obj->_y, obj->_currImagePtr->_nextSeqPtr, obj->_priority == kPriorityOverOverlay); break; case kCycleBackward: { - seq_t *seqPtr = obj->_currImagePtr; + Seq *seqPtr = obj->_currImagePtr; if (!obj->_frameTimer) { // Show next frame while (seqPtr->_nextSeqPtr != obj->_currImagePtr) seqPtr = seqPtr->_nextSeqPtr; @@ -107,8 +107,8 @@ void ObjectHandler_v2d::updateImages() { _vm->_scheduler->waitForRefresh(); // Cycle any animating objects - for (int i = 0; i < num_objs; i++) { - object_t *obj = &_objects[objindex[i]]; + for (int i = 0; i < objNumb; i++) { + Object *obj = &_objects[objindex[i]]; if (obj->_cycling != kCycleInvisible) { // Only if it's visible if (obj->_cycling == kCycleAlmostInvisible) @@ -140,7 +140,7 @@ void ObjectHandler_v2d::updateImages() { case kCycleBackward: { if (!obj->_frameTimer) { // Time to step to prev frame - seq_t *seqPtr = obj->_currImagePtr; + Seq *seqPtr = obj->_currImagePtr; while (obj->_currImagePtr->_nextSeqPtr != seqPtr) obj->_currImagePtr = obj->_currImagePtr->_nextSeqPtr; // Find out if this is first frame of sequence @@ -183,8 +183,8 @@ void ObjectHandler_v2d::moveObjects() { // and store all (visible) object baselines into the boundary file. // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if (obj->_screenIndex == *_vm->_screen_p) { switch (obj->_pathType) { case kPathChase: @@ -284,13 +284,13 @@ void ObjectHandler_v2d::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object + Object *obj = &_objects[i]; // Get pointer to object if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Seq *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates int x1 = obj->_x + currImage->_x1; // Left edge of object int x2 = obj->_x + currImage->_x2; // Right edge @@ -338,15 +338,15 @@ void ObjectHandler_v2d::moveObjects() { // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing if (_vm->_maze._enabledFl) { - seq_t *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image + Seq *currImage = _vm->_hero->_currImagePtr; // Get ptr to current image // hero coordinates int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object int x2 = _vm->_hero->_x + currImage->_x2; // Right edge @@ -359,8 +359,8 @@ void ObjectHandler_v2d::moveObjects() { void ObjectHandler_v2d::homeIn(const int objIndex1, const int objIndex2, const int8 objDx, const int8 objDy) { // object obj1 will home in on object obj2 - object_t *obj1 = &_objects[objIndex1]; - object_t *obj2 = &_objects[objIndex2]; + Object *obj1 = &_objects[objIndex1]; + Object *obj2 = &_objects[objIndex2]; obj1->_pathType = kPathAuto; int dx = obj1->_x + obj1->_currImagePtr->_x1 - obj2->_x - obj2->_currImagePtr->_x1; int dy = obj1->_y + obj1->_currImagePtr->_y1 - obj2->_y - obj2->_currImagePtr->_y1; diff --git a/engines/hugo/object_v3d.cpp b/engines/hugo/object_v3d.cpp index 15d5fcd936..13c9c8c93d 100644 --- a/engines/hugo/object_v3d.cpp +++ b/engines/hugo/object_v3d.cpp @@ -64,8 +64,8 @@ void ObjectHandler_v3d::moveObjects() { // and store all (visible) object baselines into the boundary file. // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if (obj->_screenIndex == *_vm->_screen_p) { switch (obj->_pathType) { case kPathChase: @@ -166,13 +166,13 @@ void ObjectHandler_v3d::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object + Object *obj = &_objects[i]; // Get pointer to object if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y // to move as close to a boundary as possible without crossing it. - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Seq *currImage = obj->_currImagePtr; // Get ptr to current image // object coordinates int x1 = obj->_x + currImage->_x1; // Left edge of object int x2 = obj->_x + currImage->_x2; // Right edge @@ -220,15 +220,15 @@ void ObjectHandler_v3d::moveObjects() { // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { - object_t *obj = &_objects[i]; // Get pointer to object - seq_t *currImage = obj->_currImagePtr; // Get ptr to current image + Object *obj = &_objects[i]; // Get pointer to object + Seq *currImage = obj->_currImagePtr; // Get ptr to current image if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } // If maze mode is enabled, do special maze processing if (_vm->_maze._enabledFl) { - seq_t *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image + Seq *currImage = _vm->_hero->_currImagePtr;// Get ptr to current image // hero coordinates int x1 = _vm->_hero->_x + currImage->_x1; // Left edge of object int x2 = _vm->_hero->_x + currImage->_x2; // Right edge @@ -249,8 +249,8 @@ void ObjectHandler_v3d::swapImages(int objIndex1, int objIndex2) { saveSeq(&_objects[objIndex1]); - seqList_t tmpSeqList[kMaxSeqNumb]; - int seqListSize = sizeof(seqList_t) * kMaxSeqNumb; + SeqList tmpSeqList[kMaxSeqNumb]; + int seqListSize = sizeof(SeqList) * kMaxSeqNumb; memmove(tmpSeqList, _objects[objIndex1]._seqList, seqListSize); memmove(_objects[objIndex1]._seqList, _objects[objIndex2]._seqList, seqListSize); diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp index 3b0eb1d979..68343a0374 100644 --- a/engines/hugo/parser.cpp +++ b/engines/hugo/parser.cpp @@ -99,7 +99,7 @@ void Parser::loadCmdList(Common::ReadStream &in) { } -void Parser::readBG(Common::ReadStream &in, background_t &curBG) { +void Parser::readBG(Common::ReadStream &in, Background &curBG) { curBG._verbIndex = in.readUint16BE(); curBG._nounIndex = in.readUint16BE(); curBG._commentIndex = in.readSint16BE(); @@ -112,7 +112,7 @@ void Parser::readBG(Common::ReadStream &in, background_t &curBG) { * Read _backgrounObjects from Hugo.dat */ void Parser::loadBackgroundObjects(Common::ReadStream &in) { - background_t tmpBG; + Background tmpBG; memset(&tmpBG, 0, sizeof(tmpBG)); for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { @@ -120,13 +120,13 @@ void Parser::loadBackgroundObjects(Common::ReadStream &in) { if (varnt == _vm->_gameVariant) { _backgroundObjectsSize = numElem; - _backgroundObjects = (background_t **)malloc(sizeof(background_t *) * numElem); + _backgroundObjects = (Background **)malloc(sizeof(Background *) * numElem); } for (int i = 0; i < numElem; i++) { uint16 numSubElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) - _backgroundObjects[i] = (background_t *)malloc(sizeof(background_t) * numSubElem); + _backgroundObjects[i] = (Background *)malloc(sizeof(Background) * numSubElem); for (int j = 0; j < numSubElem; j++) readBG(in, (varnt == _vm->_gameVariant) ? _backgroundObjects[i][j] : tmpBG); @@ -138,15 +138,15 @@ void Parser::loadBackgroundObjects(Common::ReadStream &in) { * Read _catchallList from Hugo.dat */ void Parser::loadCatchallList(Common::ReadStream &in) { - background_t *wrkCatchallList = 0; - background_t tmpBG; + Background *wrkCatchallList = 0; + Background tmpBG; memset(&tmpBG, 0, sizeof(tmpBG)); for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { uint16 numElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) - _catchallList = wrkCatchallList = (background_t *)malloc(sizeof(background_t) * numElem); + _catchallList = wrkCatchallList = (Background *)malloc(sizeof(Background) * numElem); for (int i = 0; i < numElem; i++) readBG(in, (varnt == _vm->_gameVariant) ? wrkCatchallList[i] : tmpBG); @@ -164,7 +164,7 @@ void Parser::loadArrayReqs(Common::SeekableReadStream &in) { const char *Parser::useBG(const char *name) { debugC(1, kDebugEngine, "useBG(%s)", name); - objectList_t p = _backgroundObjects[*_vm->_screen_p]; + ObjectList p = _backgroundObjects[*_vm->_screen_p]; for (int i = 0; p[i]._verbIndex != 0; i++) { if ((name == _vm->_text->getNoun(p[i]._nounIndex, 0) && p[i]._verbIndex != _vm->_look) && @@ -208,7 +208,7 @@ void Parser::switchTurbo() { void Parser::charHandler() { debugC(4, kDebugParser, "charHandler"); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); // Check for one or more characters in ring buffer while (_getIndex != _putIndex) { @@ -268,7 +268,7 @@ void Parser::charHandler() { void Parser::keyHandler(Common::Event event) { debugC(1, kDebugParser, "keyHandler(%d)", event.kbd.keycode); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); uint16 nChar = event.kbd.keycode; if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_SCRL)) diff --git a/engines/hugo/parser.h b/engines/hugo/parser.h index 18f4916b1e..e72c46f591 100644 --- a/engines/hugo/parser.h +++ b/engines/hugo/parser.h @@ -64,7 +64,7 @@ struct cmd { * interesting ever happens with them. Rather than just be dumb and say * "don't understand" we produce an interesting msg to keep user sane. */ -struct background_t { +struct Background { uint16 _verbIndex; uint16 _nounIndex; int _commentIndex; // Index of comment produced on match @@ -73,7 +73,7 @@ struct background_t { byte _bonusIndex; // Index of bonus score (0 = no bonus) }; -typedef background_t *objectList_t; +typedef Background *ObjectList; class Parser { public: @@ -97,7 +97,7 @@ public: virtual void lineHandler() = 0; virtual void showInventory() const = 0; - virtual void takeObject(object_t *obj) = 0; + virtual void takeObject(Object *obj) = 0; protected: HugoEngine *_vm; @@ -105,18 +105,18 @@ protected: int16 _cmdLineIndex; // Index into line uint32 _cmdLineTick; // For flashing cursor char _cmdLineCursor; - command_t _cmdLine; // Build command line + Command _cmdLine; // Build command line uint16 _backgroundObjectsSize; uint16 _cmdListSize; uint16 **_arrayReqs; - background_t **_backgroundObjects; - background_t *_catchallList; + Background **_backgroundObjects; + Background *_catchallList; cmd **_cmdList; const char *findNoun() const; const char *findVerb() const; - void readBG(Common::ReadStream &in, background_t &curBG); + void readBG(Common::ReadStream &in, Background &curBG); void readCmd(Common::ReadStream &in, cmd &curCmd); void showDosInventory() const; @@ -136,17 +136,17 @@ public: virtual void lineHandler(); virtual void showInventory() const; - virtual void takeObject(object_t *obj); + virtual void takeObject(Object *obj); protected: - virtual void dropObject(object_t *obj); + virtual void dropObject(Object *obj); const char *findNextNoun(const char *noun) const; - bool isBackgroundWord_v1(const char *noun, const char *verb, objectList_t obj) const; - bool isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, objectList_t obj) const; - bool isGenericVerb_v1(const char *word, object_t *obj); - bool isNear_v1(const char *verb, const char *noun, object_t *obj, char *comment) const; - bool isObjectVerb_v1(const char *word, object_t *obj); + bool isBackgroundWord_v1(const char *noun, const char *verb, ObjectList obj) const; + bool isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, ObjectList obj) const; + bool isGenericVerb_v1(const char *word, Object *obj); + bool isNear_v1(const char *verb, const char *noun, Object *obj, char *comment) const; + bool isObjectVerb_v1(const char *word, Object *obj); }; class Parser_v2d : public Parser_v1d { @@ -164,13 +164,13 @@ public: virtual void lineHandler(); protected: - void dropObject(object_t *obj); - bool isBackgroundWord_v3(objectList_t obj) const; - bool isCatchallVerb_v3(objectList_t obj) const; - bool isGenericVerb_v3(object_t *obj, char *comment); - bool isNear_v3(object_t *obj, const char *verb, char *comment) const; - bool isObjectVerb_v3(object_t *obj, char *comment); - void takeObject(object_t *obj); + void dropObject(Object *obj); + bool isBackgroundWord_v3(ObjectList obj) const; + bool isCatchallVerb_v3(ObjectList obj) const; + bool isGenericVerb_v3(Object *obj, char *comment); + bool isNear_v3(Object *obj, const char *verb, char *comment) const; + bool isObjectVerb_v3(Object *obj, char *comment); + void takeObject(Object *obj); }; class Parser_v1w : public Parser_v3d { diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp index aa43cce536..f29a03f796 100644 --- a/engines/hugo/parser_v1d.cpp +++ b/engines/hugo/parser_v1d.cpp @@ -78,7 +78,7 @@ const char *Parser_v1d::findNextNoun(const char *noun) const { * If object not near, return suitable string; may be similar object closer * If radius is -1, treat radius as infinity */ -bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, char *comment) const { +bool Parser_v1d::isNear_v1(const char *verb, const char *noun, Object *obj, char *comment) const { debugC(1, kDebugParser, "isNear(%s, %s, obj, %s)", verb, noun, comment); if (!noun && !obj->_verbOnlyFl) { // No noun specified & object not context senesitive @@ -140,8 +140,8 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, object_t *obj, ch * say_ok needed for special case of take/drop which may be handled not only * here but also in a cmd_list with a donestr string simultaneously */ -bool Parser_v1d::isGenericVerb_v1(const char *word, object_t *obj) { - debugC(1, kDebugParser, "isGenericVerb(%s, object_t *obj)", word); +bool Parser_v1d::isGenericVerb_v1(const char *word, Object *obj) { + debugC(1, kDebugParser, "isGenericVerb(%s, Object *obj)", word); if (!obj->_genericCmd) return false; @@ -181,8 +181,8 @@ bool Parser_v1d::isGenericVerb_v1(const char *word, object_t *obj) { * and if it passes, perform the actions in the action list. If the verb * is catered for, return TRUE */ -bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) { - debugC(1, kDebugParser, "isObjectVerb(%s, object_t *obj)", word); +bool Parser_v1d::isObjectVerb_v1(const char *word, Object *obj) { + debugC(1, kDebugParser, "isObjectVerb(%s, Object *obj)", word); // First, find matching verb in cmd list uint16 cmdIndex = obj->_cmdIndex; // ptr to list of commands @@ -231,7 +231,7 @@ bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) { * Print text for possible background object. Return TRUE if match found * Only match if both verb and noun found. Test_ca will match verb-only */ -bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, objectList_t obj) const { +bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, ObjectList obj) const { debugC(1, kDebugParser, "isBackgroundWord(%s, %s, object_list_t obj)", noun, verb); if (!noun) @@ -249,8 +249,8 @@ bool Parser_v1d::isBackgroundWord_v1(const char *noun, const char *verb, objectL /** * Do all things necessary to carry an object */ -void Parser_v1d::takeObject(object_t *obj) { - debugC(1, kDebugParser, "takeObject(object_t *obj)"); +void Parser_v1d::takeObject(Object *obj) { + debugC(1, kDebugParser, "takeObject(Object *obj)"); obj->_carriedFl = true; if (obj->_seqNumb) // Don't change if no image to display @@ -264,8 +264,8 @@ void Parser_v1d::takeObject(object_t *obj) { /** * Do all necessary things to drop an object */ -void Parser_v1d::dropObject(object_t *obj) { - debugC(1, kDebugParser, "dropObject(object_t *obj)"); +void Parser_v1d::dropObject(Object *obj) { + debugC(1, kDebugParser, "dropObject(Object *obj)"); obj->_carriedFl = false; obj->_screenIndex = *_vm->_screen_p; @@ -281,7 +281,7 @@ void Parser_v1d::dropObject(object_t *obj) { * Print text for possible background object. Return TRUE if match found * If test_noun TRUE, must have a noun given */ -bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, objectList_t obj) const { +bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char *verb, ObjectList obj) const { debugC(1, kDebugParser, "isCatchallVerb(%d, %s, %s, object_list_t obj)", (testNounFl) ? 1 : 0, noun, verb); if (_vm->_maze._enabledFl) @@ -305,7 +305,7 @@ bool Parser_v1d::isCatchallVerb_v1(bool testNounFl, const char *noun, const char void Parser_v1d::lineHandler() { debugC(1, kDebugParser, "lineHandler()"); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { @@ -403,7 +403,7 @@ void Parser_v1d::lineHandler() { noun = findNextNoun(noun); // Find a noun in the line // Must try at least once for objects allowing verb-context for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; + Object *obj = &_vm->_object->_objects[i]; if (isNear_v1(verb, noun, obj, farComment)) { if (isObjectVerb_v1(verb, obj) // Foreground object || isGenericVerb_v1(verb, obj))// Common action type @@ -424,7 +424,7 @@ void Parser_v1d::lineHandler() { } void Parser_v1d::showInventory() const { - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); if (gameStatus._viewState == kViewPlay) { if (gameStatus._gameOverFl) _vm->gameOverMsg(); diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp index 832e6fd1b0..8c0da63554 100644 --- a/engines/hugo/parser_v1w.cpp +++ b/engines/hugo/parser_v1w.cpp @@ -56,7 +56,7 @@ Parser_v1w::~Parser_v1w() { void Parser_v1w::lineHandler() { debugC(1, kDebugParser, "lineHandler()"); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { @@ -147,7 +147,7 @@ void Parser_v1w::lineHandler() { // Test for nearby objects referenced explicitly for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; + Object *obj = &_vm->_object->_objects[i]; if (isWordPresent(_vm->_text->getNounArray(obj->_nounIndex))) { if (isObjectVerb_v3(obj, farComment) || isGenericVerb_v3(obj, farComment)) return; @@ -157,7 +157,7 @@ void Parser_v1w::lineHandler() { // Test for nearby objects that only require a verb // Note comment is unused if not near. for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; + Object *obj = &_vm->_object->_objects[i]; if (obj->_verbOnlyFl) { char contextComment[kCompLineSize * 5] = ""; // Unused comment for context objects if (isObjectVerb_v3(obj, contextComment) || isGenericVerb_v3(obj, contextComment)) @@ -200,8 +200,8 @@ void Parser_v1w::lineHandler() { } void Parser_v1w::showInventory() const { - status_t &gameStatus = _vm->getGameStatus(); - istate_t inventState = _vm->_inventory->getInventoryState(); + Status &gameStatus = _vm->getGameStatus(); + Istate inventState = _vm->_inventory->getInventoryState(); if (gameStatus._gameOverFl) { _vm->gameOverMsg(); } else if ((inventState == kInventoryOff) && (gameStatus._viewState == kViewPlay)) { diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp index 2daf3c5e9f..674836b90e 100644 --- a/engines/hugo/parser_v2d.cpp +++ b/engines/hugo/parser_v2d.cpp @@ -55,7 +55,7 @@ Parser_v2d::~Parser_v2d() { void Parser_v2d::lineHandler() { debugC(1, kDebugParser, "lineHandler()"); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { @@ -153,7 +153,7 @@ void Parser_v2d::lineHandler() { noun = findNextNoun(noun); // Find a noun in the line // Must try at least once for objects allowing verb-context for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; + Object *obj = &_vm->_object->_objects[i]; if (isNear_v1(verb, noun, obj, farComment)) { if (isObjectVerb_v1(verb, obj) // Foreground object || isGenericVerb_v1(verb, obj))// Common action type diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp index abfe263f6e..9bbaf49f67 100644 --- a/engines/hugo/parser_v3d.cpp +++ b/engines/hugo/parser_v3d.cpp @@ -55,7 +55,7 @@ Parser_v3d::~Parser_v3d() { void Parser_v3d::lineHandler() { debugC(1, kDebugParser, "lineHandler()"); - status_t &gameStatus = _vm->getGameStatus(); + Status &gameStatus = _vm->getGameStatus(); // Toggle God Mode if (!strncmp(_vm->_line, "PPG", 3)) { @@ -149,7 +149,7 @@ void Parser_v3d::lineHandler() { // Test for nearby objects referenced explicitly for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; + Object *obj = &_vm->_object->_objects[i]; if (isWordPresent(_vm->_text->getNounArray(obj->_nounIndex))) { if (isObjectVerb_v3(obj, farComment) || isGenericVerb_v3(obj, farComment)) return; @@ -159,7 +159,7 @@ void Parser_v3d::lineHandler() { // Test for nearby objects that only require a verb // Note comment is unused if not near. for (int i = 0; i < _vm->_object->_numObj; i++) { - object_t *obj = &_vm->_object->_objects[i]; + Object *obj = &_vm->_object->_objects[i]; if (obj->_verbOnlyFl) { char contextComment[kCompLineSize * 5] = ""; // Unused comment for context objects if (isObjectVerb_v3(obj, contextComment) || isGenericVerb_v3(obj, contextComment)) @@ -204,8 +204,8 @@ void Parser_v3d::lineHandler() { * If it does, and the object is near and passes the tests in the command * list then carry out the actions in the action list and return TRUE */ -bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) { - debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment); +bool Parser_v3d::isObjectVerb_v3(Object *obj, char *comment) { + debugC(1, kDebugParser, "isObjectVerb(Object *obj, %s)", comment); // First, find matching verb in cmd list uint16 cmdIndex = obj->_cmdIndex; // ptr to list of commands @@ -259,8 +259,8 @@ bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) { /** * Test whether command line contains one of the generic actions */ -bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) { - debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment); +bool Parser_v3d::isGenericVerb_v3(Object *obj, char *comment) { + debugC(1, kDebugParser, "isGenericVerb(Object *obj, %s)", comment); if (!obj->_genericCmd) return false; @@ -313,8 +313,8 @@ bool Parser_v3d::isGenericVerb_v3(object_t *obj, char *comment) { * If radius is -1, treat radius as infinity * Verb is included to determine correct comment if not near */ -bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const { - debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment); +bool Parser_v3d::isNear_v3(Object *obj, const char *verb, char *comment) const { + debugC(1, kDebugParser, "isNear(Object *obj, %s, %s)", verb, comment); if (obj->_carriedFl) // Object is being carried return true; @@ -368,8 +368,8 @@ bool Parser_v3d::isNear_v3(object_t *obj, const char *verb, char *comment) const /** * Do all things necessary to carry an object */ -void Parser_v3d::takeObject(object_t *obj) { - debugC(1, kDebugParser, "takeObject(object_t *obj)"); +void Parser_v3d::takeObject(Object *obj) { + debugC(1, kDebugParser, "takeObject(Object *obj)"); obj->_carriedFl = true; if (obj->_seqNumb) { // Don't change if no image to display @@ -385,8 +385,8 @@ void Parser_v3d::takeObject(object_t *obj) { /** * Do all necessary things to drop an object */ -void Parser_v3d::dropObject(object_t *obj) { - debugC(1, kDebugParser, "dropObject(object_t *obj)"); +void Parser_v3d::dropObject(Object *obj) { + debugC(1, kDebugParser, "dropObject(Object *obj)"); obj->_carriedFl = false; obj->_screenIndex = *_vm->_screen_p; @@ -407,7 +407,7 @@ void Parser_v3d::dropObject(object_t *obj) { * Note that if the background command list has match set TRUE then do not * print text if there are any recognizable nouns in the command line */ -bool Parser_v3d::isCatchallVerb_v3(objectList_t obj) const { +bool Parser_v3d::isCatchallVerb_v3(ObjectList obj) const { debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)"); if (_vm->_maze._enabledFl) @@ -435,7 +435,7 @@ bool Parser_v3d::isCatchallVerb_v3(objectList_t obj) const { * Search for matching verb/noun pairs in background command list * Print text for possible background object. Return TRUE if match found */ -bool Parser_v3d::isBackgroundWord_v3(objectList_t obj) const { +bool Parser_v3d::isBackgroundWord_v3(ObjectList obj) const { debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)"); if (_vm->_maze._enabledFl) diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index 873cb587af..45d72bafb1 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -61,7 +61,7 @@ int16 Route::getRouteIndex() const { void Route::setDirection(const uint16 keyCode) { debugC(1, kDebugRoute, "setDirection(%d)", keyCode); - object_t *obj = _vm->_hero; // Pointer to hero object + Object *obj = _vm->_hero; // Pointer to hero object // Set first image in sequence switch (keyCode) { @@ -107,7 +107,7 @@ void Route::setDirection(const uint16 keyCode) { void Route::setWalk(const uint16 direction) { debugC(1, kDebugRoute, "setWalk(%d)", direction); - object_t *obj = _vm->_hero; // Pointer to hero object + Object *obj = _vm->_hero; // Pointer to hero object if (_vm->getGameStatus()._storyModeFl || obj->_pathType != kPathUser) // Make sure user has control return; @@ -188,8 +188,8 @@ void Route::segment(int16 x, int16 y) { debugC(1, kDebugRoute, "segment(%d, %d)", x, y); // Note: use of static - can't waste stack - static image_pt p; // Ptr to _boundaryMap[y] - static segment_t *seg_p; // Ptr to segment + static ImagePtr p; // Ptr to _boundaryMap[y] + static Segment *segPtr; // Ptr to segment // Bomb out if stack exhausted // Vinterstum: Is this just a safeguard, or actually used? @@ -285,10 +285,10 @@ void Route::segment(int16 x, int16 y) { _fullSegmentFl = true; } else { // Create segment - seg_p = &_segment[_segmentNumb]; - seg_p->_y = y; - seg_p->_x1 = x1; - seg_p->_x2 = x2; + segPtr = &_segment[_segmentNumb]; + segPtr->_y = y; + segPtr->_x1 = x1; + segPtr->_x2 = x2; _segmentNumb++; } } @@ -332,7 +332,7 @@ bool Route::findRoute(const int16 cx, const int16 cy) { int16 heroy = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2; // Hero baseline // Store all object baselines into objbound (except hero's = [0]) - object_t *obj; // Ptr to object + Object *obj; // Ptr to object int i; for (i = 1, obj = &_vm->_object->_objects[i]; i < _vm->_object->_numObj; i++, obj++) { if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) @@ -382,18 +382,18 @@ bool Route::findRoute(const int16 cx, const int16 cy) { // Look ahead for furthest straight line for (int16 j = i + 1; j < _segmentNumb; j++) { - segment_t *seg_p = &_segment[j]; + Segment *segPtr = &_segment[j]; // Can we get to this segment from previous node? - if (seg_p->_x1 <= routeNode->x && seg_p->_x2 >= routeNode->x + _heroWidth - 1) { - routeNode->y = seg_p->_y; // Yes, keep updating node + if (segPtr->_x1 <= routeNode->x && segPtr->_x2 >= routeNode->x + _heroWidth - 1) { + routeNode->y = segPtr->_y; // Yes, keep updating node } else { // No, create another node on previous segment to reach it if ((routeNode = newNode()) == 0) // Add new route node return false; // Too many nodes // Find overlap between old and new segments - int16 x1 = MAX(_segment[j - 1]._x1, seg_p->_x1); - int16 x2 = MIN(_segment[j - 1]._x2, seg_p->_x2); + int16 x1 = MAX(_segment[j - 1]._x1, segPtr->_x1); + int16 x2 = MIN(_segment[j - 1]._x2, segPtr->_x2); // If room, add a little offset to reduce staircase effect int16 dx = kHeroMaxWidth >> 1; @@ -500,7 +500,7 @@ void Route::processRoute() { * go_for is the purpose, id indexes the exit or object to walk to * Returns FALSE if route not found */ -bool Route::startRoute(const go_t routeType, const int16 objId, int16 cx, int16 cy) { +bool Route::startRoute(const RouteType routeType, const int16 objId, int16 cx, int16 cy) { debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", routeType, objId, cx, cy); // Don't attempt to walk if user does not have control diff --git a/engines/hugo/route.h b/engines/hugo/route.h index 53b0dd0f88..716829a201 100644 --- a/engines/hugo/route.h +++ b/engines/hugo/route.h @@ -37,11 +37,11 @@ namespace Hugo { /** * Purpose of an automatic route */ -enum go_t {kRouteSpace, kRouteExit, kRouteLook, kRouteGet}; +enum RouteType {kRouteSpace, kRouteExit, kRouteLook, kRouteGet}; -struct segment_t { // Search segment - int16 _y; // y position - int16 _x1, _x2; // Range of segment +struct Segment { // Search segment + int16 _y; // y position + int16 _x1, _x2; // Range of segment }; class Route { @@ -52,7 +52,7 @@ public: int16 getRouteIndex() const; void processRoute(); - bool startRoute(const go_t routeType, const int16 objId, int16 cx, int16 cy); + bool startRoute(const RouteType routeType, const int16 objId, int16 cx, int16 cy); void setDirection(const uint16 keyCode); void setWalk(const uint16 direction); @@ -66,12 +66,12 @@ private: uint16 _oldWalkDirection; // Last direction char - int16 _routeIndex; // Index into route list, or -1 - go_t _routeType; // Purpose of an automatic route - int16 _routeObjId; // Index of exit of object walking to + int16 _routeIndex; // Index into route list, or -1 + RouteType _routeType; // Purpose of an automatic route + int16 _routeObjId; // Index of exit of object walking to byte _boundaryMap[kYPix][kXPix]; // Boundary byte map - segment_t _segment[kMaxSeg]; // List of points in fill-path + Segment _segment[kMaxSeg]; // List of points in fill-path Common::Point _route[kMaxNodes]; // List of nodes in route (global) int16 _segmentNumb; // Count number of segments int16 _routeListIndex; // Index into route list diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 0e57b08f19..3bbec6670e 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -83,12 +83,12 @@ void Scheduler::initEventQueue() { /** * Return a ptr to an event structure from the free list */ -event_t *Scheduler::getQueue() { +Event *Scheduler::getQueue() { debugC(4, kDebugSchedule, "getQueue"); if (!_freeEvent) // Error: no more events available error("An error has occurred: %s", "getQueue"); - event_t *resEvent = _freeEvent; + Event *resEvent = _freeEvent; _freeEvent = _freeEvent->_nextEvent; resEvent->_nextEvent = 0; return resEvent; @@ -175,8 +175,8 @@ void Scheduler::newScreen(const int screenIndex) { } // 1. Clear out all local events - event_t *curEvent = _headEvent; // The earliest event - event_t *wrkEvent; // Event ptr + Event *curEvent = _headEvent; // The earliest event + Event *wrkEvent; // Event ptr while (curEvent) { // While mature events found wrkEvent = curEvent->_nextEvent; // Save p (becomes undefined after Del) if (curEvent->_localActionFl) @@ -259,7 +259,7 @@ void Scheduler::loadPoints(Common::SeekableReadStream &in) { uint16 numElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) { _numBonuses = numElem; - _points = (point_t *)malloc(sizeof(point_t) * _numBonuses); + _points = (Point *)malloc(sizeof(Point) * _numBonuses); for (int i = 0; i < _numBonuses; i++) { _points[i]._score = in.readByte(); _points[i]._scoredFl = false; @@ -270,10 +270,10 @@ void Scheduler::loadPoints(Common::SeekableReadStream &in) { } } -void Scheduler::readAct(Common::ReadStream &in, act &curAct) { +void Scheduler::readAct(Common::ReadStream &in, Act &curAct) { uint16 numSubAct; - curAct._a0._actType = (action_t) in.readByte(); + curAct._a0._actType = (Action) in.readByte(); switch (curAct._a0._actType) { case ANULL: // -1 break; @@ -285,7 +285,7 @@ void Scheduler::readAct(Common::ReadStream &in, act &curAct) { curAct._a1._timer = in.readSint16BE(); curAct._a1._objIndex = in.readSint16BE(); curAct._a1._cycleNumb = in.readSint16BE(); - curAct._a1._cycle = (cycle_t) in.readByte(); + curAct._a1._cycle = (Cycle) in.readByte(); break; case INIT_OBJXY: // 2 curAct._a2._timer = in.readSint16BE(); @@ -393,7 +393,7 @@ void Scheduler::readAct(Common::ReadStream &in, act &curAct) { break; case DEL_EVENTS: // 20 curAct._a20._timer = in.readSint16BE(); - curAct._a20._actTypeDel = (action_t) in.readByte(); + curAct._a20._actTypeDel = (Action) in.readByte(); break; case GAMEOVER: // 21 curAct._a21._timer = in.readSint16BE(); @@ -553,20 +553,20 @@ void Scheduler::readAct(Common::ReadStream &in, act &curAct) { void Scheduler::loadActListArr(Common::ReadStream &in) { debugC(6, kDebugSchedule, "loadActListArr(&in)"); - act tmpAct; + Act tmpAct; int numElem, numSubElem; for (int varnt = 0; varnt < _vm->_numVariant; varnt++) { numElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) { _actListArrSize = numElem; - _actListArr = (act **)malloc(sizeof(act *) * _actListArrSize); + _actListArr = (Act **)malloc(sizeof(Act *) * _actListArrSize); } for (int i = 0; i < numElem; i++) { numSubElem = in.readUint16BE(); if (varnt == _vm->_gameVariant) - _actListArr[i] = (act *)malloc(sizeof(act) * (numSubElem + 1)); + _actListArr[i] = (Act *)malloc(sizeof(Act) * (numSubElem + 1)); for (int j = 0; j < numSubElem; j++) { if (varnt == _vm->_gameVariant) { readAct(in, _actListArr[i][j]); @@ -708,7 +708,7 @@ void Scheduler::saveEvents(Common::WriteStream *f) { // Convert event ptrs to indexes for (int16 i = 0; i < kMaxEvents; i++) { - event_t *wrkEvent = &_events[i]; + Event *wrkEvent = &_events[i]; // fix up action pointer (to do better) int16 index, subElem; @@ -1039,7 +1039,7 @@ void Scheduler::saveActions(Common::WriteStream *f) const { /* * Find the index in the action list to be able to serialize the action to save game */ -void Scheduler::findAction(const act* action, int16* index, int16* subElem) { +void Scheduler::findAction(const Act *action, int16 *index, int16 *subElem) { assert(index && subElem); if (!action) { @@ -1104,7 +1104,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { if ((index == -1) && (subElem == -1)) _events[i]._action = 0; else - _events[i]._action = (act *)&_actListArr[index][subElem]; + _events[i]._action = (Act *)&_actListArr[index][subElem]; _events[i]._localActionFl = (f->readByte() == 1) ? true : false; _events[i]._time = f->readUint32BE(); @@ -1112,8 +1112,8 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { int16 prevIndex = f->readSint16BE(); int16 nextIndex = f->readSint16BE(); - _events[i]._prevEvent = (prevIndex == -1) ? (event_t *)0 : &_events[prevIndex]; - _events[i]._nextEvent = (nextIndex == -1) ? (event_t *)0 : &_events[nextIndex]; + _events[i]._prevEvent = (prevIndex == -1) ? (Event *)0 : &_events[prevIndex]; + _events[i]._nextEvent = (nextIndex == -1) ? (Event *)0 : &_events[nextIndex]; } _freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex]; _headEvent = (headIndex == -1) ? 0 : &_events[headIndex]; @@ -1121,7 +1121,7 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { // Adjust times to fit our time uint32 curTime = getTicks(); - event_t *wrkEvent = _headEvent; // The earliest event + Event *wrkEvent = _headEvent; // The earliest event while (wrkEvent) { // While mature events found wrkEvent->_time = wrkEvent->_time - saveTime + curTime; wrkEvent = wrkEvent->_nextEvent; @@ -1132,11 +1132,11 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { * Insert the action pointed to by p into the timer event queue * The queue goes from head (earliest) to tail (latest) timewise */ -void Scheduler::insertAction(act *action) { +void Scheduler::insertAction(Act *action) { debugC(1, kDebugSchedule, "insertAction() - Action type A%d", action->_a0._actType); // First, get and initialize the event structure - event_t *curEvent = getQueue(); + Event *curEvent = getQueue(); curEvent->_action = action; switch (action->_a0._actType) { // Assign whether local or global case AGSCHEDULE: @@ -1158,7 +1158,7 @@ void Scheduler::insertAction(act *action) { _tailEvent = _headEvent = curEvent; curEvent->_nextEvent = curEvent->_prevEvent = 0; } else { - event_t *wrkEvent = _tailEvent; // Search from latest time back + Event *wrkEvent = _tailEvent; // Search from latest time back bool found = false; while (wrkEvent && !found) { @@ -1189,14 +1189,14 @@ void Scheduler::insertAction(act *action) { * It dequeues the event and returns it to the free list. It returns a ptr * to the next action in the list, except special case of NEW_SCREEN */ -event_t *Scheduler::doAction(event_t *curEvent) { +Event *Scheduler::doAction(Event *curEvent) { debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->_action->_a0._actType); - status_t &gameStatus = _vm->getGameStatus(); - act *action = curEvent->_action; - object_t *obj1; - int dx, dy; - event_t *wrkEvent; // Save ev_p->next_p for return + Status &gameStatus = _vm->getGameStatus(); + Act *action = curEvent->_action; + Object *obj1; + int dx, dy; + Event *wrkEvent; // Save ev_p->next_p for return switch (action->_a0._actType) { case ANULL: // Big NOP from DEL_EVENTS @@ -1236,7 +1236,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm->_object->_objects[action->_a9._objIndex]._state = action->_a9._newState; break; case INIT_PATH: // act10: Initialize an object path and velocity - _vm->_object->setPath(action->_a10._objIndex, (path_t) action->_a10._newPathType, action->_a10._vxPath, action->_a10._vyPath); + _vm->_object->setPath(action->_a10._objIndex, (Path) action->_a10._newPathType, action->_a10._vxPath, action->_a10._vyPath); break; case COND_R: // act11: action lists conditional on object state if (_vm->_object->_objects[action->_a11._objIndex]._state == action->_a11._stateReq) @@ -1441,7 +1441,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { * was modified to allow deletes anywhere in the list, and the DEL_EVENT * action was modified to perform the actual delete. */ -void Scheduler::delQueue(event_t *curEvent) { +void Scheduler::delQueue(Event *curEvent) { debugC(4, kDebugSchedule, "delQueue()"); if (curEvent == _headEvent) { // If p was the head ptr @@ -1468,10 +1468,10 @@ void Scheduler::delQueue(event_t *curEvent) { /** * Delete all the active events of a given type */ -void Scheduler::delEventType(const action_t _actTypeDel) { +void Scheduler::delEventType(const Action _actTypeDel) { // Note: actions are not deleted here, simply turned into NOPs! - event_t *wrkEvent = _headEvent; // The earliest event - event_t *saveEvent; + Event *wrkEvent = _headEvent; // The earliest event + Event *saveEvent; while (wrkEvent) { // While events found in list saveEvent = wrkEvent->_nextEvent; @@ -1525,13 +1525,13 @@ void Scheduler_v1d::runScheduler() { debugC(6, kDebugSchedule, "runScheduler"); uint32 ticker = getTicks(); // The time now, in ticks - event_t *curEvent = _headEvent; // The earliest event + Event *curEvent = _headEvent; // The earliest event while (curEvent && (curEvent->_time <= ticker)) // While mature events found curEvent = doAction(curEvent); // Perform the action (returns next_p) } -void Scheduler_v1d::promptAction(act *action) { +void Scheduler_v1d::promptAction(Act *action) { Common::String response; response = Utils::promptBox(_vm->_file->fetchString(action->_a3._promptIndex)); @@ -1574,7 +1574,7 @@ const char *Scheduler_v2d::getCypher() const { return "Copyright 1991, Gray Design Associates"; } -void Scheduler_v2d::promptAction(act *action) { +void Scheduler_v2d::promptAction(Act *action) { Common::String response; response = Utils::promptBox(_vm->_file->fetchString(action->_a3._promptIndex)); @@ -1639,7 +1639,7 @@ void Scheduler_v1w::runScheduler() { debugC(6, kDebugSchedule, "runScheduler"); uint32 ticker = getTicks(); // The time now, in ticks - event_t *curEvent = _headEvent; // The earliest event + Event *curEvent = _headEvent; // The earliest event while (curEvent && (curEvent->_time <= ticker)) // While mature events found curEvent = doAction(curEvent); // Perform the action (returns next_p) diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h index 74a65a5c64..37851f1ebc 100644 --- a/engines/hugo/schedule.h +++ b/engines/hugo/schedule.h @@ -37,7 +37,7 @@ namespace Hugo { /** * Following defines the action types and action list */ -enum action_t { // Parameters: +enum Action { // Parameters: ANULL = 0xff, // Special NOP used to 'delete' events in DEL_EVENTS ASCHEDULE = 0, // 0 - Ptr to action list to be rescheduled START_OBJ, // 1 - Object number @@ -56,7 +56,7 @@ enum action_t { // Parameters: SWAP_IMAGES, // 13 - Swap 2 object images COND_SCR, // 14 - Conditional on current screen AUTOPILOT, // 15 - Set object to home in on another (stationary) object - INIT_OBJ_SEQ, // 16 - Object number, sequence index to set curr_seq_p to + INIT_OBJ_SEQ, // 16 - Object number, sequence index to set curr_seqPtr to SET_STATE_BITS, // 17 - Objnum, mask to OR with obj states word CLEAR_STATE_BITS, // 18 - Objnum, mask to ~AND with obj states word TEST_STATE_BITS, // 19 - Objnum, mask to test obj states word @@ -88,33 +88,33 @@ enum action_t { // Parameters: COND_ROUTE, // 45 - Conditional on route in progress INIT_JUMPEXIT, // 46 - Initialize status.jumpexit INIT_VIEW, // 47 - Initialize viewx, viewy, dir - INIT_OBJ_FRAME, // 48 - Object number, seq,frame to set curr_seq_p to + INIT_OBJ_FRAME, // 48 - Object number, seq,frame to set curr_seqPtr to OLD_SONG = 49 // Added by Strangerke - Set currently playing sound, old way: that is, using a string index instead of a reference in a file }; struct act0 { // Type 0 - Schedule - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action uint16 _actIndex; // Ptr to an action list }; struct act1 { // Type 1 - Start an object - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _cycleNumb; // Number of times to cycle - cycle_t _cycle; // Direction to start cycling + Cycle _cycle; // Direction to start cycling }; struct act2 { // Type 2 - Initialize an object coords - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _x, _y; // Coordinates }; struct act3 { // Type 3 - Prompt user for text - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action uint16 _promptIndex; // Index of prompt string int *_responsePtr; // Array of indexes to valid response string(s) (terminate list with -1) @@ -124,54 +124,54 @@ struct act3 { // Type 3 - Prompt user for }; struct act4 { // Type 4 - Set new background color - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action long _newBackgroundColor; // New color }; struct act5 { // Type 5 - Initialize an object velocity - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _vx, _vy; // velocity }; struct act6 { // Type 6 - Initialize an object carrying - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number bool _carriedFl; // carrying }; struct act7 { // Type 7 - Initialize an object to hero's coords - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number }; struct act8 { // Type 8 - switch to new screen - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _screenIndex; // The new screen number }; struct act9 { // Type 9 - Initialize an object state - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number byte _newState; // New state }; struct act10 { // Type 10 - Initialize an object path type - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _newPathType; // New path type - int8 _vxPath, _vyPath; // Max delta velocities e.g. for CHASE + int8 _vxPath, _vyPath; // Max delta velocities e.g. for CHASE }; struct act11 { // Type 11 - Conditional on object's state - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number byte _stateReq; // Required state @@ -180,20 +180,20 @@ struct act11 { // Type 11 - Conditional on }; struct act12 { // Type 12 - Simple text box - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _stringIndex; // Index (enum) of string in strings.dat }; struct act13 { // Type 13 - Swap first object image with second - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex1; // Index of first object int _objIndex2; // 2nd }; struct act14 { // Type 14 - Conditional on current screen - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The required object int _screenReq; // The required screen number @@ -202,7 +202,7 @@ struct act14 { // Type 14 - Conditional on }; struct act15 { // Type 15 - Home in on an object - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex1; // The object number homing in int _objIndex2; // The object number to home in on @@ -211,29 +211,29 @@ struct act15 { // Type 15 - Home in on an o // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! timer > 0 is safe -struct act16 { // Type 16 - Set curr_seq_p to seq - action_t _actType; // The type of action +struct act16 { // Type 16 - Set curr_seqPtr to seq + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _seqIndex; // The index of seq array to set to }; struct act17 { // Type 17 - SET obj individual state bits - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _stateMask; // The mask to OR with current obj state }; struct act18 { // Type 18 - CLEAR obj individual state bits - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _stateMask; // The mask to ~AND with current obj state }; struct act19 { // Type 19 - TEST obj individual state bits - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _stateMask; // The mask to AND with current obj state @@ -242,35 +242,35 @@ struct act19 { // Type 19 - TEST obj indivi }; struct act20 { // Type 20 - Remove all events with this type of action - action_t _actType; // The type of action - int _timer; // Time to set off the action - action_t _actTypeDel; // The action type to remove + Action _actType; // The type of action + int _timer; // Time to set off the action + Action _actTypeDel; // The action type to remove }; struct act21 { // Type 21 - Gameover. Disable hero & commands - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action }; struct act22 { // Type 22 - Initialize an object to hero's coords - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number }; struct act23 { // Type 23 - Exit game back to DOS - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action }; struct act24 { // Type 24 - Get bonus score - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _pointIndex; // Index into points array }; struct act25 { // Type 25 - Conditional on bounding box - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The required object number int _x1, _y1, _x2, _y2; // The bounding box @@ -279,25 +279,25 @@ struct act25 { // Type 25 - Conditional on }; struct act26 { // Type 26 - Play a sound - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int16 _soundIndex; // Sound index in data file }; struct act27 { // Type 27 - Add object's value to score - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // object number }; struct act28 { // Type 28 - Subtract object's value from score - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // object number }; struct act29 { // Type 29 - Conditional on object carried - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The required object number uint16 _actPassIndex; // Ptr to action list if success @@ -305,7 +305,7 @@ struct act29 { // Type 29 - Conditional on }; struct act30 { // Type 30 - Start special maze processing - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action byte _mazeSize; // Size of (square) maze int _x1, _y1, _x2, _y2; // Bounding box of maze @@ -314,39 +314,39 @@ struct act30 { // Type 30 - Start special m }; struct act31 { // Type 31 - Exit special maze processing - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action }; struct act32 { // Type 32 - Init fbg field of object - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number byte _priority; // Value of foreground/background field }; struct act33 { // Type 33 - Init screen field of object - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _screenIndex; // Screen number }; struct act34 { // Type 34 - Global Schedule - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action uint16 _actIndex; // Ptr to an action list }; struct act35 { // Type 35 - Remappe palette - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int16 _oldColorIndex; // Old color index, 0..15 int16 _newColorIndex; // New color index, 0..15 }; struct act36 { // Type 36 - Conditional on noun mentioned - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action uint16 _nounIndex; // The required noun (list) uint16 _actPassIndex; // Ptr to action list if success @@ -354,14 +354,14 @@ struct act36 { // Type 36 - Conditional on }; struct act37 { // Type 37 - Set new screen state - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _screenIndex; // The screen number byte _newState; // The new state }; struct act38 { // Type 38 - Position lips - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _lipsObjIndex; // The LIPS object int _objIndex; // The object to speak @@ -370,19 +370,19 @@ struct act38 { // Type 38 - Position lips }; struct act39 { // Type 39 - Init story mode - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action bool _storyModeFl; // New state of story_mode flag }; struct act40 { // Type 40 - Unsolicited text box - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _stringIndex; // Index (enum) of string in strings.dat }; struct act41 { // Type 41 - Conditional on bonus scored - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _bonusIndex; // Index into bonus list uint16 _actPassIndex; // Index of the action list if scored for the first time @@ -390,13 +390,13 @@ struct act41 { // Type 41 - Conditional on }; struct act42 { // Type 42 - Text box with "take" string - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object taken }; struct act43 { // Type 43 - Prompt user for Yes or No - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _promptIndex; // index of prompt string uint16 _actYesIndex; // Ptr to action list if YES @@ -404,12 +404,12 @@ struct act43 { // Type 43 - Prompt user for }; struct act44 { // Type 44 - Stop any route in progress - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action }; struct act45 { // Type 45 - Conditional on route in progress - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _routeIndex; // Must be >= current status.rindex uint16 _actPassIndex; // Ptr to action list if en-route @@ -417,13 +417,13 @@ struct act45 { // Type 45 - Conditional on }; struct act46 { // Type 46 - Init status.jumpexit - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action bool _jumpExitFl; // New state of jumpexit flag }; struct act47 { // Type 47 - Init viewx,viewy,dir - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object int16 _viewx; // object.viewx @@ -431,8 +431,8 @@ struct act47 { // Type 47 - Init viewx,view int16 _direction; // object.dir }; -struct act48 { // Type 48 - Set curr_seq_p to frame n - action_t _actType; // The type of action +struct act48 { // Type 48 - Set curr_seqPtr to frame n + Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _seqIndex; // The index of seq array to set to @@ -440,12 +440,12 @@ struct act48 { // Type 48 - Set curr_seq_p }; struct act49 { // Added by Strangerke - Type 49 - Play a song (DOS way) - action_t _actType; // The type of action + Action _actType; // The type of action int _timer; // Time to set off the action uint16 _songIndex; // Song index in string array }; -union act { +union Act { act0 _a0; act1 _a1; act2 _a2; @@ -498,18 +498,18 @@ union act { act49 _a49; }; -struct event_t { - act *_action; // Ptr to action to perform - bool _localActionFl; // true if action is only for this screen - uint32 _time; // (absolute) time to perform action - struct event_t *_prevEvent; // Chain to previous event - struct event_t *_nextEvent; // Chain to next event +struct Event { + Act *_action; // Ptr to action to perform + bool _localActionFl; // true if action is only for this screen + uint32 _time; // (absolute) time to perform action + struct Event *_prevEvent; // Chain to previous event + struct Event *_nextEvent; // Chain to next event }; /** * Following are points for achieving certain actions. */ -struct point_t { +struct Point { byte _score; // The value of the point bool _scoredFl; // Whether scored yet }; @@ -554,36 +554,36 @@ protected: uint16 **_screenActs; byte _numBonuses; - point_t *_points; + Point *_points; uint32 _curTick; // Current system time in ticks uint32 _oldTime; // The previous wall time in ticks uint32 _refreshTimeout; - event_t *_freeEvent; // Free list of event structures - event_t *_headEvent; // Head of list (earliest time) - event_t *_tailEvent; // Tail of list (latest time) - event_t _events[kMaxEvents]; // Statically declare event structures + Event *_freeEvent; // Free list of event structures + Event *_headEvent; // Head of list (earliest time) + Event *_tailEvent; // Tail of list (latest time) + Event _events[kMaxEvents]; // Statically declare event structures - act **_actListArr; + Act **_actListArr; virtual const char *getCypher() const = 0; virtual uint32 getTicks() = 0; - virtual void promptAction(act *action) = 0; + virtual void promptAction(Act *action) = 0; - event_t *doAction(event_t *curEvent); - event_t *getQueue(); + Event *doAction(Event *curEvent); + Event *getQueue(); uint32 getDosTicks(const bool updateFl); uint32 getWinTicks() const; - void delEventType(const action_t actTypeDel); - void delQueue(event_t *curEvent); - void findAction(const act* action, int16* index, int16* subElem); - void insertAction(act *action); - void readAct(Common::ReadStream &in, act &curAct); + void delEventType(const Action actTypeDel); + void delQueue(Event *curEvent); + void findAction(const Act* action, int16* index, int16* subElem); + void insertAction(Act *action); + void readAct(Common::ReadStream &in, Act &curAct); void restoreActions(Common::ReadStream *f); void restoreEvents(Common::ReadStream *f); void restorePoints(Common::ReadStream *in); @@ -605,7 +605,7 @@ public: protected: virtual const char *getCypher() const; virtual uint32 getTicks(); - virtual void promptAction(act *action); + virtual void promptAction(Act *action); }; class Scheduler_v2d : public Scheduler_v1d { @@ -618,7 +618,7 @@ public: protected: virtual const char *getCypher() const; - void promptAction(act *action); + void promptAction(Act *action); }; class Scheduler_v3d : public Scheduler_v2d { diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp index 463a19ae8c..a8b4759d9b 100644 --- a/engines/hugo/sound.cpp +++ b/engines/hugo/sound.cpp @@ -174,8 +174,8 @@ void SoundHandler::toggleSound() { _vm->_config._soundFl = !_vm->_config._soundFl; } -void SoundHandler::playMIDI(sound_pt seq_p, uint16 size) { - _midiPlayer->play(seq_p, size); +void SoundHandler::playMIDI(sound_pt seqPtr, uint16 size) { + _midiPlayer->play(seqPtr, size); } /** -- cgit v1.2.3 From 179427c78f2a634beb4485661bf2b1fc78ef559f Mon Sep 17 00:00:00 2001 From: Strangerke Date: Wed, 13 Jun 2012 21:18:37 +0200 Subject: HUGO: Rename pointers --- engines/hugo/display.cpp | 14 ++-- engines/hugo/display.h | 6 +- engines/hugo/file.cpp | 18 ++--- engines/hugo/file.h | 4 +- engines/hugo/game.h | 2 +- engines/hugo/hugo.cpp | 4 +- engines/hugo/hugo.h | 2 +- engines/hugo/mouse.cpp | 4 +- engines/hugo/object.cpp | 4 +- engines/hugo/object_v1d.cpp | 8 +- engines/hugo/object_v1w.cpp | 8 +- engines/hugo/object_v2d.cpp | 8 +- engines/hugo/object_v3d.cpp | 6 +- engines/hugo/parser.cpp | 4 +- engines/hugo/parser_v1d.cpp | 8 +- engines/hugo/parser_v1w.cpp | 4 +- engines/hugo/parser_v2d.cpp | 6 +- engines/hugo/parser_v3d.cpp | 12 +-- engines/hugo/route.cpp | 4 +- engines/hugo/schedule.cpp | 188 ++++++++++++++++++++++---------------------- engines/hugo/sound.cpp | 14 ++-- engines/hugo/sound.h | 2 +- 22 files changed, 165 insertions(+), 165 deletions(-) diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp index 34b0303eee..b86b1f0366 100644 --- a/engines/hugo/display.cpp +++ b/engines/hugo/display.cpp @@ -657,7 +657,7 @@ void Screen::drawBoundaries() { for (int i = 0; i < _vm->_object->_numObj; i++) { Object *obj = &_vm->_object->_objects[i]; // Get pointer to object - if (obj->_screenIndex == *_vm->_screen_p) { + if (obj->_screenIndex == *_vm->_screenPtr) { if ((obj->_currImagePtr != 0) && (obj->_cycling != kCycleInvisible)) drawRectangle(false, obj->_x + obj->_currImagePtr->_x1, obj->_y + obj->_currImagePtr->_y1, obj->_x + obj->_currImagePtr->_x2, obj->_y + obj->_currImagePtr->_y2, _TLIGHTGREEN); @@ -730,10 +730,10 @@ void Screen_v1d::loadFontArr(Common::ReadStream &in) { * processed object by looking down the current column for an overlay * base byte set (in which case the object is foreground). */ -OverlayState Screen_v1d::findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y) { +OverlayState Screen_v1d::findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y) { debugC(4, kDebugDisplay, "findOvl()"); - uint16 index = (uint16)(dst_p - _frontBuffer) >> 3; + uint16 index = (uint16)(dstPtr - _frontBuffer) >> 3; for (int i = 0; i < seqPtr->_lines-y; i++) { // Each line in object if (_vm->_object->getBaseBoundary(index)) // If any overlay base byte is non-zero then the object is foreground, else back. @@ -799,14 +799,14 @@ void Screen_v1w::loadFontArr(Common::ReadStream &in) { * processed object by looking down the current column for an overlay * base bit set (in which case the object is foreground). */ -OverlayState Screen_v1w::findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y) { +OverlayState Screen_v1w::findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y) { debugC(4, kDebugDisplay, "findOvl()"); for (; y < seqPtr->_lines; y++) { // Each line in object - byte ovb = _vm->_object->getBaseBoundary((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits - if (ovb & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set + byte ovb = _vm->_object->getBaseBoundary((uint16)(dstPtr - _frontBuffer) >> 3); // Ptr into overlay bits + if (ovb & (0x80 >> ((uint16)(dstPtr - _frontBuffer) & 7))) // Overlay bit is set return kOvlForeground; // Found a bit - must be foreground - dst_p += kXPix; + dstPtr += kXPix; } return kOvlBackground; // No bits set, must be background diff --git a/engines/hugo/display.h b/engines/hugo/display.h index 5fab2f18cc..00dc1b743c 100644 --- a/engines/hugo/display.h +++ b/engines/hugo/display.h @@ -114,7 +114,7 @@ protected: inline bool isInY(const int16 y, const Rect *rect) const; inline bool isOverlapping(const Rect *rectA, const Rect *rectB) const; - virtual OverlayState findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y) = 0; + virtual OverlayState findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y) = 0; private: byte *_curPalette; @@ -150,7 +150,7 @@ public: void loadFont(int16 fontId); void loadFontArr(Common::ReadStream &in); protected: - OverlayState findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y); + OverlayState findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y); }; class Screen_v1w : public Screen { @@ -161,7 +161,7 @@ public: void loadFont(int16 fontId); void loadFontArr(Common::ReadStream &in); protected: - OverlayState findOvl(Seq *seqPtr, ImagePtr dst_p, uint16 y); + OverlayState findOvl(Seq *seqPtr, ImagePtr dstPtr, uint16 y); }; } // End of namespace Hugo diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index b78a26241b..5556f5abc0 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -92,7 +92,7 @@ const char *FileManager::getUifFilename() const { * Return original plane data ptr */ byte *FileManager::convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const { - debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, ImagePtr data_p)", y, bpl); + debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, ImagePtr dataPtr)", y, bpl); dataPtr += y * bpl * 8; // Point to correct DIB line for (int16 r = 0, g = bpl, b = g + bpl, i = b + bpl; r < bpl; r++, g++, b++, i++) { // Each byte in all planes @@ -282,7 +282,7 @@ void FileManager::readImage(const int objNum, Object *objPtr) { * Read sound (or music) file data. Call with SILENCE to free-up * any allocated memory. Also returns size of data */ -sound_pt FileManager::getSound(const int16 sound, uint16 *size) { +SoundPtr FileManager::getSound(const int16 sound, uint16 *size) { debugC(1, kDebugFile, "getSound(%d)", sound); // No more to do if SILENCE (called for cleanup purposes) @@ -298,25 +298,25 @@ sound_pt FileManager::getSound(const int16 sound, uint16 *size) { if (!_hasReadHeader) { for (int i = 0; i < kMaxSounds; i++) { - _s_hdr[i]._size = fp.readUint16LE(); - _s_hdr[i]._offset = fp.readUint32LE(); + _soundHdr[i]._size = fp.readUint16LE(); + _soundHdr[i]._offset = fp.readUint32LE(); } if (fp.err()) error("Wrong sound file format"); _hasReadHeader = true; } - *size = _s_hdr[sound]._size; + *size = _soundHdr[sound]._size; if (*size == 0) error("Wrong sound file format or missing sound %d", sound); // Allocate memory for sound or music, if possible - sound_pt soundPtr = (byte *)malloc(_s_hdr[sound]._size); // Ptr to sound data + SoundPtr soundPtr = (byte *)malloc(_soundHdr[sound]._size); // Ptr to sound data assert(soundPtr); // Seek to data and read it - fp.seek(_s_hdr[sound]._offset, SEEK_SET); - if (fp.read(soundPtr, _s_hdr[sound]._size) != _s_hdr[sound]._size) + fp.seek(_soundHdr[sound]._offset, SEEK_SET); + if (fp.read(soundPtr, _soundHdr[sound]._size) != _soundHdr[sound]._size) error("Wrong sound file format"); fp.close(); @@ -513,7 +513,7 @@ bool FileManager::restoreGame(const int16 slot) { _vm->_maze._x4 = in->readSint16BE(); _vm->_maze._firstScreenIndex = in->readByte(); - _vm->_scheduler->restoreScreen(*_vm->_screen_p); + _vm->_scheduler->restoreScreen(*_vm->_screenPtr); if ((_vm->getGameStatus()._viewState = (Vstate) in->readByte()) != kViewPlay) _vm->_screen->hideCursor(); diff --git a/engines/hugo/file.h b/engines/hugo/file.h index 151b749ce7..e4aa7f7fec 100644 --- a/engines/hugo/file.h +++ b/engines/hugo/file.h @@ -47,7 +47,7 @@ public: FileManager(HugoEngine *vm); virtual ~FileManager(); - sound_pt getSound(const int16 sound, uint16 *size); + SoundPtr getSound(const int16 sound, uint16 *size); void readBootFile(); void readImage(const int objNum, Object *objPtr); @@ -118,7 +118,7 @@ protected: // If this is the first call, read the lookup table bool _hasReadHeader; - SoundHdr _s_hdr[kMaxSounds]; // Sound lookup table + SoundHdr _soundHdr[kMaxSounds]; // Sound lookup table private: byte *convertPCC(byte *p, const uint16 y, const uint16 bpl, ImagePtr dataPtr) const; diff --git a/engines/hugo/game.h b/engines/hugo/game.h index 29e3bf9b55..ed49ee8cbe 100644 --- a/engines/hugo/game.h +++ b/engines/hugo/game.h @@ -95,7 +95,7 @@ struct hugoBoot { // Common HUGO boot file * Game specific type definitions */ typedef byte *ImagePtr; // ptr to an object image (sprite) -typedef byte *sound_pt; // ptr to sound (or music) data +typedef byte *SoundPtr; // ptr to sound (or music) data /** * Structure for initializing maze processing diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index 5ae43b8b5a..f2db630198 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -427,7 +427,7 @@ bool HugoEngine::loadHugoDat() { _scheduler->loadActListArr(in); _scheduler->loadAlNewscrIndex(in); _hero = &_object->_objects[kHeroIndex]; // This always points to hero - _screen_p = &(_object->_objects[kHeroIndex]._screenIndex); // Current screen is hero's + _screenPtr = &(_object->_objects[kHeroIndex]._screenIndex); // Current screen is hero's _heroImage = kHeroIndex; // Current in use hero image for (int varnt = 0; varnt < _numVariant; varnt++) { @@ -660,7 +660,7 @@ void HugoEngine::readScreenFiles(const int screenNum) { void HugoEngine::setNewScreen(const int screenNum) { debugC(1, kDebugEngine, "setNewScreen(%d)", screenNum); - *_screen_p = screenNum; // HERO object + *_screenPtr = screenNum; // HERO object _object->setCarriedScreen(screenNum); // Carried objects } diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 312f2272db..9f495a9037 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -226,7 +226,7 @@ public: int8 _normalTPS; // Number of ticks (frames) per second. // 8 for Win versions, 9 for DOS versions Object *_hero; - byte *_screen_p; + byte *_screenPtr; byte _heroImage; byte *_screenStates; Command _line; // Line of user text input diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index fef3cca608..a95170696c 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -223,7 +223,7 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int _vm->_screen->displayList(kDisplayAdd, 0, kDibOffY, kXPix, kInvDy); break; case kExitHotspot: // Walk to exit hotspot - i = findExit(cx, cy, *_vm->_screen_p); + i = findExit(cx, cy, *_vm->_screenPtr); x = _hotspots[i]._viewx; y = _hotspots[i]._viewy; if (x >= 0) { // Hotspot refers to an exit @@ -327,7 +327,7 @@ void MouseHandler::mouseHandler() { // Process cursor over an exit hotspot if (objId == -1) { - int i = findExit(cx, cy, *_vm->_screen_p); + int i = findExit(cx, cy, *_vm->_screenPtr); if (i != -1 && _hotspots[i]._viewx >= 0) { objId = kExitHotspot; cursorText(_vm->_text->getTextMouse(kMsExit), cx, cy, U_FONT8, _TBRIGHTWHITE); diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp index e0dd0abd49..7b4783e4d8 100644 --- a/engines/hugo/object.cpp +++ b/engines/hugo/object.cpp @@ -199,7 +199,7 @@ int16 ObjectHandler::findObject(uint16 x, uint16 y) { // Check objects on screen for (int i = 0; i < _numObj; i++, obj++) { // Object must be in current screen and "useful" - if (obj->_screenIndex == *_vm->_screen_p && (obj->_genericCmd || obj->_objValue || obj->_cmdIndex)) { + if (obj->_screenIndex == *_vm->_screenPtr && (obj->_genericCmd || obj->_objValue || obj->_cmdIndex)) { Seq *curImage = obj->_currImagePtr; // Object must have a visible image... if (curImage != 0 && obj->_cycling != kCycleInvisible) { @@ -347,7 +347,7 @@ void ObjectHandler::showTakeables() { for (int j = 0; j < _numObj; j++) { Object *obj = &_objects[j]; if ((obj->_cycling != kCycleInvisible) && - (obj->_screenIndex == *_vm->_screen_p) && + (obj->_screenIndex == *_vm->_screenPtr) && (((TAKE & obj->_genericCmd) == TAKE) || obj->_objValue)) { Utils::notifyBox(Common::String::format("You can also see:\n%s.", _vm->_text->getNoun(obj->_nounIndex, LOOK_NAME))); } diff --git a/engines/hugo/object_v1d.cpp b/engines/hugo/object_v1d.cpp index e5fedb3b2a..7f88e9e5b8 100644 --- a/engines/hugo/object_v1d.cpp +++ b/engines/hugo/object_v1d.cpp @@ -64,7 +64,7 @@ void ObjectHandler_v1d::updateImages() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling >= kCycleAlmostInvisible)) objindex[objNumb++] = i; } @@ -185,7 +185,7 @@ void ObjectHandler_v1d::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if (obj->_screenIndex == *_vm->_screen_p) { + if (obj->_screenIndex == *_vm->_screenPtr) { switch (obj->_pathType) { case kPathChase: { // Allowable motion wrt boundary @@ -272,7 +272,7 @@ void ObjectHandler_v1d::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y @@ -327,7 +327,7 @@ void ObjectHandler_v1d::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } diff --git a/engines/hugo/object_v1w.cpp b/engines/hugo/object_v1w.cpp index e1e8496d9d..61b0f2e48a 100644 --- a/engines/hugo/object_v1w.cpp +++ b/engines/hugo/object_v1w.cpp @@ -64,7 +64,7 @@ void ObjectHandler_v1w::updateImages() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling >= kCycleAlmostInvisible)) objindex[objNumb++] = i; } @@ -182,7 +182,7 @@ void ObjectHandler_v1w::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if (obj->_screenIndex == *_vm->_screen_p) { + if (obj->_screenIndex == *_vm->_screenPtr) { switch (obj->_pathType) { case kPathChase: case kPathChase2: { @@ -282,7 +282,7 @@ void ObjectHandler_v1w::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y @@ -337,7 +337,7 @@ void ObjectHandler_v1w::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } diff --git a/engines/hugo/object_v2d.cpp b/engines/hugo/object_v2d.cpp index f0d83269d5..7cb6c20dd0 100644 --- a/engines/hugo/object_v2d.cpp +++ b/engines/hugo/object_v2d.cpp @@ -64,7 +64,7 @@ void ObjectHandler_v2d::updateImages() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling >= kCycleAlmostInvisible)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling >= kCycleAlmostInvisible)) objindex[objNumb++] = i; } @@ -185,7 +185,7 @@ void ObjectHandler_v2d::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if (obj->_screenIndex == *_vm->_screen_p) { + if (obj->_screenIndex == *_vm->_screenPtr) { switch (obj->_pathType) { case kPathChase: case kPathChase2: { @@ -285,7 +285,7 @@ void ObjectHandler_v2d::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y @@ -340,7 +340,7 @@ void ObjectHandler_v2d::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } diff --git a/engines/hugo/object_v3d.cpp b/engines/hugo/object_v3d.cpp index 13c9c8c93d..7bb4b95b4a 100644 --- a/engines/hugo/object_v3d.cpp +++ b/engines/hugo/object_v3d.cpp @@ -66,7 +66,7 @@ void ObjectHandler_v3d::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if (obj->_screenIndex == *_vm->_screen_p) { + if (obj->_screenIndex == *_vm->_screenPtr) { switch (obj->_pathType) { case kPathChase: case kPathChase2: { @@ -167,7 +167,7 @@ void ObjectHandler_v3d::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_vx || obj->_vy)) { + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_vx || obj->_vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y @@ -222,7 +222,7 @@ void ObjectHandler_v3d::moveObjects() { for (int i = 0; i < _numObj; i++) { Object *obj = &_objects[i]; // Get pointer to object Seq *currImage = obj->_currImagePtr; // Get ptr to current image - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling > kCycleAlmostInvisible) && (obj->_priority == kPriorityFloating)) clearBoundary(obj->_oldx + currImage->_x1, obj->_oldx + currImage->_x2, obj->_oldy + currImage->_y2); } diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp index 68343a0374..d18cc2181c 100644 --- a/engines/hugo/parser.cpp +++ b/engines/hugo/parser.cpp @@ -164,11 +164,11 @@ void Parser::loadArrayReqs(Common::SeekableReadStream &in) { const char *Parser::useBG(const char *name) { debugC(1, kDebugEngine, "useBG(%s)", name); - ObjectList p = _backgroundObjects[*_vm->_screen_p]; + ObjectList p = _backgroundObjects[*_vm->_screenPtr]; for (int i = 0; p[i]._verbIndex != 0; i++) { if ((name == _vm->_text->getNoun(p[i]._nounIndex, 0) && p[i]._verbIndex != _vm->_look) && - ((p[i]._roomState == kStateDontCare) || (p[i]._roomState == _vm->_screenStates[*_vm->_screen_p]))) + ((p[i]._roomState == kStateDontCare) || (p[i]._roomState == _vm->_screenStates[*_vm->_screenPtr]))) return _vm->_text->getVerb(p[i]._verbIndex, 0); } diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp index f29a03f796..f29b0161f5 100644 --- a/engines/hugo/parser_v1d.cpp +++ b/engines/hugo/parser_v1d.cpp @@ -87,7 +87,7 @@ bool Parser_v1d::isNear_v1(const char *verb, const char *noun, Object *obj, char return false; } else if (obj->_carriedFl) { // Object is being carried return true; - } else if (obj->_screenIndex != *_vm->_screen_p) { // Not in same screen + } else if (obj->_screenIndex != *_vm->_screenPtr) { // Not in same screen if (obj->_objValue) strcpy (comment, _vm->_text->getTextParser(kCmtAny4)); return false; @@ -268,7 +268,7 @@ void Parser_v1d::dropObject(Object *obj) { debugC(1, kDebugParser, "dropObject(Object *obj)"); obj->_carriedFl = false; - obj->_screenIndex = *_vm->_screen_p; + obj->_screenIndex = *_vm->_screenPtr; if (obj->_seqNumb) // Don't change if no image to display obj->_cycling = kCycleNotCycling; obj->_x = _vm->_hero->_x - 1; @@ -410,7 +410,7 @@ void Parser_v1d::lineHandler() { return; } } - if ((*farComment == '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screen_p])) + if ((*farComment == '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screenPtr])) return; } while (noun); } @@ -418,7 +418,7 @@ void Parser_v1d::lineHandler() { if (*farComment != '\0') // An object matched but not near enough Utils::notifyBox(farComment); else if (!isCatchallVerb_v1(true, noun, verb, _catchallList) && - !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p]) && + !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screenPtr]) && !isCatchallVerb_v1(false, noun, verb, _catchallList)) Utils::notifyBox(_vm->_text->getTextParser(kTBEh_1d)); } diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp index 8c0da63554..3722ccc0e1 100644 --- a/engines/hugo/parser_v1w.cpp +++ b/engines/hugo/parser_v1w.cpp @@ -166,9 +166,9 @@ void Parser_v1w::lineHandler() { } // No objects match command line, try background and catchall commands - if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screen_p])) + if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screenPtr])) return; - if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p])) + if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screenPtr])) return; if (isBackgroundWord_v3(_catchallList)) diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp index 674836b90e..6d71186f49 100644 --- a/engines/hugo/parser_v2d.cpp +++ b/engines/hugo/parser_v2d.cpp @@ -160,15 +160,15 @@ void Parser_v2d::lineHandler() { return; } } - if ((*farComment != '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screen_p])) + if ((*farComment != '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screenPtr])) return; } while (noun); } noun = findNextNoun(noun); - if ( !isCatchallVerb_v1(true, noun, verb, _backgroundObjects[*_vm->_screen_p]) + if ( !isCatchallVerb_v1(true, noun, verb, _backgroundObjects[*_vm->_screenPtr]) && !isCatchallVerb_v1(true, noun, verb, _catchallList) - && !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p]) + && !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screenPtr]) && !isCatchallVerb_v1(false, noun, verb, _catchallList)) { if (*farComment != '\0') { // An object matched but not near enough Utils::notifyBox(farComment); diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp index 9bbaf49f67..a7e5896833 100644 --- a/engines/hugo/parser_v3d.cpp +++ b/engines/hugo/parser_v3d.cpp @@ -168,9 +168,9 @@ void Parser_v3d::lineHandler() { } // No objects match command line, try background and catchall commands - if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screen_p])) + if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screenPtr])) return; - if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p])) + if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screenPtr])) return; if (isBackgroundWord_v3(_catchallList)) @@ -319,7 +319,7 @@ bool Parser_v3d::isNear_v3(Object *obj, const char *verb, char *comment) const { if (obj->_carriedFl) // Object is being carried return true; - if (obj->_screenIndex != *_vm->_screen_p) { + if (obj->_screenIndex != *_vm->_screenPtr) { // Not in same screen if (obj->_objValue) strcpy(comment, _vm->_text->getTextParser(kCmtAny1)); @@ -389,7 +389,7 @@ void Parser_v3d::dropObject(Object *obj) { debugC(1, kDebugParser, "dropObject(Object *obj)"); obj->_carriedFl = false; - obj->_screenIndex = *_vm->_screen_p; + obj->_screenIndex = *_vm->_screenPtr; if ((obj->_seqNumb > 1) || (obj->_seqList[0]._imageNbr > 1)) obj->_cycling = kCycleForward; else @@ -417,7 +417,7 @@ bool Parser_v3d::isCatchallVerb_v3(ObjectList obj) const { if (isWordPresent(_vm->_text->getVerbArray(obj[i]._verbIndex)) && obj[i]._nounIndex == 0 && (!obj[i]._matchFl || !findNoun()) && ((obj[i]._roomState == kStateDontCare) || - (obj[i]._roomState == _vm->_screenStates[*_vm->_screen_p]))) { + (obj[i]._roomState == _vm->_screenStates[*_vm->_screenPtr]))) { Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex)); _vm->_scheduler->processBonus(obj[i]._bonusIndex); @@ -445,7 +445,7 @@ bool Parser_v3d::isBackgroundWord_v3(ObjectList obj) const { if (isWordPresent(_vm->_text->getVerbArray(obj[i]._verbIndex)) && isWordPresent(_vm->_text->getNounArray(obj[i]._nounIndex)) && ((obj[i]._roomState == kStateDontCare) || - (obj[i]._roomState == _vm->_screenStates[*_vm->_screen_p]))) { + (obj[i]._roomState == _vm->_screenStates[*_vm->_screenPtr]))) { Utils::notifyBox(_vm->_file->fetchString(obj[i]._commentIndex)); _vm->_scheduler->processBonus(obj[i]._bonusIndex); return true; diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index 45d72bafb1..54dae88c28 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -335,7 +335,7 @@ bool Route::findRoute(const int16 cx, const int16 cy) { Object *obj; // Ptr to object int i; for (i = 1, obj = &_vm->_object->_objects[i]; i < _vm->_object->_numObj; i++, obj++) { - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) _vm->_object->storeBoundary(obj->_oldx + obj->_currImagePtr->_x1, obj->_oldx + obj->_currImagePtr->_x2, obj->_oldy + obj->_currImagePtr->_y2); } @@ -350,7 +350,7 @@ bool Route::findRoute(const int16 cx, const int16 cy) { // Clear all object baselines from objbound for (i = 0, obj = _vm->_object->_objects; i < _vm->_object->_numObj; i++, obj++) { - if ((obj->_screenIndex == *_vm->_screen_p) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) + if ((obj->_screenIndex == *_vm->_screenPtr) && (obj->_cycling != kCycleInvisible) && (obj->_priority == kPriorityFloating)) _vm->_object->clearBoundary(obj->_oldx + obj->_currImagePtr->_x1, obj->_oldx + obj->_currImagePtr->_x2, obj->_oldy + obj->_currImagePtr->_y2); } diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 3bbec6670e..32b8a47df7 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -66,12 +66,12 @@ void Scheduler::initCypher() { void Scheduler::initEventQueue() { debugC(1, kDebugSchedule, "initEventQueue"); - // Chain next_p from first to last + // Chain nextEvent from first to last for (int i = kMaxEvents; --i;) _events[i - 1]._nextEvent = &_events[i]; _events[kMaxEvents - 1]._nextEvent = 0; - // Chain prev_p from last to first + // Chain prevEvent from last to first for (int i = 1; i < kMaxEvents; i++) _events[i]._prevEvent = &_events[i - 1]; _events[0]._prevEvent = 0; @@ -658,28 +658,28 @@ void Scheduler::processMaze(const int x1, const int x2, const int y1, const int if (x1 < _vm->_maze._x1) { // Exit west - _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p - 1; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr - 1; _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x2 - kShiftSize - (x2 - x1); _actListArr[_alNewscrIndex][0]._a2._y = _vm->_hero->_y; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } else if (x2 > _vm->_maze._x2) { // Exit east - _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p + 1; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr + 1; _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x1 + kShiftSize; _actListArr[_alNewscrIndex][0]._a2._y = _vm->_hero->_y; _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } else if (y1 < _vm->_maze._y1 - kShiftSize) { // Exit north - _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p - _vm->_maze._size; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr - _vm->_maze._size; _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x3; _actListArr[_alNewscrIndex][0]._a2._y = _vm->_maze._y2 - kShiftSize - (y2 - y1); _vm->_route->resetRoute(); insertActionList(_alNewscrIndex); } else if (y2 > _vm->_maze._y2 - kShiftSize / 2) { // Exit south - _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screen_p + _vm->_maze._size; + _actListArr[_alNewscrIndex][3]._a8._screenIndex = *_vm->_screenPtr + _vm->_maze._size; _actListArr[_alNewscrIndex][0]._a2._x = _vm->_maze._x4; _actListArr[_alNewscrIndex][0]._a2._y = _vm->_maze._y1 + kShiftSize; _vm->_route->resetRoute(); @@ -1090,10 +1090,10 @@ void Scheduler::restoreSchedulerData(Common::ReadStream *in) { void Scheduler::restoreEvents(Common::ReadStream *f) { debugC(1, kDebugSchedule, "restoreEvents"); - uint32 saveTime = f->readUint32BE(); // time of save - int16 freeIndex = f->readSint16BE(); // Free list index - int16 headIndex = f->readSint16BE(); // Head of list index - int16 tailIndex = f->readSint16BE(); // Tail of list index + uint32 saveTime = f->readUint32BE(); // time of save + int16 freeIndex = f->readSint16BE(); // Free list index + int16 headIndex = f->readSint16BE(); // Head of list index + int16 tailIndex = f->readSint16BE(); // Tail of list index // Restore events indexes to pointers for (int i = 0; i < kMaxEvents; i++) { @@ -1121,8 +1121,8 @@ void Scheduler::restoreEvents(Common::ReadStream *f) { // Adjust times to fit our time uint32 curTime = getTicks(); - Event *wrkEvent = _headEvent; // The earliest event - while (wrkEvent) { // While mature events found + Event *wrkEvent = _headEvent; // The earliest event + while (wrkEvent) { // While mature events found wrkEvent->_time = wrkEvent->_time - saveTime + curTime; wrkEvent = wrkEvent->_nextEvent; } @@ -1140,31 +1140,31 @@ void Scheduler::insertAction(Act *action) { curEvent->_action = action; switch (action->_a0._actType) { // Assign whether local or global case AGSCHEDULE: - curEvent->_localActionFl = false; // Lasts over a new screen + curEvent->_localActionFl = false; // Lasts over a new screen break; // Workaround: When dying, switch to storyMode in order to block the keyboard. case GAMEOVER: _vm->getGameStatus()._storyModeFl = true; // No break on purpose default: - curEvent->_localActionFl = true; // Rest are for current screen only + curEvent->_localActionFl = true; // Rest are for current screen only break; } curEvent->_time = action->_a0._timer + getTicks(); // Convert rel to abs time // Now find the place to insert the event - if (!_tailEvent) { // Empty queue + if (!_tailEvent) { // Empty queue _tailEvent = _headEvent = curEvent; curEvent->_nextEvent = curEvent->_prevEvent = 0; } else { - Event *wrkEvent = _tailEvent; // Search from latest time back + Event *wrkEvent = _tailEvent; // Search from latest time back bool found = false; while (wrkEvent && !found) { - if (wrkEvent->_time <= curEvent->_time) { // Found if new event later + if (wrkEvent->_time <= curEvent->_time) { // Found if new event later found = true; - if (wrkEvent == _tailEvent) // New latest in list + if (wrkEvent == _tailEvent) // New latest in list _tailEvent = curEvent; else wrkEvent->_nextEvent->_prevEvent = curEvent; @@ -1175,8 +1175,8 @@ void Scheduler::insertAction(Act *action) { wrkEvent = wrkEvent->_prevEvent; } - if (!found) { // Must be earliest in list - _headEvent->_prevEvent = curEvent; // So insert as new head + if (!found) { // Must be earliest in list + _headEvent->_prevEvent = curEvent; // So insert as new head curEvent->_nextEvent = _headEvent; curEvent->_prevEvent = 0; _headEvent = curEvent; @@ -1196,106 +1196,106 @@ Event *Scheduler::doAction(Event *curEvent) { Act *action = curEvent->_action; Object *obj1; int dx, dy; - Event *wrkEvent; // Save ev_p->next_p for return + Event *wrkEvent; // Save ev_p->nextEvent for return switch (action->_a0._actType) { - case ANULL: // Big NOP from DEL_EVENTS + case ANULL: // Big NOP from DEL_EVENTS break; - case ASCHEDULE: // act0: Schedule an action list + case ASCHEDULE: // act0: Schedule an action list insertActionList(action->_a0._actIndex); break; - case START_OBJ: // act1: Start an object cycling + case START_OBJ: // act1: Start an object cycling _vm->_object->_objects[action->_a1._objIndex]._cycleNumb = action->_a1._cycleNumb; _vm->_object->_objects[action->_a1._objIndex]._cycling = action->_a1._cycle; break; - case INIT_OBJXY: // act2: Initialize an object + case INIT_OBJXY: // act2: Initialize an object _vm->_object->_objects[action->_a2._objIndex]._x = action->_a2._x; // Coordinates _vm->_object->_objects[action->_a2._objIndex]._y = action->_a2._y; break; - case PROMPT: // act3: Prompt user for key phrase + case PROMPT: // act3: Prompt user for key phrase promptAction(action); break; - case BKGD_COLOR: // act4: Set new background color + case BKGD_COLOR: // act4: Set new background color _vm->_screen->setBackgroundColor(action->_a4._newBackgroundColor); break; - case INIT_OBJVXY: // act5: Initialize an object velocity + case INIT_OBJVXY: // act5: Initialize an object velocity _vm->_object->setVelocity(action->_a5._objIndex, action->_a5._vx, action->_a5._vy); break; - case INIT_CARRY: // act6: Initialize an object + case INIT_CARRY: // act6: Initialize an object _vm->_object->setCarry(action->_a6._objIndex, action->_a6._carriedFl); // carried status break; - case INIT_HF_COORD: // act7: Initialize an object to hero's "feet" coords + case INIT_HF_COORD: // act7: Initialize an object to hero's "feet" coords _vm->_object->_objects[action->_a7._objIndex]._x = _vm->_hero->_x - 1; _vm->_object->_objects[action->_a7._objIndex]._y = _vm->_hero->_y + _vm->_hero->_currImagePtr->_y2 - 1; - _vm->_object->_objects[action->_a7._objIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! + _vm->_object->_objects[action->_a7._objIndex]._screenIndex = *_vm->_screenPtr; // Don't forget screen! break; - case NEW_SCREEN: // act8: Start new screen + case NEW_SCREEN: // act8: Start new screen newScreen(action->_a8._screenIndex); break; - case INIT_OBJSTATE: // act9: Initialize an object state + case INIT_OBJSTATE: // act9: Initialize an object state _vm->_object->_objects[action->_a9._objIndex]._state = action->_a9._newState; break; - case INIT_PATH: // act10: Initialize an object path and velocity + case INIT_PATH: // act10: Initialize an object path and velocity _vm->_object->setPath(action->_a10._objIndex, (Path) action->_a10._newPathType, action->_a10._vxPath, action->_a10._vyPath); break; - case COND_R: // act11: action lists conditional on object state + case COND_R: // act11: action lists conditional on object state if (_vm->_object->_objects[action->_a11._objIndex]._state == action->_a11._stateReq) insertActionList(action->_a11._actPassIndex); else insertActionList(action->_a11._actFailIndex); break; - case TEXT: // act12: Text box (CF WARN) + case TEXT: // act12: Text box (CF WARN) Utils::notifyBox(_vm->_file->fetchString(action->_a12._stringIndex)); // Fetch string from file break; - case SWAP_IMAGES: // act13: Swap 2 object images + case SWAP_IMAGES: // act13: Swap 2 object images _vm->_object->swapImages(action->_a13._objIndex1, action->_a13._objIndex2); break; - case COND_SCR: // act14: Conditional on current screen + case COND_SCR: // act14: Conditional on current screen if (_vm->_object->_objects[action->_a14._objIndex]._screenIndex == action->_a14._screenReq) insertActionList(action->_a14._actPassIndex); else insertActionList(action->_a14._actFailIndex); break; - case AUTOPILOT: // act15: Home in on a (stationary) object + case AUTOPILOT: // act15: Home in on a (stationary) object _vm->_object->homeIn(action->_a15._objIndex1, action->_a15._objIndex2, action->_a15._dx, action->_a15._dy); break; - case INIT_OBJ_SEQ: // act16: Set sequence number to use + case INIT_OBJ_SEQ: // act16: Set sequence number to use // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! t>0 is safe _vm->_object->_objects[action->_a16._objIndex]._currImagePtr = _vm->_object->_objects[action->_a16._objIndex]._seqList[action->_a16._seqIndex]._seqPtr; break; - case SET_STATE_BITS: // act17: OR mask with curr obj state + case SET_STATE_BITS: // act17: OR mask with curr obj state _vm->_object->_objects[action->_a17._objIndex]._state |= action->_a17._stateMask; break; - case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state + case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state _vm->_object->_objects[action->_a18._objIndex]._state &= ~action->_a18._stateMask; break; - case TEST_STATE_BITS: // act19: If all bits set, do apass else afail + case TEST_STATE_BITS: // act19: If all bits set, do apass else afail if ((_vm->_object->_objects[action->_a19._objIndex]._state & action->_a19._stateMask) == action->_a19._stateMask) insertActionList(action->_a19._actPassIndex); else insertActionList(action->_a19._actFailIndex); break; - case DEL_EVENTS: // act20: Remove all events of this action type + case DEL_EVENTS: // act20: Remove all events of this action type delEventType(action->_a20._actTypeDel); break; - case GAMEOVER: // act21: Game over! + case GAMEOVER: // act21: Game over! // NOTE: Must wait at least 1 tick before issuing this action if // any objects are to be made invisible! gameStatus._gameOverFl = true; break; - case INIT_HH_COORD: // act22: Initialize an object to hero's actual coords + case INIT_HH_COORD: // act22: Initialize an object to hero's actual coords _vm->_object->_objects[action->_a22._objIndex]._x = _vm->_hero->_x; _vm->_object->_objects[action->_a22._objIndex]._y = _vm->_hero->_y; - _vm->_object->_objects[action->_a22._objIndex]._screenIndex = *_vm->_screen_p;// Don't forget screen! + _vm->_object->_objects[action->_a22._objIndex]._screenIndex = *_vm->_screenPtr;// Don't forget screen! break; - case EXIT: // act23: Exit game back to DOS + case EXIT: // act23: Exit game back to DOS _vm->endGame(); break; - case BONUS: // act24: Get bonus score for action + case BONUS: // act24: Get bonus score for action processBonus(action->_a24._pointIndex); break; - case COND_BOX: // act25: Conditional on bounding box + case COND_BOX: // act25: Conditional on bounding box obj1 = &_vm->_object->_objects[action->_a25._objIndex]; dx = obj1->_x + obj1->_currImagePtr->_x1; dy = obj1->_y + obj1->_currImagePtr->_y2; @@ -1305,25 +1305,25 @@ Event *Scheduler::doAction(Event *curEvent) { else insertActionList(action->_a25._actFailIndex); break; - case SOUND: // act26: Play a sound (or tune) + case SOUND: // act26: Play a sound (or tune) if (action->_a26._soundIndex < _vm->_tunesNbr) _vm->_sound->playMusic(action->_a26._soundIndex); else _vm->_sound->playSound(action->_a26._soundIndex, kSoundPriorityMedium); break; - case ADD_SCORE: // act27: Add object's value to score + case ADD_SCORE: // act27: Add object's value to score _vm->adjustScore(_vm->_object->_objects[action->_a27._objIndex]._objValue); break; - case SUB_SCORE: // act28: Subtract object's value from score + case SUB_SCORE: // act28: Subtract object's value from score _vm->adjustScore(-_vm->_object->_objects[action->_a28._objIndex]._objValue); break; - case COND_CARRY: // act29: Conditional on object being carried + case COND_CARRY: // act29: Conditional on object being carried if (_vm->_object->isCarried(action->_a29._objIndex)) insertActionList(action->_a29._actPassIndex); else insertActionList(action->_a29._actFailIndex); break; - case INIT_MAZE: // act30: Enable and init maze structure + case INIT_MAZE: // act30: Enable and init maze structure _vm->_maze._enabledFl = true; _vm->_maze._size = action->_a30._mazeSize; _vm->_maze._x1 = action->_a30._x1; @@ -1334,7 +1334,7 @@ Event *Scheduler::doAction(Event *curEvent) { _vm->_maze._x4 = action->_a30._x4; _vm->_maze._firstScreenIndex = action->_a30._firstScreenIndex; break; - case EXIT_MAZE: // act31: Disable maze mode + case EXIT_MAZE: // act31: Disable maze mode _vm->_maze._enabledFl = false; break; case INIT_PRIORITY: @@ -1343,71 +1343,71 @@ Event *Scheduler::doAction(Event *curEvent) { case INIT_SCREEN: _vm->_object->_objects[action->_a33._objIndex]._screenIndex = action->_a33._screenIndex; break; - case AGSCHEDULE: // act34: Schedule a (global) action list + case AGSCHEDULE: // act34: Schedule a (global) action list insertActionList(action->_a34._actIndex); break; - case REMAPPAL: // act35: Remap a palette color + case REMAPPAL: // act35: Remap a palette color _vm->_screen->remapPal(action->_a35._oldColorIndex, action->_a35._newColorIndex); break; - case COND_NOUN: // act36: Conditional on noun mentioned + case COND_NOUN: // act36: Conditional on noun mentioned if (_vm->_parser->isWordPresent(_vm->_text->getNounArray(action->_a36._nounIndex))) insertActionList(action->_a36._actPassIndex); else insertActionList(action->_a36._actFailIndex); break; - case SCREEN_STATE: // act37: Set new screen state + case SCREEN_STATE: // act37: Set new screen state _vm->_screenStates[action->_a37._screenIndex] = action->_a37._newState; break; - case INIT_LIPS: // act38: Position lips on object + case INIT_LIPS: // act38: Position lips on object _vm->_object->_objects[action->_a38._lipsObjIndex]._x = _vm->_object->_objects[action->_a38._objIndex]._x + action->_a38._dxLips; _vm->_object->_objects[action->_a38._lipsObjIndex]._y = _vm->_object->_objects[action->_a38._objIndex]._y + action->_a38._dyLips; - _vm->_object->_objects[action->_a38._lipsObjIndex]._screenIndex = *_vm->_screen_p; // Don't forget screen! + _vm->_object->_objects[action->_a38._lipsObjIndex]._screenIndex = *_vm->_screenPtr; // Don't forget screen! _vm->_object->_objects[action->_a38._lipsObjIndex]._cycling = kCycleForward; break; - case INIT_STORY_MODE: // act39: Init story_mode flag + case INIT_STORY_MODE: // act39: Init story_mode flag // This is similar to the QUIET path mode, except that it is // independant of it and it additionally disables the ">" prompt gameStatus._storyModeFl = action->_a39._storyModeFl; break; - case WARN: // act40: Text box (CF TEXT) + case WARN: // act40: Text box (CF TEXT) Utils::notifyBox(_vm->_file->fetchString(action->_a40._stringIndex)); break; - case COND_BONUS: // act41: Perform action if got bonus + case COND_BONUS: // act41: Perform action if got bonus if (_points[action->_a41._bonusIndex]._scoredFl) insertActionList(action->_a41._actPassIndex); else insertActionList(action->_a41._actFailIndex); break; - case TEXT_TAKE: // act42: Text box with "take" message + case TEXT_TAKE: // act42: Text box with "take" message Utils::notifyBox(Common::String::format(TAKE_TEXT, _vm->_text->getNoun(_vm->_object->_objects[action->_a42._objIndex]._nounIndex, TAKE_NAME))); break; - case YESNO: // act43: Prompt user for Yes or No + case YESNO: // act43: Prompt user for Yes or No if (Utils::yesNoBox(_vm->_file->fetchString(action->_a43._promptIndex))) insertActionList(action->_a43._actYesIndex); else insertActionList(action->_a43._actNoIndex); break; - case STOP_ROUTE: // act44: Stop any route in progress + case STOP_ROUTE: // act44: Stop any route in progress _vm->_route->resetRoute(); break; - case COND_ROUTE: // act45: Conditional on route in progress + case COND_ROUTE: // act45: Conditional on route in progress if (_vm->_route->getRouteIndex() >= action->_a45._routeIndex) insertActionList(action->_a45._actPassIndex); else insertActionList(action->_a45._actFailIndex); break; - case INIT_JUMPEXIT: // act46: Init status.jumpexit flag + case INIT_JUMPEXIT: // act46: Init status.jumpexit flag // This is to allow left click on exit to get there immediately // For example the plane crash in Hugo2 where hero is invisible // Couldn't use INVISIBLE flag since conflicts with boat in Hugo1 _vm->_mouse->setJumpExitFl(action->_a46._jumpExitFl); break; - case INIT_VIEW: // act47: Init object._viewx, viewy, dir + case INIT_VIEW: // act47: Init object._viewx, viewy, dir _vm->_object->_objects[action->_a47._objIndex]._viewx = action->_a47._viewx; _vm->_object->_objects[action->_a47._objIndex]._viewy = action->_a47._viewy; _vm->_object->_objects[action->_a47._objIndex]._direction = action->_a47._direction; break; - case INIT_OBJ_FRAME: // act48: Set seq,frame number to use + case INIT_OBJ_FRAME: // act48: Set seq,frame number to use // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! t>0 is safe _vm->_object->_objects[action->_a48._objIndex]._currImagePtr = _vm->_object->_objects[action->_a48._objIndex]._seqList[action->_a48._seqIndex]._seqPtr; @@ -1424,11 +1424,11 @@ Event *Scheduler::doAction(Event *curEvent) { } if (action->_a0._actType == NEW_SCREEN) { // New_screen() deletes entire list - return 0; // next_p = 0 since list now empty + return 0; // nextEvent = 0 since list now empty } else { wrkEvent = curEvent->_nextEvent; - delQueue(curEvent); // Return event to free list - return wrkEvent; // Return next event ptr + delQueue(curEvent); // Return event to free list + return wrkEvent; // Return next event ptr } } @@ -1444,9 +1444,9 @@ Event *Scheduler::doAction(Event *curEvent) { void Scheduler::delQueue(Event *curEvent) { debugC(4, kDebugSchedule, "delQueue()"); - if (curEvent == _headEvent) { // If p was the head ptr - _headEvent = curEvent->_nextEvent; // then make new head_p - } else { // Unlink p + if (curEvent == _headEvent) { // If p was the head ptr + _headEvent = curEvent->_nextEvent; // then make new head_p + } else { // Unlink p curEvent->_prevEvent->_nextEvent = curEvent->_nextEvent; if (curEvent->_nextEvent) curEvent->_nextEvent->_prevEvent = curEvent->_prevEvent; @@ -1455,12 +1455,12 @@ void Scheduler::delQueue(Event *curEvent) { } if (_headEvent) - _headEvent->_prevEvent = 0; // Mark end of list + _headEvent->_prevEvent = 0; // Mark end of list else - _tailEvent = 0; // Empty queue + _tailEvent = 0; // Empty queue - curEvent->_nextEvent = _freeEvent; // Return p to free list - if (_freeEvent) // Special case, if free list was empty + curEvent->_nextEvent = _freeEvent; // Return p to free list + if (_freeEvent) // Special case, if free list was empty _freeEvent->_prevEvent = curEvent; _freeEvent = curEvent; } @@ -1470,10 +1470,10 @@ void Scheduler::delQueue(Event *curEvent) { */ void Scheduler::delEventType(const Action _actTypeDel) { // Note: actions are not deleted here, simply turned into NOPs! - Event *wrkEvent = _headEvent; // The earliest event + Event *wrkEvent = _headEvent; // The earliest event Event *saveEvent; - while (wrkEvent) { // While events found in list + while (wrkEvent) { // While events found in list saveEvent = wrkEvent->_nextEvent; if (wrkEvent->_action->_a20._actType == _actTypeDel) delQueue(wrkEvent); @@ -1524,11 +1524,11 @@ uint32 Scheduler_v1d::getTicks() { void Scheduler_v1d::runScheduler() { debugC(6, kDebugSchedule, "runScheduler"); - uint32 ticker = getTicks(); // The time now, in ticks - Event *curEvent = _headEvent; // The earliest event + uint32 ticker = getTicks(); // The time now, in ticks + Event *curEvent = _headEvent; // The earliest event - while (curEvent && (curEvent->_time <= ticker)) // While mature events found - curEvent = doAction(curEvent); // Perform the action (returns next_p) + while (curEvent && (curEvent->_time <= ticker)) // While mature events found + curEvent = doAction(curEvent); // Perform the action (returns nextEvent) } void Scheduler_v1d::promptAction(Act *action) { @@ -1583,7 +1583,7 @@ void Scheduler_v2d::promptAction(Act *action) { debug(1, "doAction(act3), expecting answer %s", _vm->_file->fetchString(action->_a3._responsePtr[0])); bool found = false; - const char *tmpStr; // General purpose string ptr + const char *tmpStr; // General purpose string ptr for (int dx = 0; !found && (action->_a3._responsePtr[dx] != -1); dx++) { tmpStr = _vm->_file->fetchString(action->_a3._responsePtr[dx]); @@ -1638,12 +1638,12 @@ uint32 Scheduler_v1w::getTicks() { void Scheduler_v1w::runScheduler() { debugC(6, kDebugSchedule, "runScheduler"); - uint32 ticker = getTicks(); // The time now, in ticks - Event *curEvent = _headEvent; // The earliest event + uint32 ticker = getTicks(); // The time now, in ticks + Event *curEvent = _headEvent; // The earliest event - while (curEvent && (curEvent->_time <= ticker)) // While mature events found - curEvent = doAction(curEvent); // Perform the action (returns next_p) + while (curEvent && (curEvent->_time <= ticker)) // While mature events found + curEvent = doAction(curEvent); // Perform the action (returns nextEvent) - _vm->getGameStatus()._tick++; // Accessed elsewhere via getTicks() + _vm->getGameStatus()._tick++; // Accessed elsewhere via getTicks() } } // End of namespace Hugo diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp index a8b4759d9b..aefa03cd5e 100644 --- a/engines/hugo/sound.cpp +++ b/engines/hugo/sound.cpp @@ -174,7 +174,7 @@ void SoundHandler::toggleSound() { _vm->_config._soundFl = !_vm->_config._soundFl; } -void SoundHandler::playMIDI(sound_pt seqPtr, uint16 size) { +void SoundHandler::playMIDI(SoundPtr seqPtr, uint16 size) { _midiPlayer->play(seqPtr, size); } @@ -182,7 +182,7 @@ void SoundHandler::playMIDI(sound_pt seqPtr, uint16 size) { * Read a tune sequence from the sound database and start playing it */ void SoundHandler::playMusic(int16 tune) { - sound_pt seqPtr; // Sequence data from file + SoundPtr seqPtr; // Sequence data from file uint16 size; // Size of sequence data if (_vm->_config._musicFl) { @@ -198,9 +198,9 @@ void SoundHandler::playMusic(int16 tune) { * Override currently playing sound only if lower or same priority */ void SoundHandler::playSound(int16 sound, const byte priority) { - // uint32 dwVolume; // Left, right volume of sound - sound_pt sound_p; // Sound data - uint16 size; // Size of data + // uint32 dwVolume; // Left, right volume of sound + SoundPtr soundPtr; // Sound data + uint16 size; // Size of data // Sound disabled if (!_vm->_config._soundFl || !_vm->_mixer->isReady()) @@ -210,10 +210,10 @@ void SoundHandler::playSound(int16 sound, const byte priority) { _curPriority = priority; // Get sound data - if ((sound_p = _vm->_file->getSound(sound, &size)) == 0) + if ((soundPtr = _vm->_file->getSound(sound, &size)) == 0) return; - Audio::AudioStream *stream = Audio::makeRawStream(sound_p, size, 11025, Audio::FLAG_UNSIGNED); + Audio::AudioStream *stream = Audio::makeRawStream(soundPtr, size, 11025, Audio::FLAG_UNSIGNED); _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, stream); } diff --git a/engines/hugo/sound.h b/engines/hugo/sound.h index cb6d4e3168..b00d93eeb1 100644 --- a/engines/hugo/sound.h +++ b/engines/hugo/sound.h @@ -97,7 +97,7 @@ private: void stopSound(); void stopMusic(); - void playMIDI(sound_pt seq_p, uint16 size); + void playMIDI(SoundPtr seqPtr, uint16 size); }; } // End of namespace Hugo -- cgit v1.2.3 From e4f08a4644c5a59b8e02b3702eef436e52e2d994 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 13 Jun 2012 22:55:27 +0300 Subject: SCI: Fix the loading screen and the loading functionality in Shivers Shivers uses extra special hardcoded save files together with the normal ones that are used to store slot names and spot descriptions. The scheme is a bit odd, and since the names of the extra save files are hardcoded, this scheme is problematic to use. We skip the creation of these files altogether and use virtual files instead, which means that the (broken) spot descriptions won't be visible next to each save description. This isn't a major issue for now, and it's left as a future TODO to implement this feature in a cleaner way, and not with extra save files. This scheme fixes the slot descriptions in the loading screen. Also, kCD(1) has been implemented, which fixes loading of the save states themselves --- engines/sci/engine/file.cpp | 8 ++++- engines/sci/engine/file.h | 1 + engines/sci/engine/kfile.cpp | 85 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 78 insertions(+), 16 deletions(-) diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp index 66f54d67df..3470d23fe2 100644 --- a/engines/sci/engine/file.cpp +++ b/engines/sci/engine/file.cpp @@ -346,6 +346,12 @@ VirtualIndexFile::VirtualIndexFile(Common::String fileName) : _fileName(fileName delete inFile; } +VirtualIndexFile::VirtualIndexFile(uint32 initialSize) : _changed(false) { + _bufferSize = initialSize; + _buffer = new char[_bufferSize]; + _ptr = _buffer; +} + VirtualIndexFile::~VirtualIndexFile() { close(); @@ -430,7 +436,7 @@ bool VirtualIndexFile::seek(int32 offset, int whence) { } void VirtualIndexFile::close() { - if (_changed) { + if (_changed && !_fileName.empty()) { Common::WriteStream *outFile = g_sci->getSaveFileManager()->openForSaving(_fileName); outFile->write(_buffer, _bufferSize); delete outFile; diff --git a/engines/sci/engine/file.h b/engines/sci/engine/file.h index 896dcd2a42..1c8e302d15 100644 --- a/engines/sci/engine/file.h +++ b/engines/sci/engine/file.h @@ -115,6 +115,7 @@ private: class VirtualIndexFile { public: VirtualIndexFile(Common::String fileName); + VirtualIndexFile(uint32 initialSize); ~VirtualIndexFile(); uint32 read(char *buffer, uint32 size); diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 445a019368..7a2f161829 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -199,6 +199,9 @@ reg_t kCD(EngineState *s, int argc, reg_t *argv) { case 0: // Return whether the contents of disc argv[1] is available. return TRUE_REG; + case 1: + // Return the current CD number + return make_reg(0, 1); default: warning("CD(%d)", argv[0].toUint16()); } @@ -219,21 +222,6 @@ reg_t kFileIO(EngineState *s, int argc, reg_t *argv) { reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { Common::String name = s->_segMan->getString(argv[0]); -#ifdef ENABLE_SCI32 - if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { - if (s->_virtualIndexFile) { - return make_reg(0, VIRTUALFILE_HANDLE); - } else { - Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH); - Common::String wrappedName = g_sci->wrapFilename(englishName); - if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) { - s->_virtualIndexFile = new VirtualIndexFile(wrappedName); - return make_reg(0, VIRTUALFILE_HANDLE); - } - } - } -#endif - // SCI32 can call K_FILEIO_OPEN with only one argument. It seems to // just be checking if it exists. int mode = (argc < 2) ? (int)_K_FILE_MODE_OPEN_OR_FAIL : argv[1].toUint16(); @@ -261,6 +249,73 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) { } debugC(kDebugLevelFile, "kFileIO(open): %s, 0x%x", name.c_str(), mode); +#ifdef ENABLE_SCI32 + if (name == PHANTASMAGORIA_SAVEGAME_INDEX) { + if (s->_virtualIndexFile) { + return make_reg(0, VIRTUALFILE_HANDLE); + } else { + Common::String englishName = g_sci->getSciLanguageString(name, K_LANG_ENGLISH); + Common::String wrappedName = g_sci->wrapFilename(englishName); + if (!g_sci->getSaveFileManager()->listSavefiles(wrappedName).empty()) { + s->_virtualIndexFile = new VirtualIndexFile(wrappedName); + return make_reg(0, VIRTUALFILE_HANDLE); + } + } + } + + // Shivers is trying to store savegame descriptions and current spots in + // separate .SG files, which are hardcoded in the scripts. + // Essentially, there is a normal save file, created by the executable + // and an extra hardcoded save file, created by the game scripts, probably + // because they didn't want to modify the save/load code to add the extra + // information. + // Each slot in the book then has two strings, the save description and a + // description of the current spot that the player is at. Currently, the + // spot strings are always empty (probably related to the unimplemented + // kString subop 14, which gets called right before this call). + // For now, we don't allow the creation of these files, which means that + // all the spot descriptions next to each slot description will be empty + // (they are empty anyway). Until a viable solution is found to handle these + // extra files and until the spot description strings are initialized + // correctly, we resort to virtual files in order to make the load screen + // useable. Without this code it is unusable, as the extra information is + // always saved to 0.SG for some reason, but on restore the correct file is + // used. Perhaps the virtual ID is not taken into account when saving. + // + // Future TODO: maintain spot descriptions and show them too, ideally without + // having to return to this logic of extra hardcoded files. + if (g_sci->getGameId() == GID_SHIVERS && name.hasSuffix(".SG")) { + if (mode == _K_FILE_MODE_OPEN_OR_CREATE || mode == _K_FILE_MODE_CREATE) { + // Game scripts are trying to create a file with the save + // description, stop them here + debugC(kDebugLevelFile, "Not creating unused file %s", name.c_str()); + return SIGNAL_REG; + } else if (mode == _K_FILE_MODE_OPEN_OR_FAIL) { + // Create a virtual file containing the save game description + // and slot number, as the game scripts expect. + int slotNumber; + sscanf(name.c_str(), "%d.SG", &slotNumber); + + Common::Array saves; + listSavegames(saves); + int savegameNr = findSavegame(saves, slotNumber - SAVEGAMEID_OFFICIALRANGE_START); + + if (!s->_virtualIndexFile) { + // Make the virtual file buffer big enough to avoid having it grow dynamically. + // 50 bytes should be more than enough. + s->_virtualIndexFile = new VirtualIndexFile(50); + } + + s->_virtualIndexFile->seek(0, SEEK_SET); + s->_virtualIndexFile->write(saves[savegameNr].name, strlen(saves[savegameNr].name)); + s->_virtualIndexFile->write("\0", 1); + s->_virtualIndexFile->write("\0", 1); // Spot description (empty) + s->_virtualIndexFile->seek(0, SEEK_SET); + return make_reg(0, VIRTUALFILE_HANDLE); + } + } +#endif + // QFG import rooms get a virtual filelisting instead of an actual one if (g_sci->inQfGImportRoom()) { // We need to find out what the user actually selected, "savedHeroes" is -- cgit v1.2.3 From 87eb651886ef911d8026d777abec72c88ffdf32f Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 14 Jun 2012 00:19:34 +0100 Subject: TOON: Migrate Character API x,y coordinates and subclasses to int16. This harmonises the usage with Common::Point. --- engines/toon/character.cpp | 34 ++++++++++++++++------------------ engines/toon/character.h | 28 ++++++++++++++-------------- engines/toon/drew.cpp | 2 +- engines/toon/drew.h | 2 +- engines/toon/flux.cpp | 4 ++-- engines/toon/flux.h | 2 +- 6 files changed, 35 insertions(+), 37 deletions(-) diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index 260296cc9f..2a28642f6a 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -81,7 +81,7 @@ Character::~Character(void) { void Character::init() { } -void Character::forceFacing( int32 facing ) { +void Character::forceFacing(int32 facing) { debugC(4, kDebugCharacter, "forceFacing(%d)", facing); _facing = facing; } @@ -136,8 +136,7 @@ void Character::setFacing(int32 facing) { _facing = facing; } -void Character::forcePosition(int32 x, int32 y) { - +void Character::forcePosition(int16 x, int16 y) { debugC(5, kDebugCharacter, "forcePosition(%d, %d)", x, y); setPosition(x, y); @@ -145,7 +144,7 @@ void Character::forcePosition(int32 x, int32 y) { _finalY = y; } -void Character::setPosition(int32 x, int32 y) { +void Character::setPosition(int16 x, int16 y) { debugC(5, kDebugCharacter, "setPosition(%d, %d)", x, y); _x = x; @@ -155,7 +154,7 @@ void Character::setPosition(int32 x, int32 y) { return; } -bool Character::walkTo(int32 newPosX, int32 newPosY) { +bool Character::walkTo(int16 newPosX, int16 newPosY) { debugC(1, kDebugCharacter, "walkTo(%d, %d)", newPosX, newPosY); if (!_visible) @@ -168,21 +167,19 @@ bool Character::walkTo(int32 newPosX, int32 newPosY) { // don't allow flux to go at the same position as drew if (_id == 1 ) { - int32 sizeX = MAX(5, 30 * _vm->getDrew()->getScale() / 1024); - int32 sizeY = MAX(2, 20 * _vm->getDrew()->getScale() / 1024); + int16 sizeX = MAX(5, 30 * _vm->getDrew()->getScale() / 1024); + int16 sizeY = MAX(2, 20 * _vm->getDrew()->getScale() / 1024); _vm->getPathFinding()->addBlockingEllipse(_vm->getDrew()->getFinalX(), _vm->getDrew()->getFinalY(), sizeX, sizeY); } - int16 tempFinalX, tempFinalY; - _vm->getPathFinding()->findClosestWalkingPoint(newPosX, newPosY, &tempFinalX, &tempFinalY, _x, _y); - _finalX = tempFinalX, _finalY = tempFinalY; // FIXME - Bodge to match types... + _vm->getPathFinding()->findClosestWalkingPoint(newPosX, newPosY, &_finalX, &_finalY, _x, _y); if (_x == _finalX && _y == _finalY) return true; if (_vm->getPathFinding()->findPath(_x, _y, _finalX, _finalY)) { - int32 localFinalX = _finalX; - int32 localFinalY = _finalY; + int16 localFinalX = _finalX; + int16 localFinalY = _finalY; int32 smoothDx = 0; int32 smoothDy = 0; @@ -266,10 +263,11 @@ int32 Character::getFlag() { return _flags; } -int32 Character::getX() { +int16 Character::getX() { return _x; } -int32 Character::getY() { + +int16 Character::getY() { return _y; } @@ -529,7 +527,7 @@ void Character::update(int32 timeIncrement) { } // adapted from Kyra -int32 Character::getFacingFromDirection(int32 dx, int32 dy) { +int32 Character::getFacingFromDirection(int16 dx, int16 dy) { debugC(4, kDebugCharacter, "getFacingFromDirection(%d, %d)", dx, dy); static const int facingTable[] = { @@ -640,7 +638,7 @@ void Character::load(Common::ReadStream *stream) { // "not visible" flag. if (_flags & 0x100) { _flags &= ~0x100; - setVisible(false); + setVisible(false); } } @@ -1080,11 +1078,11 @@ void Character::setDefaultSpecialAnimationId(int32 defaultAnimationId) { _animSpecialDefaultId = defaultAnimationId; } -int32 Character::getFinalX() { +int16 Character::getFinalX() { return _finalX; } -int32 Character::getFinalY() { +int16 Character::getFinalY() { return _finalY; } diff --git a/engines/toon/character.h b/engines/toon/character.h index d06a6c060c..d2d84a8c9b 100644 --- a/engines/toon/character.h +++ b/engines/toon/character.h @@ -65,13 +65,13 @@ public: virtual int32 getFlag(); virtual int32 getAnimFlag(); virtual void setAnimFlag(int32 flag); - virtual void setPosition(int32 x, int32 y); - virtual void forcePosition(int32 x, int32 y); - virtual int32 getX(); - virtual int32 getY(); - virtual int32 getFinalX(); - virtual int32 getFinalY(); - virtual bool walkTo(int32 newPosX, int32 newPosY); + virtual void setPosition(int16 x, int16 y); + virtual void forcePosition(int16 x, int16 y); + virtual int16 getX(); + virtual int16 getY(); + virtual int16 getFinalX(); + virtual int16 getFinalY(); + virtual bool walkTo(int16 newPosX, int16 newPosY); virtual bool getVisible(); virtual void setVisible(bool visible); virtual bool loadWalkAnimation(const Common::String &animName); @@ -99,7 +99,7 @@ public: virtual void resetScale() {} virtual void plotPath(Graphics::Surface& surface); - int32 getFacingFromDirection(int32 dx, int32 dy); + int32 getFacingFromDirection(int16 dx, int16 dy); static const SpecialCharacterAnimation *getSpecialAnimation(int32 characterId, int32 animationId); protected: @@ -112,11 +112,11 @@ protected: int32 _sceneAnimationId; int32 _lineToSayId; int32 _time; - int32 _x; - int32 _y; + int16 _x; + int16 _y; int32 _z; - int32 _finalX; - int32 _finalY; + int16 _finalX; + int16 _finalY; int32 _facing; int32 _flags; int32 _animFlags; @@ -137,8 +137,8 @@ protected: Animation *_shadowAnim; Animation *_specialAnim; - int32 _currentPathX[4096]; - int32 _currentPathY[4096]; + int16 _currentPathX[4096]; + int16 _currentPathY[4096]; int32 _currentPathNodeCount; int32 _currentPathNode; int32 _currentWalkStamp; diff --git a/engines/toon/drew.cpp b/engines/toon/drew.cpp index df5cfcfa03..dfd3f515fa 100644 --- a/engines/toon/drew.cpp +++ b/engines/toon/drew.cpp @@ -48,7 +48,7 @@ bool CharacterDrew::setupPalette() { return false; } -void CharacterDrew::setPosition(int32 x, int32 y) { +void CharacterDrew::setPosition(int16 x, int16 y) { debugC(5, kDebugCharacter, "setPosition(%d, %d)", x, y); _z = _vm->getLayerAtPoint(x, y); diff --git a/engines/toon/drew.h b/engines/toon/drew.h index 3357b99846..ff1b619125 100644 --- a/engines/toon/drew.h +++ b/engines/toon/drew.h @@ -35,7 +35,7 @@ public: virtual ~CharacterDrew(); bool setupPalette(); void playStandingAnim(); - void setPosition(int32 x, int32 y); + void setPosition(int16 x, int16 y); void resetScale(); void update(int32 timeIncrement); void playWalkAnim(int32 start, int32 end); diff --git a/engines/toon/flux.cpp b/engines/toon/flux.cpp index b752e65c82..70aa40fb36 100644 --- a/engines/toon/flux.cpp +++ b/engines/toon/flux.cpp @@ -45,7 +45,7 @@ void CharacterFlux::playStandingAnim() { _animationInstance->stopAnimation(); _animationInstance->setLooping(true); - //s/etVisible(true); + //setVisible(true); } void CharacterFlux::setVisible(bool visible) { @@ -99,7 +99,7 @@ int32 CharacterFlux::fixFacingForAnimation(int32 originalFacing, int32 animation return finalFacing; } -void CharacterFlux::setPosition(int32 x, int32 y) { +void CharacterFlux::setPosition(int16 x, int16 y) { debugC(5, kDebugCharacter, "setPosition(%d, %d)", x, y); _z = _vm->getLayerAtPoint(x, y); diff --git a/engines/toon/flux.h b/engines/toon/flux.h index c208bc5bda..1dc0d9c55f 100644 --- a/engines/toon/flux.h +++ b/engines/toon/flux.h @@ -34,7 +34,7 @@ public: CharacterFlux(ToonEngine *vm); virtual ~CharacterFlux(); - void setPosition(int32 x, int32 y); + void setPosition(int16 x, int16 y); void playStandingAnim(); void playWalkAnim(int32 start, int32 end); void update(int32 timeIncrement); -- cgit v1.2.3 From b9057761df4de1b314aaec9eb7b14653863bb031 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 14 Jun 2012 02:36:45 +0300 Subject: SCI: Add missing documentation for the plane_items / pi console command --- engines/sci/console.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 6a44972a4b..94ac437a15 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -373,6 +373,7 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" animate_list / al - Shows the current list of objects in kAnimate's draw list (SCI0 - SCI1.1)\n"); DebugPrintf(" window_list / wl - Shows a list of all the windows (ports) in the draw list (SCI0 - SCI1.1)\n"); DebugPrintf(" plane_list / pl - Shows a list of all the planes in the draw list (SCI2+)\n"); + DebugPrintf(" plane_items / pi - Shows a list of all items for a plane (SCI2+)\n"); DebugPrintf(" saved_bits - List saved bits on the hunk\n"); DebugPrintf(" show_saved_bits - Display saved bits\n"); DebugPrintf("\n"); -- cgit v1.2.3 From 84ed361370a83d1806cd146562c4debf3a6aa767 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 14 Jun 2012 02:59:52 +0200 Subject: GUI: Remove unused SaveLoadChooser::setList. --- gui/saveload.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/saveload.h b/gui/saveload.h index e81b10d214..a19f5ab083 100644 --- a/gui/saveload.h +++ b/gui/saveload.h @@ -66,7 +66,7 @@ public: ~SaveLoadChooser(); virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); - void setList(const StringArray& list); + /** * Runs the save/load chooser with the currently active config manager * domain as target. -- cgit v1.2.3 From 0a3fb38bc728c11654810d426819853d86ae609c Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 14 Jun 2012 12:10:39 +0300 Subject: SCI: Add handling of two more configuration settings for LSL7 --- engines/sci/engine/kmisc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 47c891eefd..2e80764d01 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -388,6 +388,12 @@ reg_t kGetConfig(EngineState *s, int argc, reg_t *argv) { // Used to enable the debug mode in Torin's Passage (French). // If true, the debug mode is enabled. s->_segMan->strcpy(data, ""); + } else if (setting == "leakdump") { + // An unknown setting in LSL7. Likely used for debugging. + s->_segMan->strcpy(data, ""); + } else if (setting == "startroom") { + // Debug setting in LSL7, specifies the room to start from. + s->_segMan->strcpy(data, ""); } else { error("GetConfig: Unknown configuration setting %s", setting.c_str()); } -- cgit v1.2.3 From 21b6b81f16abc4af90a7e21974d51ad7a984f1ed Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 14 Jun 2012 12:12:30 +0300 Subject: SCI: A separate implementation is needed for syncStringHeap() for SCI3 --- engines/sci/engine/savegame.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 404bea799d..7c41e18bec 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -467,7 +467,7 @@ void Script::syncStringHeap(Common::Serializer &s) { break; } while (1); - } else { + } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1){ // Strings in SCI1.1 come after the object instances byte *buf = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2; @@ -477,6 +477,8 @@ void Script::syncStringHeap(Common::Serializer &s) { // Now, sync everything till the end of the buffer s.syncBytes(buf, _heapSize - (buf - _heapStart)); + } else if (getSciVersion() == SCI_VERSION_3) { + warning("TODO: syncStringHeap(): Implement SCI3 variant"); } } -- cgit v1.2.3 From 9c8ff41181955048abd602f1d58639e2082182c7 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 14 Jun 2012 12:14:04 +0300 Subject: SCI: Add known large SCI3 scripts --- engines/sci/engine/script.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 8b26969f4a..5f0118b5b6 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -115,6 +115,13 @@ void Script::init(int script_nr, ResourceManager *resMan) { // scheme. We need an overlaying mechanism, or a mechanism to split script parts // in different segments to handle these. For now, simply stop when such a script // is found. + // + // Known large SCI 3 scripts are: + // Lighthouse: 9, 220, 270, 351, 360, 490, 760, 765, 800 + // LSL7: 240, 511, 550 + // Phantasmagoria 2: none (hooray!) + // RAMA: 70 + // // TODO: Remove this once such a mechanism is in place if (script->size > 65535) error("TODO: SCI script %d is over 64KB - it's %d bytes long. This can't " -- cgit v1.2.3 From 27f2b6e4dd829663f771fec0651b8a1e31514a90 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 14 Jun 2012 12:15:57 +0300 Subject: SCI: Change the script buffer size to be a size_t as well This will be needed in the future to load large SCI3 scripts --- engines/sci/engine/script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 1ebae3b7a8..a180579d2f 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -57,7 +57,7 @@ private: int _lockers; /**< Number of classes and objects that require this script */ size_t _scriptSize; size_t _heapSize; - uint16 _bufSize; + size_t _bufSize; const uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */ uint16 _numExports; /**< Number of entries in the exports table */ -- cgit v1.2.3 From d2eab05e7d08bd5e4e615ee786e62be64293060a Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 14 Jun 2012 13:38:45 +0100 Subject: TOON: Replace Character _currentPath static buffers with Common::Array. --- engines/toon/character.cpp | 57 ++++++++++++++++++++++------------------------ engines/toon/character.h | 9 ++++---- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index 2a28642f6a..c9073de587 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -56,7 +56,6 @@ Character::Character(ToonEngine *vm) : _vm(vm) { _animScriptId = -1; _animSpecialId = -1; _animSpecialDefaultId = 0; - _currentPathNodeCount = 0; _currentPathNode = 0; _currentWalkStamp = 0; _visible = true; @@ -123,7 +122,7 @@ void Character::setFacing(int32 facing) { _lastWalkTime = _vm->getOldMilli(); } - if (_currentPathNode == 0) + if (_currentPathNode == 0) playStandingAnim(); else playWalkAnim(0, 0); @@ -166,7 +165,7 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) { _vm->getPathFinding()->resetBlockingRects(); // don't allow flux to go at the same position as drew - if (_id == 1 ) { + if (_id == 1) { int16 sizeX = MAX(5, 30 * _vm->getDrew()->getScale() / 1024); int16 sizeY = MAX(2, 20 * _vm->getDrew()->getScale() / 1024); _vm->getPathFinding()->addBlockingEllipse(_vm->getDrew()->getFinalX(), _vm->getDrew()->getFinalY(), sizeX, sizeY); @@ -183,11 +182,9 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) { int32 smoothDx = 0; int32 smoothDy = 0; - for (uint32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++) { - _currentPathX[a] = _vm->getPathFinding()->getPathNodeX(a); - _currentPathY[a] = _vm->getPathFinding()->getPathNodeY(a); - } - _currentPathNodeCount = _vm->getPathFinding()->getPathNodeCount(); + _currentPath.clear(); + for (uint32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++) + _currentPath.push_back(Common::Point(_vm->getPathFinding()->getPathNodeX(a), _vm->getPathFinding()->getPathNodeY(a))); _currentPathNode = 0; stopSpecialAnim(); @@ -202,12 +199,12 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) { int32 localWalkStamp = _currentWalkStamp; if (_blockingWalk) { - while ((_x != newPosX || _y != newPosY) && _currentPathNode < _currentPathNodeCount && !_vm->shouldQuitGame()) { - if (_currentPathNode < _currentPathNodeCount - 4) { - int32 delta = MIN(4, _currentPathNodeCount - _currentPathNode); + while ((_x != newPosX || _y != newPosY) && _currentPathNode < _currentPath.size() && !_vm->shouldQuitGame()) { + if (_currentPathNode < _currentPath.size() - 4) { + int32 delta = MIN(4, _currentPath.size() - _currentPathNode); - int32 dx = _currentPathX[_currentPathNode+delta] - _x; - int32 dy = _currentPathY[_currentPathNode+delta] - _y; + int16 dx = _currentPath[_currentPathNode+delta].x - _x; + int16 dy = _currentPath[_currentPathNode+delta].y - _y; // smooth the facing computation. It prevents some ugly flickering from happening if (!smoothDx && !smoothDy) { @@ -226,9 +223,9 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) { _numPixelToWalk += _speed * (_vm->getSystem()->getMillis() - _lastWalkTime) * _scale / 1024; _lastWalkTime = _vm->getSystem()->getMillis(); - while (_numPixelToWalk >= 1000 && _currentPathNode < _currentPathNodeCount) { - _x = _currentPathX[_currentPathNode]; - _y = _currentPathY[_currentPathNode]; + while (_numPixelToWalk >= 1000 && _currentPathNode < _currentPath.size()) { + _x = _currentPath[_currentPathNode].x; + _y = _currentPath[_currentPathNode].y; _currentPathNode += 1; _numPixelToWalk -= 1000; } @@ -244,7 +241,7 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) { playStandingAnim(); _flags &= ~0x1; _currentPathNode = 0; - _currentPathNodeCount = 0; + _currentPath.clear(); if (_x != localFinalX || _y != localFinalY) { return false; @@ -348,12 +345,12 @@ void Character::stopSpecialAnim() { void Character::update(int32 timeIncrement) { debugC(5, kDebugCharacter, "update(%d)", timeIncrement); - if ((_flags & 0x1) && _currentPathNodeCount > 0) { - if (_currentPathNode < _currentPathNodeCount) { - if (_currentPathNode < _currentPathNodeCount - 10) { - int32 delta = MIN(10, _currentPathNodeCount - _currentPathNode); - int32 dx = _currentPathX[_currentPathNode+delta] - _x; - int32 dy = _currentPathY[_currentPathNode+delta] - _y; + if ((_flags & 0x1) && _currentPath.size() > 0) { + if (_currentPathNode < _currentPath.size()) { + if (_currentPathNode < _currentPath.size() - 10) { + int32 delta = MIN(10, _currentPath.size() - _currentPathNode); + int16 dx = _currentPath[_currentPathNode+delta].x - _x; + int16 dy = _currentPath[_currentPathNode+delta].y - _y; setFacing(getFacingFromDirection(dx, dy)); playWalkAnim(0, 0); } @@ -362,9 +359,9 @@ void Character::update(int32 timeIncrement) { _numPixelToWalk += _speed * (_vm->getSystem()->getMillis() - _lastWalkTime) * _scale / 1024; _lastWalkTime = _vm->getSystem()->getMillis(); - while (_numPixelToWalk > 1000 && _currentPathNode < _currentPathNodeCount) { - _x = _currentPathX[_currentPathNode]; - _y = _currentPathY[_currentPathNode]; + while (_numPixelToWalk > 1000 && _currentPathNode < _currentPath.size()) { + _x = _currentPath[_currentPathNode].x; + _y = _currentPath[_currentPathNode].y; _currentPathNode += 1; _numPixelToWalk -= 1000; } @@ -372,7 +369,7 @@ void Character::update(int32 timeIncrement) { } else { playStandingAnim(); _flags &= ~0x1; - _currentPathNodeCount = 0; + _currentPath.clear(); } } @@ -664,7 +661,7 @@ void Character::stopWalk() { _finalY = _y; _flags &= ~0x1; _currentPathNode = 0; - _currentPathNodeCount = 0; + _currentPath.clear(); } const SpecialCharacterAnimation *Character::getSpecialAnimation(int32 characterId, int32 animationId) { @@ -996,8 +993,8 @@ bool Character::loadShadowAnimation(const Common::String &animName) { } void Character::plotPath(Graphics::Surface& surface) { - for (int i = 0; i < _currentPathNodeCount; i++) { - *(byte *)surface.getBasePtr(_currentPathX[i], _currentPathY[i]) = ( i < _currentPathNode); + for (uint32 i = 0; i < _currentPath.size(); i++) { + *(byte *)surface.getBasePtr(_currentPath[i].x, _currentPath[i].y) = (i < _currentPathNode); } } diff --git a/engines/toon/character.h b/engines/toon/character.h index d2d84a8c9b..d33c314bf7 100644 --- a/engines/toon/character.h +++ b/engines/toon/character.h @@ -23,6 +23,9 @@ #ifndef TOON_CHARACTER_H #define TOON_CHARACTER_H +#include "common/array.h" +#include "common/rect.h" + #include "toon/toon.h" namespace Toon { @@ -137,10 +140,8 @@ protected: Animation *_shadowAnim; Animation *_specialAnim; - int16 _currentPathX[4096]; - int16 _currentPathY[4096]; - int32 _currentPathNodeCount; - int32 _currentPathNode; + Common::Array _currentPath; + uint32 _currentPathNode; int32 _currentWalkStamp; }; -- cgit v1.2.3 From 198c116061d58c19e5a0bd97f47925bb7d585923 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 14:40:33 +0200 Subject: GOB: Fix stupid typo/bug I introduced in 2007 Luckily, it apparently didn't have any visible symptoms... --- engines/gob/mult.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index 06a7130cef..b3d7ea6263 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -366,10 +366,11 @@ void Mult::doPalAnim() { palPtr->blue, 0, 0x13); palPtr = _vm->_global->_pPaletteDesc->vgaPal; - for (_counter = 0; _counter < 16; _counter++, palPtr++) + for (_counter = 0; _counter < 16; _counter++, palPtr++) { _vm->_global->_redPalette[_counter] = palPtr->red; _vm->_global->_greenPalette[_counter] = palPtr->green; _vm->_global->_bluePalette[_counter] = palPtr->blue; + } } else _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -- cgit v1.2.3 From ccad083ab905b1e708bc9b7b3db501c9f1f028ab Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 15:24:49 +0200 Subject: GOB: Fix a "condition depends on uninitialised value" in Geisha --- engines/gob/palanim.cpp | 93 +++++++++++++------------------------------------ 1 file changed, 24 insertions(+), 69 deletions(-) diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp index 8a5327c3f1..f90b141725 100644 --- a/engines/gob/palanim.cpp +++ b/engines/gob/palanim.cpp @@ -75,47 +75,28 @@ bool PalAnim::fadeStepColor(int color) { bool PalAnim::fadeStep(int16 oper) { bool stop = true; - byte newRed; - byte newGreen; - byte newBlue; if (oper == 0) { - if (_vm->_global->_setAllPalette) { - if (_vm->_global->_inVM != 0) - error("PalAnim::fadeStep(): _vm->_global->_inVM != 0 not supported"); - - for (int i = 0; i < 256; i++) { - newRed = fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]); - newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]); - newBlue = fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]); - - if ((_vm->_global->_redPalette[i] != newRed) || - (_vm->_global->_greenPalette[i] != newGreen) || - (_vm->_global->_bluePalette[i] != newBlue)) { - - _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13); - - _vm->_global->_redPalette[i] = newRed; - _vm->_global->_greenPalette[i] = newGreen; - _vm->_global->_bluePalette[i] = newBlue; - stop = false; - } - } - } else { - for (int i = 0; i < 16; i++) { - - _vm->_video->setPalElem(i, - fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]), - fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]), - fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]), - -1, _vm->_global->_videoMode); - - if ((_vm->_global->_redPalette[i] != _toFadeRed[i]) || - (_vm->_global->_greenPalette[i] != _toFadeGreen[i]) || - (_vm->_global->_bluePalette[i] != _toFadeBlue[i])) - stop = false; + int colorCount = _vm->_global->_setAllPalette ? _vm->_global->_colorCount : 256; + + for (int i = 0; i < colorCount; i++) { + byte newRed = fadeColor(_vm->_global->_redPalette [i], _toFadeRed [i]); + byte newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]); + byte newBlue = fadeColor(_vm->_global->_bluePalette [i], _toFadeBlue [i]); + + if ((_vm->_global->_redPalette [i] != newRed ) || + (_vm->_global->_greenPalette[i] != newGreen) || + (_vm->_global->_bluePalette [i] != newBlue)) { + + _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13); + + _vm->_global->_redPalette [i] = newRed; + _vm->_global->_greenPalette[i] = newGreen; + _vm->_global->_bluePalette [i] = newBlue; + stop = false; } } + } else if ((oper > 0) && (oper < 4)) stop = fadeStepColor(oper - 1); @@ -124,44 +105,18 @@ bool PalAnim::fadeStep(int16 oper) { void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { bool stop; - int16 i; if (_vm->shouldQuit()) return; _fadeValue = (fadeV < 0) ? -fadeV : 2; - if (!_vm->_global->_setAllPalette) { - if (!palDesc) { - for (i = 0; i < 16; i++) { - _toFadeRed[i] = 0; - _toFadeGreen[i] = 0; - _toFadeBlue[i] = 0; - } - } else { - for (i = 0; i < 16; i++) { - _toFadeRed[i] = palDesc->vgaPal[i].red; - _toFadeGreen[i] = palDesc->vgaPal[i].green; - _toFadeBlue[i] = palDesc->vgaPal[i].blue; - } - } - } else { - if (_vm->_global->_inVM != 0) - error("PalAnim::fade(): _vm->_global->_inVM != 0 is not supported"); - - if (!palDesc) { - for (i = 0; i < 256; i++) { - _toFadeRed[i] = 0; - _toFadeGreen[i] = 0; - _toFadeBlue[i] = 0; - } - } else { - for (i = 0; i < 256; i++) { - _toFadeRed[i] = palDesc->vgaPal[i].red; - _toFadeGreen[i] = palDesc->vgaPal[i].green; - _toFadeBlue[i] = palDesc->vgaPal[i].blue; - } - } + int colorCount = _vm->_global->_setAllPalette ? _vm->_global->_colorCount : 256; + + for (int i = 0; i < colorCount; i++) { + _toFadeRed [i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].red; + _toFadeGreen[i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].green; + _toFadeBlue [i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].blue; } if (allColors == 0) { -- cgit v1.2.3 From 0e6fb437799ba8f35776c59c02a02d59a99a71cf Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 15:27:37 +0200 Subject: GOB: Remove useless variable --- engines/gob/global.cpp | 1 - engines/gob/global.h | 1 - engines/gob/init_v1.cpp | 2 -- engines/gob/init_v2.cpp | 2 -- 4 files changed, 6 deletions(-) diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index 1264c09860..87656a5fad 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -111,7 +111,6 @@ Global::Global(GobEngine *vm) : _vm(vm) { _dontSetPalette = false; _debugFlag = 0; - _inVM = 0; _inter_animDataSize = 10; diff --git a/engines/gob/global.h b/engines/gob/global.h index fa2f2c9637..175331dd83 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -127,7 +127,6 @@ public: SurfacePtr _primarySurfDesc; int16 _debugFlag; - int16 _inVM; int16 _inter_animDataSize; diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp index 25d521aca6..a8e8cbe2c3 100644 --- a/engines/gob/init_v1.cpp +++ b/engines/gob/init_v1.cpp @@ -41,8 +41,6 @@ void Init_v1::initVideo() { _vm->_global->_mousePresent = 1; - _vm->_global->_inVM = 0; - if ((_vm->_global->_videoMode == 0x13) && !_vm->isEGA()) _vm->_global->_colorCount = 256; diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp index 1289d561ea..c204b04a40 100644 --- a/engines/gob/init_v2.cpp +++ b/engines/gob/init_v2.cpp @@ -45,8 +45,6 @@ void Init_v2::initVideo() { _vm->_global->_mousePresent = 1; - _vm->_global->_inVM = 0; - _vm->_global->_colorCount = 16; if (!_vm->isEGA() && ((_vm->getPlatform() == Common::kPlatformPC) || -- cgit v1.2.3 From 5ae4ed09ea9b0ffd4ef00e55eb1f738103fdeeeb Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 15:33:30 +0200 Subject: GOB: Fix an uninitialised value in Geisha's Penetration --- engines/gob/minigames/geisha/submarine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index d16761cb7c..bf15306e5a 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -51,7 +51,7 @@ enum Animation { }; -Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) { +Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove), _direction(kDirectionNone) { turn(kDirectionN); } -- cgit v1.2.3 From 4aa0ec7fc4eae0941efb15affe664544c33822ea Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 14 Jun 2012 17:23:01 +0100 Subject: TOON: Change Pathfinding weight buffers to uint16. This should result in a significant saving in RAM usage. Have added warning outputs if the weights exceed the maximum limit. --- engines/toon/path.cpp | 34 +++++++++++++++++++--------------- engines/toon/path.h | 8 ++++---- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/engines/toon/path.cpp b/engines/toon/path.cpp index 735801eebc..7914aed595 100644 --- a/engines/toon/path.cpp +++ b/engines/toon/path.cpp @@ -60,7 +60,7 @@ void PathFindingHeap::clear() { memset(_data, 0, sizeof(HeapDataGrid) * _size); } -void PathFindingHeap::push(int16 x, int16 y, int16 weight) { +void PathFindingHeap::push(int16 x, int16 y, uint16 weight) { debugC(2, kDebugPath, "push(%d, %d, %d)", x, y, weight); if (_count == _size) { @@ -104,7 +104,7 @@ void PathFindingHeap::push(int16 x, int16 y, int16 weight) { } } -void PathFindingHeap::pop(int16 *x, int16 *y, int16 *weight) { +void PathFindingHeap::pop(int16 *x, int16 *y, uint16 *weight) { debugC(2, kDebugPath, "pop(x, y, weight)"); if (!_count) { @@ -170,7 +170,7 @@ void PathFinding::init(Picture *mask) { _heap->unload(); _heap->init(500); delete[] _sq; - _sq = new int32[_width * _height]; + _sq = new uint16[_width * _height]; } bool PathFinding::isLikelyWalkable(int16 x, int16 y) { @@ -304,18 +304,16 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { } // no direct line, we use the standard A* algorithm - memset(_sq , 0, _width * _height * sizeof(int32)); + memset(_sq , 0, _width * _height * sizeof(uint16)); _heap->clear(); int16 curX = x; int16 curY = y; - int16 curWeight = 0; + uint16 curWeight = 0; _sq[curX + curY *_width] = 1; _heap->push(curX, curY, abs(destx - x) + abs(desty - y)); - int16 wei; while (_heap->getCount()) { - wei = 0; _heap->pop(&curX, &curY, &curWeight); int32 curNode = curX + curY * _width; @@ -328,15 +326,23 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { for (int16 px = startX; px <= endX && !next; px++) { for (int16 py = startY; py <= endY && !next; py++) { if (px != curX || py != curY) { - wei = abs(px - curX) + abs(py - curY); + uint16 wei = abs(px - curX) + abs(py - curY); - int32 curPNode = px + py * _width; if (isWalkable(px, py)) { // walkable ? - int32 sum = _sq[curNode] + wei * (1 + (isLikelyWalkable(px, py) ? 5 : 0)); + int32 curPNode = px + py * _width; + uint32 sum = _sq[curNode] + wei * (1 + (isLikelyWalkable(px, py) ? 5 : 0)); + if (sum > (uint32)0xFFFF) { + warning("PathFinding::findPath sum exceeds maximum representable!"); + sum = (uint32)0xFFFF; + } if (_sq[curPNode] > sum || !_sq[curPNode]) { - int32 newWeight = abs(destx - px) + abs(desty - py); _sq[curPNode] = sum; - _heap->push(px, py, _sq[curPNode] + newWeight); + uint32 newWeight = _sq[curPNode] + abs(destx - px) + abs(desty - py); + if (newWeight > (uint32)0xFFFF) { + warning("PathFinding::findPath newWeight exceeds maximum representable!"); + newWeight = (uint16)0xFFFF; + } + _heap->push(px, py, newWeight); if (!newWeight) next = true; // we found it ! } @@ -359,7 +365,7 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { Common::Array retPath; retPath.push_back(Common::Point(curX, curY)); - int32 bestscore = _sq[destx + desty * _width]; + uint16 bestscore = _sq[destx + desty * _width]; bool retVal = false; while (true) { @@ -374,8 +380,6 @@ bool PathFinding::findPath(int16 x, int16 y, int16 destx, int16 desty) { for (int16 px = startX; px <= endX; px++) { for (int16 py = startY; py <= endY; py++) { if (px != curX || py != curY) { - wei = abs(px - curX) + abs(py - curY); - int32 PNode = px + py * _width; if (_sq[PNode] && (isWalkable(px, py))) { if (_sq[PNode] < bestscore) { diff --git a/engines/toon/path.h b/engines/toon/path.h index 2476dc3b8a..59f74ef286 100644 --- a/engines/toon/path.h +++ b/engines/toon/path.h @@ -36,8 +36,8 @@ public: PathFindingHeap(); ~PathFindingHeap(); - void push(int16 x, int16 y, int16 weight); - void pop(int16 *x, int16 *y, int16 *weight); + void push(int16 x, int16 y, uint16 weight); + void pop(int16 *x, int16 *y, uint16 *weight); void init(int32 size); void clear(); void unload(); @@ -46,7 +46,7 @@ public: private: struct HeapDataGrid { int16 _x, _y; - int16 _weight; + uint16 _weight; }; HeapDataGrid *_data; @@ -84,7 +84,7 @@ private: PathFindingHeap *_heap; - int32 *_sq; + uint16 *_sq; int16 _width; int16 _height; -- cgit v1.2.3 From acaf8f762382f1aa886d4a3f5b0b8b662863f01c Mon Sep 17 00:00:00 2001 From: D G Turner Date: Thu, 14 Jun 2012 21:02:44 +0100 Subject: TOON: Fix two latent off-by-one errors in Character Class. These were exposed by assertions from Common::Array usage. --- engines/toon/character.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/toon/character.cpp b/engines/toon/character.cpp index c9073de587..09730626f2 100644 --- a/engines/toon/character.cpp +++ b/engines/toon/character.cpp @@ -201,7 +201,7 @@ bool Character::walkTo(int16 newPosX, int16 newPosY) { if (_blockingWalk) { while ((_x != newPosX || _y != newPosY) && _currentPathNode < _currentPath.size() && !_vm->shouldQuitGame()) { if (_currentPathNode < _currentPath.size() - 4) { - int32 delta = MIN(4, _currentPath.size() - _currentPathNode); + int32 delta = MIN(4, _currentPath.size() - 1 - _currentPathNode); int16 dx = _currentPath[_currentPathNode+delta].x - _x; int16 dy = _currentPath[_currentPathNode+delta].y - _y; @@ -348,7 +348,7 @@ void Character::update(int32 timeIncrement) { if ((_flags & 0x1) && _currentPath.size() > 0) { if (_currentPathNode < _currentPath.size()) { if (_currentPathNode < _currentPath.size() - 10) { - int32 delta = MIN(10, _currentPath.size() - _currentPathNode); + int32 delta = MIN(10, _currentPath.size() - 1 - _currentPathNode); int16 dx = _currentPath[_currentPathNode+delta].x - _x; int16 dy = _currentPath[_currentPathNode+delta].y - _y; setFacing(getFacingFromDirection(dx, dy)); -- cgit v1.2.3 From 3b8b3c4caffc8a19a7ad4c4fa55bad712f0e5fce Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 23:39:33 +0200 Subject: GOB: Fix a failed assert in Litte Red Riding Hood --- engines/gob/inter_v1.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 6fc472a0ac..3652637e32 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1584,14 +1584,13 @@ void Inter_v1::o1_waitEndPlay(OpFuncParams ¶ms) { } void Inter_v1::o1_playComposition(OpFuncParams ¶ms) { - int16 composition[50]; - int16 dataVar; - int16 freqVal; + int16 dataVar = _vm->_game->_script->readVarIndex(); + int16 freqVal = _vm->_game->_script->readValExpr(); - dataVar = _vm->_game->_script->readVarIndex(); - freqVal = _vm->_game->_script->readValExpr(); + int16 composition[50]; + int maxEntries = MIN(50, (_variables->getSize() - dataVar) / 4); for (int i = 0; i < 50; i++) - composition[i] = (int16) VAR_OFFSET(dataVar + i * 4); + composition[i] = (i < maxEntries) ? ((int16) VAR_OFFSET(dataVar + i * 4)) : -1; _vm->_sound->blasterPlayComposition(composition, freqVal); } -- cgit v1.2.3 From 59b2a84552ae4f64e3e6ddc8b29ecda4f3dd524d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 00:51:03 +0200 Subject: GOB: Add a proper GameType for Little Red --- engines/gob/detection_tables.h | 32 ++++++++++++++++---------------- engines/gob/gob.cpp | 1 + engines/gob/gob.h | 3 ++- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index 77b54a19cd..bd35900473 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -1615,7 +1615,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1629,7 +1629,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1643,7 +1643,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1657,7 +1657,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1671,7 +1671,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1689,7 +1689,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesNone, 0, 0, 0 }, @@ -1703,7 +1703,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1717,7 +1717,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1731,7 +1731,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1745,7 +1745,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1759,7 +1759,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1773,7 +1773,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1787,7 +1787,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1801,7 +1801,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1815,7 +1815,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1829,7 +1829,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 4e7aa467b5..acd8fcb468 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -438,6 +438,7 @@ bool GobEngine::initGameParts() { break; case kGameTypeWeen: + case kGameTypeLittleRed: case kGameTypeGob2: _init = new Init_v2(this); _video = new Video_v2(this); diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 6277585015..165760e6d5 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -127,7 +127,8 @@ enum GameType { kGameTypeAdi2, kGameTypeAdi4, kGameTypeAdibou2, - kGameTypeAdibou1 + kGameTypeAdibou1, + kGameTypeLittleRed }; enum Features { -- cgit v1.2.3 From f16cc050e97de6339347a650b9a801153dc7ad91 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 00:56:55 +0200 Subject: GOB: Add class Inter_LittleRed This fixes the crash when selecting an animal in the "Languages" screen. Interestingly, the German names of the animals are partially wrong... And for "Das Schmetterling" (sic!), even the recorded speech sample is wrong. --- engines/gob/gob.cpp | 12 +++++++++- engines/gob/inter.h | 11 +++++++++ engines/gob/inter_littlered.cpp | 49 +++++++++++++++++++++++++++++++++++++++++ engines/gob/inter_v2.cpp | 6 ++--- engines/gob/module.mk | 1 + 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 engines/gob/inter_littlered.cpp diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index acd8fcb468..a13f6a372f 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -438,7 +438,6 @@ bool GobEngine::initGameParts() { break; case kGameTypeWeen: - case kGameTypeLittleRed: case kGameTypeGob2: _init = new Init_v2(this); _video = new Video_v2(this); @@ -463,6 +462,17 @@ bool GobEngine::initGameParts() { _saveLoad = new SaveLoad_v2(this, _targetName.c_str()); break; + case kGameTypeLittleRed: + _init = new Init_v2(this); + _video = new Video_v2(this); + _inter = new Inter_LittleRed(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); + break; + case kGameTypeGob3: _init = new Init_v3(this); _video = new Video_v2(this); diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 1e6f74db4e..907a275e50 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -513,6 +513,17 @@ protected: void oFascin_setWinFlags(); }; +class Inter_LittleRed : public Inter_v2 { +public: + Inter_LittleRed(GobEngine *vm); + virtual ~Inter_LittleRed() {} + +protected: + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); +}; + class Inter_v3 : public Inter_v2 { public: Inter_v3(GobEngine *vm); diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp new file mode 100644 index 0000000000..6a63998216 --- /dev/null +++ b/engines/gob/inter_littlered.cpp @@ -0,0 +1,49 @@ +/* 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 "gob/gob.h" +#include "gob/inter.h" + +namespace Gob { + +#define OPCODEVER Inter_LittleRed +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) + +Inter_LittleRed::Inter_LittleRed(GobEngine *vm) : Inter_v2(vm) { +} + +void Inter_LittleRed::setupOpcodesDraw() { + Inter_v2::setupOpcodesDraw(); +} + +void Inter_LittleRed::setupOpcodesFunc() { + Inter_v2::setupOpcodesFunc(); +} + +void Inter_LittleRed::setupOpcodesGob() { + OPCODEGOB(500, o2_playProtracker); + OPCODEGOB(501, o2_stopProtracker); +} + +} // End of namespace Gob diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 54f6a1acc1..cb58fe86f7 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1248,7 +1248,7 @@ void Inter_v2::o2_checkData(OpFuncParams ¶ms) { file = "EMAP2011.TOT"; int32 size = -1; - SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file.c_str()); + SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(file.c_str()) : SaveLoad::kSaveModeNone; if (mode == SaveLoad::kSaveModeNone) { size = _vm->_dataIO->fileSize(file); @@ -1277,7 +1277,7 @@ void Inter_v2::o2_readData(OpFuncParams ¶ms) { debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)", file, dataVar, size, offset); - SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file); + SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(file) : SaveLoad::kSaveModeNone; if (mode == SaveLoad::kSaveModeSave) { WRITE_VAR(1, 1); @@ -1349,7 +1349,7 @@ void Inter_v2::o2_writeData(OpFuncParams ¶ms) { WRITE_VAR(1, 1); - SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file); + SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(file) : SaveLoad::kSaveModeNone; if (mode == SaveLoad::kSaveModeSave) { if (!_vm->_saveLoad->save(file, dataVar, size, offset)) { diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 7c5d7de158..20214ea940 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -44,6 +44,7 @@ MODULE_OBJS := \ inter_v2.o \ inter_bargon.o \ inter_fascin.o \ + inter_littlered.o \ inter_inca2.o \ inter_playtoons.o \ inter_v3.o \ -- cgit v1.2.3 From 90999d8f8ca9bc0554dcb353a4ee143299bf8bc3 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 03:03:36 +0200 Subject: AUDIO: Implement a missing Protracker feature When a row has a new period, but no new sample, restart the track's last sample (except when we're doing portamento). --- audio/mods/protracker.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/audio/mods/protracker.cpp b/audio/mods/protracker.cpp index 084b0edf9a..1e18d5adf8 100644 --- a/audio/mods/protracker.cpp +++ b/audio/mods/protracker.cpp @@ -61,6 +61,7 @@ private: struct { byte sample; + byte lastSample; uint16 period; Offset offset; @@ -184,6 +185,7 @@ void ProtrackerStream::updateRow() { _track[track].vibratoPos = 0; } _track[track].sample = note.sample; + _track[track].lastSample = note.sample; _track[track].finetune = _module.sample[note.sample - 1].finetune; _track[track].vol = _module.sample[note.sample - 1].vol; } @@ -194,7 +196,9 @@ void ProtrackerStream::updateRow() { _track[track].period = _module.noteToPeriod(note.note, _track[track].finetune); else _track[track].period = note.period; + _track[track].offset = Offset(0); + _track[track].sample = _track[track].lastSample; } } -- cgit v1.2.3 From a529d960917850d5e7a89293d615e28d9130468a Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 15 Jun 2012 00:38:45 -0400 Subject: SCUMM: Adjust some wiz image ops and flood fill rects Fixes black lines appearing on the field in football/football2002 and some soccer2004 menus. --- engines/scumm/he/script_v100he.cpp | 6 ++++++ engines/scumm/he/script_v90he.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index 3e2053790e..a2eb42214b 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -876,6 +876,7 @@ void ScummEngine_v100he::o100_floodFill() { _floodFillParams.box.top = 0; _floodFillParams.box.right = 639; _floodFillParams.box.bottom = 479; + adjustRect(_floodFillParams.box); break; case 6: _floodFillParams.y = pop(); @@ -886,6 +887,7 @@ void ScummEngine_v100he::o100_floodFill() { _floodFillParams.box.right = pop(); _floodFillParams.box.top = pop(); _floodFillParams.box.left = pop(); + adjustRect(_floodFillParams.box); break; case 20: _floodFillParams.flags = pop(); @@ -1345,6 +1347,7 @@ void ScummEngine_v100he::o100_wizImageOps() { _wizParams.fillColor = pop(); _wizParams.box2.top = _wizParams.box2.bottom = pop(); _wizParams.box2.left = _wizParams.box2.right = pop(); + adjustRect(_wizParams.box2); break; case 135: _wizParams.processFlags |= kWPFDstResNum; @@ -1358,6 +1361,7 @@ void ScummEngine_v100he::o100_wizImageOps() { _wizParams.box2.right = pop(); _wizParams.box2.top = pop(); _wizParams.box2.left = pop(); + adjustRect(_wizParams.box2); break; case 137: _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2; @@ -1365,6 +1369,7 @@ void ScummEngine_v100he::o100_wizImageOps() { _wizParams.fillColor = pop(); _wizParams.box2.top = _wizParams.box2.bottom = pop(); _wizParams.box2.left = _wizParams.box2.right = pop(); + adjustRect(_wizParams.box2); break; case 138: _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2; @@ -1374,6 +1379,7 @@ void ScummEngine_v100he::o100_wizImageOps() { _wizParams.box2.right = pop(); _wizParams.box2.top = pop(); _wizParams.box2.left = pop(); + adjustRect(_wizParams.box2); break; default: error("o100_wizImageOps: Unknown case %d", subOp); diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index 9e8ac7e2f2..0c3d5b3399 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -244,6 +244,7 @@ void ScummEngine_v90he::o90_wizImageOps() { _wizParams.box2.right = pop(); _wizParams.box2.top = pop(); _wizParams.box2.left = pop(); + adjustRect(_wizParams.box2); break; case 134: // HE99+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2; @@ -253,6 +254,7 @@ void ScummEngine_v90he::o90_wizImageOps() { _wizParams.box2.right = pop(); _wizParams.box2.top = pop(); _wizParams.box2.left = pop(); + adjustRect(_wizParams.box2); break; case 135: // HE99+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2; @@ -260,6 +262,7 @@ void ScummEngine_v90he::o90_wizImageOps() { _wizParams.fillColor = pop(); _wizParams.box2.top = _wizParams.box2.bottom = pop(); _wizParams.box2.left = _wizParams.box2.right = pop(); + adjustRect(_wizParams.box2); break; case 136: // HE99+ _wizParams.processFlags |= kWPFFillColor | kWPFClipBox2; @@ -267,6 +270,7 @@ void ScummEngine_v90he::o90_wizImageOps() { _wizParams.fillColor = pop(); _wizParams.box2.top = _wizParams.box2.bottom = pop(); _wizParams.box2.left = _wizParams.box2.right = pop(); + adjustRect(_wizParams.box2); break; case 137: // HE99+ _wizParams.processFlags |= kWPFDstResNum; @@ -1488,6 +1492,7 @@ void ScummEngine_v90he::o90_floodFill() { _floodFillParams.box.top = 0; _floodFillParams.box.right = 639; _floodFillParams.box.bottom = 479; + adjustRect(_floodFillParams.box); break; case 65: _floodFillParams.y = pop(); @@ -1501,6 +1506,7 @@ void ScummEngine_v90he::o90_floodFill() { _floodFillParams.box.right = pop(); _floodFillParams.box.top = pop(); _floodFillParams.box.left = pop(); + adjustRect(_floodFillParams.box); break; case 255: floodFill(&_floodFillParams, this); -- cgit v1.2.3 From 83e014f2bdf0dc20b37996063c6deb959ffab20d Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 15 Jun 2012 01:09:28 -0400 Subject: SCUMM: Fix rect bounds in getPolygonOverlap() --- engines/scumm/he/script_v90he.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index 0c3d5b3399..1ea9960a18 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -1672,7 +1672,7 @@ void ScummEngine_v90he::o90_getPolygonOverlap() { { Common::Rect r2; _sprite->getSpriteBounds(args2[0], false, r2); - Common::Rect r1(args1[0], args1[1], args1[2], args1[3]); + Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1); if (r2.isValidRect() == false) { push(0); break; @@ -1717,7 +1717,7 @@ void ScummEngine_v90he::o90_getPolygonOverlap() { { Common::Rect r2; _sprite->getSpriteBounds(args2[0], true, r2); - Common::Rect r1(args1[0], args1[1], args1[2], args1[3]); + Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1); if (r2.isValidRect() == false) { push(0); break; -- cgit v1.2.3 From a5c23f73fc5cd082368a110250ea03f26a9c8a50 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Fri, 15 Jun 2012 18:58:29 +1000 Subject: NEWS: Add Fixes in HE98 version of Pajama Sam's Lost & Found. --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index acff8b8473..4db976b0d8 100644 --- a/NEWS +++ b/NEWS @@ -53,6 +53,7 @@ For a more comprehensive changelog of the latest experimental code, see: SCUMM: - Added support for the Macintosh version of SPY Fox in Hold the Mustard. - Added a difficulty selection dialog for Loom FM-TOWNS. + - Fixed graphical glitches in HE98 version of Pajama Sam's Lost & Found. iPhone port: - Changed "F5 (menu)" gesture to open up the global main menu instead. -- cgit v1.2.3 From 85e0a90f4adb1e2b811ca7c02ad594ecdcd11bea Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Fri, 15 Jun 2012 19:20:03 +1000 Subject: SCUMM: The target and Wii releases of a few HE games are HE101, since they have differce in debugInput opcode too. --- devtools/scumm-md5.txt | 6 +++--- engines/scumm/scumm-md5.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/devtools/scumm-md5.txt b/devtools/scumm-md5.txt index 5223d6785d..176f04aaf8 100644 --- a/devtools/scumm-md5.txt +++ b/devtools/scumm-md5.txt @@ -632,9 +632,9 @@ pajama Pajama Sam 1: No Need to Hide When It's Dark Outside a095e33061606d231ff37dca4c64c8ac -1 de All HE 99 - - Joachim Eberhard 898eaa21f79cf8d4f08db856244689ff 66505 en Windows HE 99 Updated - Joachim Eberhard 37aed3f91c1ef959e0bd265f9b13781f -1 us All HE 100 Updated - Kirben - 782393c5934ecd0b536eaf5fd541bd26 -1 en Windows HE 100 Updated - Jonathan 4aa93cb30e485b728504ba3a693f12bf -1 ru Windows HE 100 - - sev - c225bec1b6c0798a2b8c89ac226dc793 -1 en Wii HE 100 - - sanguinehearts + 782393c5934ecd0b536eaf5fd541bd26 -1 en Windows HE 101 Updated - Jonathan + c225bec1b6c0798a2b8c89ac226dc793 -1 en Wii HE 101 - - sanguinehearts f237bf8a5ef9af78b2a6a4f3901da341 18354 en All - Demo - khalek, sev 7f945525abcd48015adf1632637a44a1 -1 fr All - Demo - Kirben @@ -841,7 +841,7 @@ spyfox SPY Fox 1: Dry Cereal 72ac6bc980d5101c2142189d746bd62f -1 ru Windows HE 99 - - sev 3de99ef0523f8ca7958faa3afccd035a -1 us All HE 100 Updated - Kirben 23394c8d29cc63c61313959431a12476 -1 en Windows HE 100 Updated - Jonathan - 50b831f11b8c4b83784cf81f4dcc69ea -1 en Wii HE 100 - - sanguinehearts + 50b831f11b8c4b83784cf81f4dcc69ea -1 en Wii HE 101 - - sanguinehearts 15878e3bee2e1e759184abee98589eaa -1 en iOS HE 100 - - clone2727 53e94115b55dd51d4b8ff0871aa1df1e 20103 en All - Demo - khalek, sev diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 9aac4a082f..0814e3bfe1 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Tue Jun 5 16:56:40 2012 + This file was generated by the md5table tool on Fri Jun 15 09:16:45 2012 DO NOT EDIT MANUALLY! */ @@ -227,7 +227,7 @@ static const MD5Table md5table[] = { { "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows }, { "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows }, { "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows }, - { "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii }, + { "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii }, { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC }, { "51305e929e330e24a75a0351c8f9975e", "freddi2", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "513f91a9dbe8d5490b39e56a3ac5bbdf", "pajama2", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, @@ -334,7 +334,7 @@ static const MD5Table md5table[] = { { "7766c9487f9d53a8cb0edabda5119c3d", "puttputt", "HE 60", "", 8022, Common::EN_ANY, Common::kPlatformPC }, { "77f5c9cc0986eb729c1a6b4c8823bbae", "zakloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns }, { "780e4a0ae2ff17dc296f4a79543b44f8", "puttmoon", "", "", -1, Common::UNK_LANG, Common::kPlatformPC }, - { "782393c5934ecd0b536eaf5fd541bd26", "pajama", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, + { "782393c5934ecd0b536eaf5fd541bd26", "pajama", "HE 101", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "784b499c98d07260a30952685758636b", "pajama3", "", "Demo", 13911, Common::DE_DEU, Common::kPlatformWindows }, { "78bd5f036ea35a878b74e4f47941f784", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, @@ -494,7 +494,7 @@ static const MD5Table md5table[] = { { "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", -1, Common::NL_NLD, Common::kPlatformWindows }, { "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD }, { "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, - { "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii }, + { "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii }, { "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST }, { "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "c30ef068add4277104243c31ce46c12b", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformAmiga }, -- cgit v1.2.3 From 425926ed7ebde1fa77f3874498a6f285af75ac08 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 11:33:28 +0300 Subject: SCI: Limit floodfill hack to GK1 Fixes the intro of LSL7 and the inventory screen in PQ4 --- engines/sci/graphics/frameout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index db49497b6b..dff332458a 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -647,7 +647,7 @@ void GfxFrameout::kernelFrameout() { // Since I first wrote the patch, the race has stopped occurring for me though. // I'll leave this for investigation later, when someone can reproduce. //if (it->pictureId == kPlanePlainColored) // FIXME: This is what SSCI does, and fixes the intro of LSL7, but breaks the dialogs in GK1 (adds black boxes) - if (it->pictureId == kPlanePlainColored && it->planeBack) + if (it->pictureId == kPlanePlainColored && (it->planeBack || g_sci->getGameId() != GID_GK1)) _paint32->fillRect(it->planeRect, it->planeBack); _coordAdjuster->pictureSetDisplayArea(it->planeRect); -- cgit v1.2.3 From 577d7e41c9ca2c498dc85e41c373fbdca8d2ed41 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 11:44:54 +0300 Subject: SCI: Change Script::getObject() to accept a reg_t This is needed for upcoming changes to the Script class --- engines/sci/engine/kernel.cpp | 2 +- engines/sci/engine/script.cpp | 14 +++++++------- engines/sci/engine/script.h | 4 ++-- engines/sci/engine/seg_manager.cpp | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index c99bc4fe47..0266414b26 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -377,7 +377,7 @@ uint16 Kernel::findRegType(reg_t reg) { if (reg.offset <= (*(Script *)mobj).getBufSize() && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) { - result |= ((Script *)mobj)->getObject(reg.offset) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE; + result |= ((Script *)mobj)->getObject(reg) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE; } else result |= SIG_TYPE_REFERENCE; break; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 5f0118b5b6..08f7922b1e 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -243,16 +243,16 @@ const byte *Script::getSci3ObjectsPointer() { return ptr; } -Object *Script::getObject(uint16 offset) { - if (_objects.contains(offset)) - return &_objects[offset]; +Object *Script::getObject(reg_t pos) { + if (_objects.contains(pos.offset)) + return &_objects[pos.offset]; else return 0; } -const Object *Script::getObject(uint16 offset) const { - if (_objects.contains(offset)) - return &_objects[offset]; +const Object *Script::getObject(reg_t pos) const { + if (_objects.contains(pos.offset)) + return &_objects[pos.offset]; else return 0; } @@ -746,7 +746,7 @@ Common::Array Script::listAllDeallocatable(SegmentId segId) const { Common::Array Script::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; if (addr.offset <= _bufSize && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(_buf + addr.offset)) { - const Object *obj = getObject(addr.offset); + const Object *obj = getObject(addr); if (obj) { // Note all local variables, if we have a local variable environment if (_localsSegment) diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index a180579d2f..06a7f089ba 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -119,8 +119,8 @@ public: virtual void saveLoadWithSerializer(Common::Serializer &ser); - Object *getObject(uint16 offset); - const Object *getObject(uint16 offset) const; + Object *getObject(reg_t pos); + const Object *getObject(reg_t pos) const; /** * Initializes an object within the segment manager diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index cc127c8dbc..cfa83a7697 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -228,7 +228,7 @@ Object *SegManager::getObject(reg_t pos) const { Script *scr = (Script *)mobj; if (pos.offset <= scr->getBufSize() && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(scr->getBuf(pos.offset))) { - obj = scr->getObject(pos.offset); + obj = scr->getObject(pos); } } } -- cgit v1.2.3 From e1ae1108601cce0ad7aeab5f3e017f630f02e7ea Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 11:48:56 +0300 Subject: SCI: Clean up the script initialization code --- engines/sci/engine/script.cpp | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 08f7922b1e..f8c5539325 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -37,17 +37,22 @@ Script::Script() : SegmentObj(SEG_TYPE_SCRIPT) { _buf = NULL; _bufSize = 0; _scriptSize = 0; - _heapSize = 0; - _synonyms = NULL; _heapStart = NULL; + _heapSize = 0; + _exportTable = NULL; + _numExports = 0; + _synonyms = NULL; + _numSynonyms = 0; _localsOffset = 0; _localsSegment = 0; _localsBlock = NULL; _localsCount = 0; + _lockers = 1; + _markedAsDeleted = false; } @@ -65,25 +70,11 @@ void Script::freeScript() { void Script::init(int script_nr, ResourceManager *resMan) { Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0); - if (!script) error("Script %d not found", script_nr); - _localsOffset = 0; - _localsBlock = NULL; - _localsCount = 0; - - _markedAsDeleted = false; - _nr = script_nr; - _buf = 0; - _heapStart = 0; - - _scriptSize = script->size; - _bufSize = script->size; - _heapSize = 0; - - _lockers = 1; + _bufSize = _scriptSize = script->size; if (getSciVersion() == SCI_VERSION_0_EARLY) { _bufSize += READ_LE_UINT16(script->data) * 2; @@ -163,11 +154,6 @@ void Script::load(ResourceManager *resMan) { memcpy(_heapStart, heap->data, heap->size); } - _exportTable = 0; - _numExports = 0; - _synonyms = 0; - _numSynonyms = 0; - if (getSciVersion() <= SCI_VERSION_1_LATE) { _exportTable = (const uint16 *)findBlockSCI0(SCI_OBJ_EXPORTS); if (_exportTable) { -- cgit v1.2.3 From 9aaefbd53665cd03359ad692d64e3fc437f97202 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 11:53:19 +0300 Subject: SCI: _propertyOffsetsSci3 and classpos should be 32-bit integers These are needed for future handling of large SCI3 script files --- engines/sci/engine/object.cpp | 7 ++++--- engines/sci/engine/object.h | 4 ++-- engines/sci/engine/script.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp index 78e216cdb5..2a0ed38e61 100644 --- a/engines/sci/engine/object.cpp +++ b/engines/sci/engine/object.cpp @@ -112,7 +112,7 @@ bool Object::relocateSci0Sci21(SegmentId segment, int location, size_t scriptSiz return relocateBlock(_variables, getPos().offset, segment, location, scriptSize); } -bool Object::relocateSci3(SegmentId segment, int location, int offset, size_t scriptSize) { +bool Object::relocateSci3(SegmentId segment, uint32 location, int offset, size_t scriptSize) { assert(_propertyOffsetsSci3); for (uint i = 0; i < _variables.size(); ++i) { @@ -286,7 +286,7 @@ void Object::initSelectorsSci3(const byte *buf) { _variables.resize(properties); uint16 *propertyIds = (uint16 *)malloc(sizeof(uint16) * properties); // uint16 *methodOffsets = (uint16 *)malloc(sizeof(uint16) * 2 * methods); - uint16 *propertyOffsets = (uint16 *)malloc(sizeof(uint16) * properties); + uint32 *propertyOffsets = (uint32 *)malloc(sizeof(uint32) * properties); int propertyCounter = 0; int methodCounter = 0; @@ -314,7 +314,8 @@ void Object::initSelectorsSci3(const byte *buf) { WRITE_SCI11ENDIAN_UINT16(&propertyIds[propertyCounter], groupBaseId + bit); _variables[propertyCounter] = make_reg(0, value); - propertyOffsets[propertyCounter] = (seeker + bit * 2) - buf; + uint32 propertyOffset = (seeker + bit * 2) - buf; + propertyOffsets[propertyCounter] = propertyOffset; ++propertyCounter; } else if (value != 0xffff) { // Method _baseMethod.push_back(groupBaseId + bit); diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h index 0ca16b48a2..e8deafa8bd 100644 --- a/engines/sci/engine/object.h +++ b/engines/sci/engine/object.h @@ -223,7 +223,7 @@ public: } bool relocateSci0Sci21(SegmentId segment, int location, size_t scriptSize); - bool relocateSci3(SegmentId segment, int location, int offset, size_t scriptSize); + bool relocateSci3(SegmentId segment, uint32 location, int offset, size_t scriptSize); int propertyOffsetToId(SegManager *segMan, int propertyOffset) const; @@ -238,7 +238,7 @@ private: const byte *_baseObj; /**< base + object offset within base */ const uint16 *_baseVars; /**< Pointer to the varselector area for this object */ Common::Array _baseMethod; /**< Pointer to the method selector area for this object */ - uint16 *_propertyOffsetsSci3; /**< This is used to enable relocation of property valuesa in SCI3 */ + uint32 *_propertyOffsetsSci3; /**< This is used to enable relocation of property valuesa in SCI3 */ Common::Array _variables; uint16 _methodCount; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index f8c5539325..18e23f36b5 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -546,7 +546,7 @@ void Script::initializeClasses(SegManager *segMan) { uint16 marker; bool isClass = false; - uint16 classpos; + uint32 classpos; int16 species = 0; while (true) { -- cgit v1.2.3 From 23ed0f1dc89a8557692928785bf3da355e36bc8e Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 12:04:28 +0300 Subject: SCI: Skip playing of the unsupported robot video 1003 in RAMA --- engines/sci/video/robot_decoder.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp index 95b3c2abc1..8ffcecc339 100644 --- a/engines/sci/video/robot_decoder.cpp +++ b/engines/sci/video/robot_decoder.cpp @@ -87,6 +87,13 @@ RobotDecoder::~RobotDecoder() { } bool RobotDecoder::load(GuiResourceId id) { + // TODO: RAMA's robot 1003 cannot be played (shown at the menu screen) - + // its drawn at odd coordinates. SV can't play it either (along with some + // others), so it must be some new functionality added in RAMA's robot + // videos. Skip it for now. + if (g_sci->getGameId() == GID_RAMA && id == 1003) + return false; + Common::String fileName = Common::String::format("%d.rbt", id); Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName); -- cgit v1.2.3 From 562a8a980c22eab85144558050e5fa5e425612c4 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 12:53:17 +0300 Subject: SCI: Further cleanup of the script code Merge the init() and load() Script methods and reset the script when necessary --- engines/sci/engine/savegame.cpp | 7 ++----- engines/sci/engine/script.cpp | 32 +++++++++++++------------------- engines/sci/engine/script.h | 3 +-- engines/sci/engine/seg_manager.cpp | 3 +-- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 7c41e18bec..cabe5f468a 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -189,7 +189,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { assert(mobj); - // Let the object sync custom data + // Let the object sync custom data. Scripts are loaded at this point. mobj->saveLoadWithSerializer(s); if (type == SEG_TYPE_SCRIPT) { @@ -200,9 +200,6 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) { // Hook the script up in the script->segment map _scriptSegMap[scr->getScriptNumber()] = i; - // Now, load the script itself - scr->load(g_sci->getResMan()); - ObjMap objects = scr->getObjectMap(); for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) it->_value.syncBaseObject(scr->getBuf(it->_value.getPos().offset)); @@ -486,7 +483,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_nr); if (s.isLoading()) - init(_nr, g_sci->getResMan()); + load(_nr, g_sci->getResMan()); s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _bufSize s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _scriptSize s.skip(4, VER(14), VER(22)); // OBSOLETE: Used to be _heapSize diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 18e23f36b5..7714983120 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -32,12 +32,21 @@ namespace Sci { -Script::Script() : SegmentObj(SEG_TYPE_SCRIPT) { +Script::Script() : SegmentObj(SEG_TYPE_SCRIPT), _buf(NULL) { + freeScript(); +} + +Script::~Script() { + freeScript(); +} + +void Script::freeScript() { _nr = 0; + + free(_buf); _buf = NULL; _bufSize = 0; _scriptSize = 0; - _heapStart = NULL; _heapSize = 0; @@ -52,23 +61,13 @@ Script::Script() : SegmentObj(SEG_TYPE_SCRIPT) { _localsCount = 0; _lockers = 1; - _markedAsDeleted = false; + _objects.clear(); } -Script::~Script() { +void Script::load(int script_nr, ResourceManager *resMan) { freeScript(); -} - -void Script::freeScript() { - free(_buf); - _buf = NULL; - _bufSize = 0; - - _objects.clear(); -} -void Script::init(int script_nr, ResourceManager *resMan) { Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0); if (!script) error("Script %d not found", script_nr); @@ -118,11 +117,6 @@ void Script::init(int script_nr, ResourceManager *resMan) { error("TODO: SCI script %d is over 64KB - it's %d bytes long. This can't " "be handled at the moment, thus stopping", script_nr, script->size); } -} - -void Script::load(ResourceManager *resMan) { - Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, _nr), 0); - assert(script != 0); uint extraLocalsWorkaround = 0; if (g_sci->getGameId() == GID_FANMADE && _nr == 1 && script->size == 11140) { diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 06a7f089ba..4d23ffbba8 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -95,8 +95,7 @@ public: ~Script(); void freeScript(); - void init(int script_nr, ResourceManager *resMan); - void load(ResourceManager *resMan); + void load(int script_nr, ResourceManager *resMan); void matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize); int32 findSignature(const SciScriptSignature *signature, const byte *scriptData, const uint32 scriptSize); diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index cfa83a7697..8f85577fb8 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -977,8 +977,7 @@ int SegManager::instantiateScript(int scriptNum) { scr = allocateScript(scriptNum, &segmentId); } - scr->init(scriptNum, _resMan); - scr->load(_resMan); + scr->load(scriptNum, _resMan); scr->initializeLocals(this); scr->initializeClasses(this); scr->initializeObjects(this, segmentId); -- cgit v1.2.3 From c668431522d834b24c00baf964d2b6b3f3a2bbb8 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Fri, 15 Jun 2012 12:11:01 +0100 Subject: TOON: Simplify code in Animation::drawFrameWithMaskAndScale(). --- engines/toon/anim.cpp | 49 +++++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/engines/toon/anim.cpp b/engines/toon/anim.cpp index 98c667c303..84f6fa375c 100644 --- a/engines/toon/anim.cpp +++ b/engines/toon/anim.cpp @@ -229,37 +229,26 @@ void Animation::drawFrameWithMaskAndScale(Graphics::Surface &surface, int32 fram uint8 *curRow = (uint8 *)surface.pixels; uint8 *curRowMask = mask->getDataPtr(); - if (strstr(_name, "SHADOW")) { - for (int y = yy1; y < yy2; y++) { - for (int x = xx1; x < xx2; x++) { - if (x < 0 || x >= 1280 || y < 0 || y >= 400) - continue; - - uint8 *cur = curRow + x + y * destPitch; - uint8 *curMask = curRowMask + x + y * destPitchMask; - - // find the good c - int32 xs = (x - xx1) * 1024 / scale; - int32 ys = (y - yy1) * 1024 / scale; - uint8 *cc = &c[ys * w + xs]; - if (*cc && ((*curMask) >= zz)) + bool shadowFlag = false; + if (strstr(_name, "SHADOW")) + shadowFlag = true; + + for (int32 y = yy1; y < yy2; y++) { + for (int32 x = xx1; x < xx2; x++) { + if (x < 0 || x >= 1280 || y < 0 || y >= 400) + continue; + + uint8 *cur = curRow + x + y * destPitch; + uint8 *curMask = curRowMask + x + y * destPitchMask; + + // find the good c + int32 xs = (x - xx1) * 1024 / scale; + int32 ys = (y - yy1) * 1024 / scale; + uint8 *cc = &c[ys * w + xs]; + if (*cc && ((*curMask) >= zz)) { + if (shadowFlag) *cur = _vm->getShadowLUT()[*cur]; - } - } - } else { - for (int y = yy1; y < yy2; y++) { - for (int x = xx1; x < xx2; x++) { - if (x < 0 || x >= 1280 || y < 0 || y >= 400) - continue; - - uint8 *cur = curRow + x + y * destPitch; - uint8 *curMask = curRowMask + x + y * destPitchMask; - - // find the good c - int32 xs = (x - xx1) * 1024 / scale; - int32 ys = (y - yy1) * 1024 / scale; - uint8 *cc = &c[ys * w + xs]; - if (*cc && ((*curMask) >= zz)) + else *cur = *cc; } } -- cgit v1.2.3 From 7632246264102d88922fc963284af6250ea12f57 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 13:32:43 +0200 Subject: GOB: Implement Util::getKeyState() for Little Red This makes the bees level playable, removing the "lock-up". Collision detection between Little Red and the bees and butterflies doesn't work yet though, so they're just flying through her. Nevertheless, the game seems to be completable now. --- engines/gob/inter.cpp | 12 +++++++++ engines/gob/inter.h | 9 +++++-- engines/gob/inter_littlered.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ engines/gob/inter_v1.cpp | 16 +++--------- engines/gob/util.cpp | 40 +++++++++++++++++++++++++++- engines/gob/util.h | 8 ++++++ 6 files changed, 128 insertions(+), 15 deletions(-) diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 9df3c06c74..843c0bff48 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -52,6 +52,7 @@ Inter::Inter(GobEngine *vm) : _vm(vm), _varStack(600) { _soundEndTimeKey = 0; _soundStopVal = 0; + _lastBusyWait = 0; _noBusyWait = false; _variables = 0; @@ -452,4 +453,15 @@ uint32 Inter::readValue(uint16 index, uint16 type) { return 0; } +void Inter::handleBusyWait() { + uint32 now = _vm->_util->getTimeKey(); + + if (!_noBusyWait) + if ((now - _lastBusyWait) <= 20) + _vm->_util->longDelay(1); + + _lastBusyWait = now; + _noBusyWait = false; +} + } // End of namespace Gob diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 907a275e50..0625646cdd 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -142,8 +142,9 @@ protected: VariableStack _varStack; - // The busy-wait detection in o1_keyFunc breaks fast scrolling in Ween - bool _noBusyWait; + // Busy-wait detection + bool _noBusyWait; + uint32 _lastBusyWait; GobEngine *_vm; @@ -172,6 +173,8 @@ protected: void storeString(const char *value); uint32 readValue(uint16 index, uint16 type); + + void handleBusyWait(); }; class Inter_v1 : public Inter { @@ -522,6 +525,8 @@ protected: virtual void setupOpcodesDraw(); virtual void setupOpcodesFunc(); virtual void setupOpcodesGob(); + + void oLittleRed_keyFunc(OpFuncParams ¶ms); }; class Inter_v3 : public Inter_v2 { diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 6a63998216..01d372aaeb 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -22,6 +22,13 @@ #include "gob/gob.h" #include "gob/inter.h" +#include "gob/global.h" +#include "gob/util.h" +#include "gob/draw.h" +#include "gob/game.h" +#include "gob/script.h" +#include "gob/hotspots.h" +#include "gob/sound/sound.h" namespace Gob { @@ -39,6 +46,8 @@ void Inter_LittleRed::setupOpcodesDraw() { void Inter_LittleRed::setupOpcodesFunc() { Inter_v2::setupOpcodesFunc(); + + OPCODEFUNC(0x14, oLittleRed_keyFunc); } void Inter_LittleRed::setupOpcodesGob() { @@ -46,4 +55,53 @@ void Inter_LittleRed::setupOpcodesGob() { OPCODEGOB(501, o2_stopProtracker); } +void Inter_LittleRed::oLittleRed_keyFunc(OpFuncParams ¶ms) { + animPalette(); + _vm->_draw->blitInvalidated(); + + handleBusyWait(); + + int16 cmd = _vm->_game->_script->readInt16(); + int16 key; + uint32 keyState; + + switch (cmd) { + case -1: + break; + + case 0: + _vm->_draw->_showCursor &= ~2; + _vm->_util->longDelay(1); + key = _vm->_game->_hotspots->check(0, 0); + storeKey(key); + + _vm->_util->clearKeyBuf(); + break; + + case 1: + _vm->_util->forceMouseUp(true); + key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); + storeKey(key); + break; + + case 2: + _vm->_util->processInput(true); + keyState = _vm->_util->getKeyState(); + + WRITE_VAR(0, keyState); + _vm->_util->clearKeyBuf(); + break; + + default: + _vm->_sound->speakerOnUpdate(cmd); + if (cmd < 20) { + _vm->_util->delay(cmd); + _noBusyWait = true; + } else + _vm->_util->longDelay(cmd); + break; + } +} + } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 3652637e32..dc533a210a 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1189,26 +1189,15 @@ void Inter_v1::o1_palLoad(OpFuncParams ¶ms) { } void Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { - static uint32 lastCalled = 0; - int16 cmd; - int16 key; - uint32 now; - if (!_vm->_vidPlayer->isPlayingLive()) { _vm->_draw->forceBlit(); _vm->_video->retrace(); } - cmd = _vm->_game->_script->readInt16(); animPalette(); _vm->_draw->blitInvalidated(); - now = _vm->_util->getTimeKey(); - if (!_noBusyWait) - if ((now - lastCalled) <= 20) - _vm->_util->longDelay(1); - lastCalled = now; - _noBusyWait = false; + handleBusyWait(); // WORKAROUND for bug #1726130: Ween busy-waits in the intro for a counter // to become 5000. We deliberately slow down busy-waiting, so we shorten @@ -1217,6 +1206,9 @@ void Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { (_vm->_game->_script->pos() == 729) && _vm->isCurrentTot("intro5.tot")) WRITE_VAR(59, 4000); + int16 cmd = _vm->_game->_script->readInt16(); + int16 key; + switch (cmd) { case -1: break; diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 7f9c6131fd..64dfcf9b12 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -21,7 +21,6 @@ */ #include "common/stream.h" -#include "common/events.h" #include "graphics/palette.h" @@ -45,6 +44,8 @@ Util::Util(GobEngine *vm) : _vm(vm) { _frameRate = 12; _frameWaitTime = 0; _startFrameTime = 0; + + _keyState = 0; } uint32 Util::getTimeKey() { @@ -116,6 +117,8 @@ void Util::processInput(bool scroll) { _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsRight)); break; case Common::EVENT_KEYDOWN: + keyDown(event); + if (event.kbd.hasFlags(Common::KBD_CTRL)) { if (event.kbd.keycode == Common::KEYCODE_f) _fastMode ^= 1; @@ -132,6 +135,7 @@ void Util::processInput(bool scroll) { addKeyToBuffer(event.kbd); break; case Common::EVENT_KEYUP: + keyUp(event); break; default: break; @@ -576,4 +580,38 @@ void Util::checkJoystick() { _vm->_global->_useJoystick = 0; } +uint32 Util::getKeyState() const { + return _keyState; +} + +void Util::keyDown(const Common::Event &event) { + if (event.kbd.keycode == Common::KEYCODE_UP) + _keyState |= 0x0001; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keyState |= 0x0002; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keyState |= 0x0004; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keyState |= 0x0008; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keyState |= 0x0020; + else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + _keyState |= 0x0040; +} + +void Util::keyUp(const Common::Event &event) { + if (event.kbd.keycode == Common::KEYCODE_UP) + _keyState &= ~0x0001; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keyState &= ~0x0002; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keyState &= ~0x0004; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keyState &= ~0x0008; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keyState &= ~0x0020; + else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + _keyState &= ~0x0040; +} + } // End of namespace Gob diff --git a/engines/gob/util.h b/engines/gob/util.h index 4228dac768..b26a78ab2c 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -25,6 +25,7 @@ #include "common/str.h" #include "common/keyboard.h" +#include "common/events.h" namespace Common { class SeekableReadStream; @@ -110,6 +111,8 @@ public: bool checkKey(int16 &key); bool keyPressed(); + uint32 getKeyState() const; + void getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons); void setMousePos(int16 x, int16 y); void waitMouseUp(); @@ -155,6 +158,8 @@ protected: int16 _frameWaitTime; uint32 _startFrameTime; + uint32 _keyState; + GobEngine *_vm; bool keyBufferEmpty(); @@ -162,6 +167,9 @@ protected: bool getKeyFromBuffer(Common::KeyState &key); int16 translateKey(const Common::KeyState &key); void checkJoystick(); + + void keyDown(const Common::Event &event); + void keyUp(const Common::Event &event); }; } // End of namespace Gob -- cgit v1.2.3 From 5961609a56a910d81d38389c6ac61d06eca6f029 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 15:09:01 +0200 Subject: GOB: Add a resource size workaround for Little Red This fixes the missing resources in the screen where Little Red has to find the animals' homes for them. --- engines/gob/gob.cpp | 10 ++++++++++ engines/gob/gob.h | 4 ++++ engines/gob/resources.cpp | 12 ++++++++++-- engines/gob/resources.h | 6 +++--- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index a13f6a372f..f3480fed99 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -233,6 +233,10 @@ bool GobEngine::isDemo() const { return (isSCNDemo() || isBATDemo()); } +bool GobEngine::hasResourceSizeWorkaround() const { + return _resourceSizeWorkaround; +} + bool GobEngine::isCurrentTot(const Common::String &tot) const { return _game->_curTotFile.equalsIgnoreCase(tot); } @@ -389,6 +393,8 @@ void GobEngine::pauseGame() { } bool GobEngine::initGameParts() { + _resourceSizeWorkaround = false; + // just detect some devices some of which will be always there if the music is not disabled _noMusic = MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB)) == MT_NULL ? true : false; _saveLoad = 0; @@ -471,6 +477,10 @@ bool GobEngine::initGameParts() { _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); + + // WORKAROUND: Little Red Riding Hood has a small resource size glitch in the + // screen where Little Red needs to find the animals' homes. + _resourceSizeWorkaround = true; break; case kGameTypeGob3: diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 165760e6d5..19489e4924 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -200,6 +200,8 @@ public: GobConsole *_console; + bool _resourceSizeWorkaround; + Global *_global; Util *_util; DataIO *_dataIO; @@ -236,6 +238,8 @@ public: bool isTrueColor() const; bool isDemo() const; + bool hasResourceSizeWorkaround() const; + bool isCurrentTot(const Common::String &tot) const; void setTrueColor(bool trueColor); diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp index d5497c25be..a84f4ac4b8 100644 --- a/engines/gob/resources.cpp +++ b/engines/gob/resources.cpp @@ -716,7 +716,7 @@ byte *Resources::getIMData(TOTResourceItem &totItem) const { return _imData + offset; } -byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { +byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 &size) const { Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_extFile); if (!stream) return 0; @@ -726,6 +726,10 @@ byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { return 0; } + // If that workaround is active, limit the resource size instead of throwing an error + if (_vm->hasResourceSizeWorkaround()) + size = MIN(size, stream->size() - extItem.offset); + byte *data = new byte[extItem.packed ? (size + 2) : size]; if (stream->read(data, size) != size) { delete[] data; @@ -737,7 +741,7 @@ byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { return data; } -byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const { +byte *Resources::getEXData(EXTResourceItem &extItem, uint32 &size) const { Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_exFile); if (!stream) return 0; @@ -747,6 +751,10 @@ byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const { return 0; } + // If that workaround is active, limit the resource size instead of throwing an error + if (_vm->hasResourceSizeWorkaround()) + size = MIN(size, stream->size() - extItem.offset); + byte *data = new byte[extItem.packed ? (size + 2) : size]; if (stream->read(data, size) != size) { delete[] data; diff --git a/engines/gob/resources.h b/engines/gob/resources.h index 39155c5176..04b3b9d31e 100644 --- a/engines/gob/resources.h +++ b/engines/gob/resources.h @@ -103,7 +103,7 @@ private: static const int kTOTTextItemSize = 2 + 2; enum ResourceType { - kResourceTOT, + kResourceTOT = 0, kResourceIM, kResourceEXT, kResourceEX @@ -201,8 +201,8 @@ private: byte *getTOTData(TOTResourceItem &totItem) const; byte *getIMData(TOTResourceItem &totItem) const; - byte *getEXTData(EXTResourceItem &extItem, uint32 size) const; - byte *getEXData(EXTResourceItem &extItem, uint32 size) const; + byte *getEXTData(EXTResourceItem &extItem, uint32 &size) const; + byte *getEXData(EXTResourceItem &extItem, uint32 &size) const; }; } // End of namespace Gob -- cgit v1.2.3 From 160732b2f73a5df173c1fa867f82fa2913ec2236 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 21:47:22 +0300 Subject: Revert "SCI: Change Script::getObject() to accept a reg_t" This reverts commit 577d7e41c9ca2c498dc85e41c373fbdca8d2ed41. --- engines/sci/engine/kernel.cpp | 2 +- engines/sci/engine/script.cpp | 14 +++++++------- engines/sci/engine/script.h | 4 ++-- engines/sci/engine/seg_manager.cpp | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 0266414b26..c99bc4fe47 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -377,7 +377,7 @@ uint16 Kernel::findRegType(reg_t reg) { if (reg.offset <= (*(Script *)mobj).getBufSize() && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) { - result |= ((Script *)mobj)->getObject(reg) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE; + result |= ((Script *)mobj)->getObject(reg.offset) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE; } else result |= SIG_TYPE_REFERENCE; break; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 7714983120..0ed9598b41 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -223,16 +223,16 @@ const byte *Script::getSci3ObjectsPointer() { return ptr; } -Object *Script::getObject(reg_t pos) { - if (_objects.contains(pos.offset)) - return &_objects[pos.offset]; +Object *Script::getObject(uint16 offset) { + if (_objects.contains(offset)) + return &_objects[offset]; else return 0; } -const Object *Script::getObject(reg_t pos) const { - if (_objects.contains(pos.offset)) - return &_objects[pos.offset]; +const Object *Script::getObject(uint16 offset) const { + if (_objects.contains(offset)) + return &_objects[offset]; else return 0; } @@ -726,7 +726,7 @@ Common::Array Script::listAllDeallocatable(SegmentId segId) const { Common::Array Script::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; if (addr.offset <= _bufSize && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(_buf + addr.offset)) { - const Object *obj = getObject(addr); + const Object *obj = getObject(addr.offset); if (obj) { // Note all local variables, if we have a local variable environment if (_localsSegment) diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 4d23ffbba8..df7f42cc0d 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -118,8 +118,8 @@ public: virtual void saveLoadWithSerializer(Common::Serializer &ser); - Object *getObject(reg_t pos); - const Object *getObject(reg_t pos) const; + Object *getObject(uint16 offset); + const Object *getObject(uint16 offset) const; /** * Initializes an object within the segment manager diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 8f85577fb8..20a8240641 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -228,7 +228,7 @@ Object *SegManager::getObject(reg_t pos) const { Script *scr = (Script *)mobj; if (pos.offset <= scr->getBufSize() && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(scr->getBuf(pos.offset))) { - obj = scr->getObject(pos); + obj = scr->getObject(pos.offset); } } } -- cgit v1.2.3 From 5ca22a1104d2e1ca0a7b7f5ac159b5c721e13ead Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 21:52:03 +0300 Subject: SCI: Fix warnings Thanks to DrMcCoy for reporting them --- engines/sci/engine/file.cpp | 2 +- engines/sci/engine/kgraphics32.cpp | 3 ++- engines/sci/engine/script.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/engines/sci/engine/file.cpp b/engines/sci/engine/file.cpp index 3470d23fe2..c44963f457 100644 --- a/engines/sci/engine/file.cpp +++ b/engines/sci/engine/file.cpp @@ -427,7 +427,7 @@ bool VirtualIndexFile::seek(int32 offset, int whence) { _ptr = _buffer + offset; break; case SEEK_END: - assert(_bufferSize - offset >= 0); + assert((int32)_bufferSize - offset >= 0); _ptr = _buffer + (_bufferSize - offset); break; } diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 53cf8ada75..377c05935a 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -241,6 +241,7 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { //int16 priority = argv[4].toSint16(); // always 0xc8 (200) when fading in/out //uint16 animate = argv[5].toUint16(); // boolean, animate or not while the transition lasts //uint16 refFrame = argv[6].toUint16(); // refFrame, always 0 when fading in/out +#if 0 int16 divisions; // If the game has the pFadeArray selector, another parameter is used here, @@ -252,7 +253,7 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { } else { divisions = (argc >= 8) ? argv[7].toSint16() : -1; // divisions (transition steps?) } - +#endif if (showStyle > 15) { warning("kSetShowStyle: Illegal style %d for plane %04x:%04x", showStyle, PRINT_REG(planeObj)); return s->r_acc; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 0ed9598b41..ca7eaad383 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -199,7 +199,7 @@ void Script::load(int script_nr, ResourceManager *resMan) { _localsOffset = 0; if (_localsOffset + _localsCount * 2 + 1 >= (int)_bufSize) { - error("Locals extend beyond end of script: offset %04x, count %d vs size %d", _localsOffset, _localsCount, _bufSize); + error("Locals extend beyond end of script: offset %04x, count %d vs size %d", _localsOffset, _localsCount, (int)_bufSize); //_localsCount = (_bufSize - _localsOffset) >> 1; } } -- cgit v1.2.3 From 041b1447c02616c0f285556bb453e79268da7dce Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 22:02:13 +0300 Subject: SCI: Replace RAW_IS_OBJECT with a method --- engines/sci/engine/kernel.cpp | 2 +- engines/sci/engine/script.cpp | 6 +++++- engines/sci/engine/script.h | 1 + engines/sci/engine/seg_manager.cpp | 2 +- engines/sci/engine/vm.h | 2 -- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index c99bc4fe47..3a33c928e7 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -376,7 +376,7 @@ uint16 Kernel::findRegType(reg_t reg) { case SEG_TYPE_SCRIPT: if (reg.offset <= (*(Script *)mobj).getBufSize() && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && - RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) { + (*(Script *)mobj).offsetIsObject(reg.offset)) { result |= ((Script *)mobj)->getObject(reg.offset) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE; } else result |= SIG_TYPE_REFERENCE; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index ca7eaad383..d09b5ace80 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -725,7 +725,7 @@ Common::Array Script::listAllDeallocatable(SegmentId segId) const { Common::Array Script::listAllOutgoingReferences(reg_t addr) const { Common::Array tmp; - if (addr.offset <= _bufSize && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(_buf + addr.offset)) { + if (addr.offset <= _bufSize && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && offsetIsObject(addr.offset)) { const Object *obj = getObject(addr.offset); if (obj) { // Note all local variables, if we have a local variable environment @@ -761,4 +761,8 @@ Common::Array Script::listObjectReferences() const { return tmp; } +bool Script::offsetIsObject(uint16 offset) const { + return (READ_SCI11ENDIAN_UINT16((const byte *)_buf + offset + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER); +} + } // End of namespace Sci diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index df7f42cc0d..0c99f13235 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -89,6 +89,7 @@ public: void syncLocalsBlock(SegManager *segMan); ObjMap &getObjectMap() { return _objects; } const ObjMap &getObjectMap() const { return _objects; } + bool offsetIsObject(uint16 offset) const; public: Script(); diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 20a8240641..eaa587e3f9 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -227,7 +227,7 @@ Object *SegManager::getObject(reg_t pos) const { } else if (mobj->getType() == SEG_TYPE_SCRIPT) { Script *scr = (Script *)mobj; if (pos.offset <= scr->getBufSize() && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET - && RAW_IS_OBJECT(scr->getBuf(pos.offset))) { + && scr->offsetIsObject(pos.offset)) { obj = scr->getObject(pos.offset); } } diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index cdd9b9a06e..67b9dd44eb 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -61,8 +61,6 @@ struct Class { reg_t reg; ///< offset; script-relative offset, segment: 0 if not instantiated }; -#define RAW_IS_OBJECT(datablock) (READ_SCI11ENDIAN_UINT16(((const byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER) - // A reference to an object's variable. // The object is stored as a reg_t, the variable as an index into _variables struct ObjVarRef { -- cgit v1.2.3 From 8666a0528ff7f01acff97355df1bddf6136869b1 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 22:03:42 +0300 Subject: SCI: Also skip a robot video in the Lighthouse demo --- engines/sci/video/robot_decoder.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engines/sci/video/robot_decoder.cpp b/engines/sci/video/robot_decoder.cpp index 8ffcecc339..ebcfac6054 100644 --- a/engines/sci/video/robot_decoder.cpp +++ b/engines/sci/video/robot_decoder.cpp @@ -93,6 +93,10 @@ bool RobotDecoder::load(GuiResourceId id) { // videos. Skip it for now. if (g_sci->getGameId() == GID_RAMA && id == 1003) return false; + + // TODO: The robot video in the Lighthouse demo gets stuck + if (g_sci->getGameId() == GID_LIGHTHOUSE && id == 16) + return false; Common::String fileName = Common::String::format("%d.rbt", id); Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName); -- cgit v1.2.3 From a0add53c6003a8ed42324d4bacc7f4745ee25543 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Fri, 15 Jun 2012 22:24:35 +0300 Subject: SCI: Change getClassAddress() to only require the caller segment The caller offset is never actually used inside the function --- engines/sci/engine/object.cpp | 4 ++-- engines/sci/engine/script.cpp | 4 ++-- engines/sci/engine/seg_manager.cpp | 4 ++-- engines/sci/engine/seg_manager.h | 2 +- engines/sci/engine/vm.cpp | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp index 2a0ed38e61..de028392ea 100644 --- a/engines/sci/engine/object.cpp +++ b/engines/sci/engine/object.cpp @@ -153,7 +153,7 @@ void Object::initSpecies(SegManager *segMan, reg_t addr) { if (speciesOffset == 0xffff) // -1 setSpeciesSelector(NULL_REG); // no species else - setSpeciesSelector(segMan->getClassAddress(speciesOffset, SCRIPT_GET_LOCK, addr)); + setSpeciesSelector(segMan->getClassAddress(speciesOffset, SCRIPT_GET_LOCK, addr.segment)); } void Object::initSuperClass(SegManager *segMan, reg_t addr) { @@ -162,7 +162,7 @@ void Object::initSuperClass(SegManager *segMan, reg_t addr) { if (superClassOffset == 0xffff) // -1 setSuperClassSelector(NULL_REG); // no superclass else - setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr)); + setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr.segment)); } bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass) { diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index d09b5ace80..d018872b43 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -653,7 +653,7 @@ void Script::initializeObjectsSci11(SegManager *segMan, SegmentId segmentId) { // Copy base from species class, as we need its selector IDs obj->setSuperClassSelector( - segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); + segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, 0)); // If object is instance, get -propDict- from class and set it for this // object. This is needed for ::isMemberOf() to work. @@ -686,7 +686,7 @@ void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) { reg_t reg = make_reg(segmentId, seeker - _buf); Object *obj = scriptObjInit(reg); - obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); + obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, 0)); seeker += READ_SCI11ENDIAN_UINT16(seeker + 2); } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index eaa587e3f9..ac02022ee7 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -939,7 +939,7 @@ void SegManager::createClassTable() { _resMan->unlockResource(vocab996); } -reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller) { +reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment) { if (classnr == 0xffff) return NULL_REG; @@ -956,7 +956,7 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller return NULL_REG; } } else - if (caller.segment != the_class->reg.segment) + if (callerSegment != the_class->reg.segment) getScript(the_class->reg.segment)->incrementLockers(); return the_class->reg; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 62e711e686..356a1b04a7 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -125,7 +125,7 @@ private: public: // TODO: document this - reg_t getClassAddress(int classnr, ScriptLoadType lock, reg_t caller); + reg_t getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment); /** * Return a pointer to the specified script. diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 162dce9fcc..7dc397c11e 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -996,7 +996,7 @@ void run_vm(EngineState *s) { case op_class: // 0x28 (40) // Get class address s->r_acc = s->_segMan->getClassAddress((unsigned)opparams[0], SCRIPT_GET_LOCK, - s->xs->addr.pc); + s->xs->addr.pc.segment); break; case 0x29: // (41) @@ -1021,7 +1021,7 @@ void run_vm(EngineState *s) { case op_super: // 0x2b (43) // Send to any class - r_temp = s->_segMan->getClassAddress(opparams[0], SCRIPT_GET_LOAD, s->xs->addr.pc); + r_temp = s->_segMan->getClassAddress(opparams[0], SCRIPT_GET_LOAD, s->xs->addr.pc.segment); if (!r_temp.isPointer()) error("[VM]: Invalid superclass in object"); -- cgit v1.2.3 From 1666d9da824c7e217fba19bcd694cc878b3d65bb Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 01:39:14 +0200 Subject: GOB: Fix mult object collision detection I broke in 2007 This fixes the sidescroller levels (like the bees and butterflies) in Little Red. I really wonder if this breakage had other effects too... --- engines/gob/mult_v2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 6593565e6a..64b9d19e33 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -1082,7 +1082,7 @@ void Mult_v2::animate() { continue; for (int j = 0; j < numAnims; j++) { - Mult_Object &animObj2 = *_renderObjs[i]; + Mult_Object &animObj2 = *_renderObjs[j]; Mult_AnimData &animData2 = *(animObj2.pAnimData); if (i == j) -- cgit v1.2.3 From 54f7d9c557e1560170256e89ac9c20a1d6be8640 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 01:44:57 +0200 Subject: GOB: Use the full title for Little Red Riding Hood While the other parts in the series are mostly hard-coded, they are small, simple and monotone enough that I might just think about implementing them some day... --- engines/gob/detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 17a2ae3da8..861cc95d41 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -50,7 +50,7 @@ static const PlainGameDescriptor gobGames[] = { {"gob2cd", "Gobliins 2 CD"}, {"ween", "Ween: The Prophecy"}, {"bargon", "Bargon Attack"}, - {"littlered", "Little Red Riding Hood"}, + {"littlered", "Once Upon A Time: Little Red Riding Hood"}, {"ajworld", "A.J's World of Discovery"}, {"gob3", "Goblins Quest 3"}, {"gob3cd", "Goblins Quest 3 CD"}, -- cgit v1.2.3 From f917db972e0ae7e4e82a6430010a155cbb3a92c0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 01:50:31 +0200 Subject: GOB: Shut up Little Red's warning about gob func 1 and 2 Those set some DOS timer interrupt related to sound. Seems to be unnecessary for us. --- engines/gob/inter_littlered.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 01d372aaeb..3a4494598e 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -51,6 +51,9 @@ void Inter_LittleRed::setupOpcodesFunc() { } void Inter_LittleRed::setupOpcodesGob() { + OPCODEGOB(1, o_gobNOP); // Sets some sound timer interrupt + OPCODEGOB(2, o_gobNOP); // Sets some sound timer interrupt + OPCODEGOB(500, o2_playProtracker); OPCODEGOB(501, o2_stopProtracker); } -- cgit v1.2.3 From a24cb57c9d4d4292da582fafc52be70103a1e369 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 02:58:53 +0200 Subject: GOB: Loop the Little Red title music --- engines/gob/inter.h | 1 + engines/gob/inter_littlered.cpp | 8 ++++++++ engines/gob/sound/sound.cpp | 4 ++++ engines/gob/sound/sound.h | 1 + engines/gob/sound/soundblaster.cpp | 24 +++++++++++++++++++++--- engines/gob/sound/soundblaster.h | 4 ++++ 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 0625646cdd..63bf3eb1c6 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -527,6 +527,7 @@ protected: virtual void setupOpcodesGob(); void oLittleRed_keyFunc(OpFuncParams ¶ms); + void oLittleRed_playComposition(OpFuncParams ¶ms); }; class Inter_v3 : public Inter_v2 { diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 3a4494598e..729d9f5694 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -48,6 +48,8 @@ void Inter_LittleRed::setupOpcodesFunc() { Inter_v2::setupOpcodesFunc(); OPCODEFUNC(0x14, oLittleRed_keyFunc); + + OPCODEFUNC(0x3D, oLittleRed_playComposition); } void Inter_LittleRed::setupOpcodesGob() { @@ -107,4 +109,10 @@ void Inter_LittleRed::oLittleRed_keyFunc(OpFuncParams ¶ms) { } } +void Inter_LittleRed::oLittleRed_playComposition(OpFuncParams ¶ms) { + _vm->_sound->blasterRepeatComposition(-1); + + o1_playComposition(params); +} + } // End of namespace Gob diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 9f72d1a98f..170330f281 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -445,6 +445,10 @@ void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount, _blaster->playSample(*sndDesc, repCount, frequency, fadeLength); } +void Sound::blasterRepeatComposition(int32 repCount) { + _blaster->repeatComposition(repCount);; +} + void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) { if (!_blaster) return; diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index 064a249253..6ad0ec5483 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -63,6 +63,7 @@ public: void blasterPlayComposition(int16 *composition, int16 freqVal, SoundDesc *sndDescs = 0, int8 sndCount = kSoundsCount); void blasterStopComposition(); + void blasterRepeatComposition(int32 repCount); char blasterPlayingSound() const; diff --git a/engines/gob/sound/soundblaster.cpp b/engines/gob/sound/soundblaster.cpp index 4ff555b0e3..915d744494 100644 --- a/engines/gob/sound/soundblaster.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -31,6 +31,8 @@ SoundBlaster::SoundBlaster(Audio::Mixer &mixer) : SoundMixer(mixer, Audio::Mixer _compositionSamples = 0; _compositionSampleCount = 0; _compositionPos = -1; + + _compositionRepCount = 0; } SoundBlaster::~SoundBlaster() { @@ -79,6 +81,7 @@ void SoundBlaster::nextCompositionPos() { if (_compositionPos == 49) _compositionPos = -1; } + _compositionPos = -1; } @@ -98,6 +101,10 @@ void SoundBlaster::playComposition(int16 *composition, int16 freqVal, nextCompositionPos(); } +void SoundBlaster::repeatComposition(int32 repCount) { + _compositionRepCount = repCount; +} + void SoundBlaster::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { @@ -106,10 +113,21 @@ void SoundBlaster::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency } void SoundBlaster::checkEndSample() { - if (_compositionPos != -1) + if (_compositionPos != -1) { + nextCompositionPos(); + return; + } + + if (_compositionRepCount != 0) { + if (_compositionRepCount > 0) + _compositionRepCount--; + nextCompositionPos(); - else - SoundMixer::checkEndSample(); + if (_compositionPos != -1) + return; + } + + SoundMixer::checkEndSample(); } void SoundBlaster::endFade() { diff --git a/engines/gob/sound/soundblaster.h b/engines/gob/sound/soundblaster.h index c2704c5482..c740ba2269 100644 --- a/engines/gob/sound/soundblaster.h +++ b/engines/gob/sound/soundblaster.h @@ -46,6 +46,8 @@ public: void stopComposition(); void endComposition(); + void repeatComposition(int32 repCount); + protected: Common::Mutex _mutex; @@ -54,6 +56,8 @@ protected: int16 _composition[50]; int8 _compositionPos; + int32 _compositionRepCount; + SoundDesc *_curSoundDesc; void setSample(SoundDesc &sndDesc, int16 repCount, -- cgit v1.2.3 From 08c0fa91059113e6ed054cf4a84317a6ff8b4d08 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 03:04:35 +0200 Subject: GOB: Remove a superfluous semicolon --- engines/gob/sound/sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 170330f281..184e14a2e6 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -446,7 +446,7 @@ void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount, } void Sound::blasterRepeatComposition(int32 repCount) { - _blaster->repeatComposition(repCount);; + _blaster->repeatComposition(repCount); } void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) { -- cgit v1.2.3 From 282b5564dadef2eea814d56e8bf7cbbbe59cf84c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 04:05:58 +0200 Subject: NEWS: Mention Little Red support --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 4db976b0d8..74112fa7cd 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ For a more comprehensive changelog of the latest experimental code, see: - Added support for Dreamweb. - Added support for Geisha. - Added support for Gregory and the Hot Air Balloon. + - Added support for Once Upon A Time: Little Red Riding Hood - Added support for Magic Tales: Baba Yaga and the Magic Geese. - Added support for Magic Tales: Imo and the King. - Added support for Magic Tales: Liam Finds a Story. -- cgit v1.2.3 From d860f0f9bf823655844c5fc56a5ac8f94774aa23 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 04:06:08 +0200 Subject: README: Add Little Red to the gob games list --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 1024c6764b..722f3298d3 100644 --- a/README +++ b/README @@ -243,6 +243,7 @@ GOB Games by Coktel Vision: Gobliins 2 [gob2] Goblins 3 [gob3] Lost in Time [lostintime] + Once Upon A Time: Little Red Riding Hood [littlered] The Bizarre Adventures of Woodruff and the Schnibble [woodruff] Urban Runner [urban] -- cgit v1.2.3 From ba07c7678a3c1f03636f408c51bae121f0280c00 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 04:06:21 +0200 Subject: GOB: Add Little Red to the gob games list comment --- engines/gob/gob.h | 1 + 1 file changed, 1 insertion(+) diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 19489e4924..808c941546 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -54,6 +54,7 @@ class StaticTextWidget; * - Urban Runner * - Bambou le sauveur de la jungle * - Geisha + * - Once Upon A Time: Little Red Riding Hood */ namespace Gob { -- cgit v1.2.3 From 555afaa50c45a51e53c88c6cb1d52a66ba367fd5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 04:21:54 +0200 Subject: NEWS: Ooops, proper alphabetical ordering --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 74112fa7cd..9fde25e3f3 100644 --- a/NEWS +++ b/NEWS @@ -9,11 +9,11 @@ For a more comprehensive changelog of the latest experimental code, see: - Added support for Dreamweb. - Added support for Geisha. - Added support for Gregory and the Hot Air Balloon. - - Added support for Once Upon A Time: Little Red Riding Hood - Added support for Magic Tales: Baba Yaga and the Magic Geese. - Added support for Magic Tales: Imo and the King. - Added support for Magic Tales: Liam Finds a Story. - Added support for Magic Tales: The Little Samurai. + - Added support for Once Upon A Time: Little Red Riding Hood - Added support for Sleeping Cub's Test of Courage. - Added support for Soltys. - Added support for The Princess and the Crab. -- cgit v1.2.3 From 230a0edc2d966e5990115b5669b5236d2d41618e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 04:29:57 +0200 Subject: AUDIO: gob uses protracker too --- audio/mods/protracker.h | 1 + 1 file changed, 1 insertion(+) diff --git a/audio/mods/protracker.h b/audio/mods/protracker.h index d52322f07e..5f47c4453b 100644 --- a/audio/mods/protracker.h +++ b/audio/mods/protracker.h @@ -25,6 +25,7 @@ * Sound decoder used in engines: * - agos * - parallaction + * - gob */ #ifndef AUDIO_MODS_PROTRACKER_H -- cgit v1.2.3 From 5230a0d61795e2855625a43d60dc3bc2ed83fc3d Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Fri, 15 Jun 2012 22:45:44 -0400 Subject: AUDIO: Make sure maxtrax and tfmx are compiled in with dynamic modules --- audio/mods/maxtrax.h | 7 ++----- audio/mods/tfmx.h | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/audio/mods/maxtrax.h b/audio/mods/maxtrax.h index c45a21a255..ffb176c241 100644 --- a/audio/mods/maxtrax.h +++ b/audio/mods/maxtrax.h @@ -20,11 +20,8 @@ * */ -// see if all engines using this class are DISABLED -#if !defined(ENABLE_KYRA) - -// normal Header Guard -#elif !defined(AUDIO_MODS_MAXTRAX_H) +// Only compiled if Kyra is built-in or we're building for dynamic modules +#if !defined(AUDIO_MODS_MAXTRAX_H) && (defined(ENABLE_KYRA) || defined(DYNAMIC_MODULES)) #define AUDIO_MODS_MAXTRAX_H // #define MAXTRAX_HAS_MODULATION diff --git a/audio/mods/tfmx.h b/audio/mods/tfmx.h index 4174fbfb27..ebe1172278 100644 --- a/audio/mods/tfmx.h +++ b/audio/mods/tfmx.h @@ -20,11 +20,8 @@ * */ -// see if all engines using this class are DISABLED -#if !defined(ENABLE_SCUMM) - -// normal Header Guard -#elif !defined(AUDIO_MODS_TFMX_H) +// Only compiled if SCUMM is built-in or we're building for dynamic modules +#if !defined(AUDIO_MODS_TFMX_H) && (defined(ENABLE_SCUMM) || defined(DYNAMIC_MODULES)) #define AUDIO_MODS_TFMX_H #include "audio/mods/paula.h" -- cgit v1.2.3