aboutsummaryrefslogtreecommitdiff
path: root/engines/agi
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agi')
-rw-r--r--engines/agi/agi.cpp165
-rw-r--r--engines/agi/agi.h4
-rw-r--r--engines/agi/cycle.cpp2
-rw-r--r--engines/agi/detection.cpp29
-rw-r--r--engines/agi/keyboard.cpp31
-rw-r--r--engines/agi/menu.cpp62
-rw-r--r--engines/agi/preagi_mickey.cpp2
-rw-r--r--engines/agi/saveload.cpp82
-rw-r--r--engines/agi/sprite.cpp5
9 files changed, 205 insertions, 177 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index e373dd3e6d..69b27e10f9 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -25,6 +25,7 @@
#include "common/md5.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -271,19 +272,6 @@ void AgiEngine::processEvents() {
}
}
-void AgiEngine::checkQuickLoad() {
- if (ConfMan.hasKey("save_slot")) {
- char saveNameBuffer[256];
-
- snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot"));
-
- if (loadGame(saveNameBuffer, false) == errOK) { // Do not check game id
- _game.exitAllLogics = 1;
- _menu->enableAll();
- }
- }
-}
-
void AgiEngine::pollTimer(void) {
static uint32 m = 0;
uint32 dm;
@@ -301,40 +289,10 @@ void AgiEngine::pollTimer(void) {
m = g_tickTimer;
}
-bool AgiEngine::isKeypress(void) {
- processEvents();
- return _keyQueueStart != _keyQueueEnd;
-}
-
-int AgiEngine::getKeypress(void) {
- int k;
-
- while (_keyQueueStart == _keyQueueEnd) // block
- pollTimer();
-
- keyDequeue(k);
-
- return k;
-}
-
-void AgiEngine::clearKeyQueue(void) {
- while (isKeypress()) {
- getKeypress();
- }
-}
-
void AgiEngine::agiTimerFunctionLow(void *refCon) {
g_tickTimer++;
}
-void AgiEngine::clearImageStack(void) {
- _imageStack.clear();
-}
-
-void AgiEngine::releaseImageStack(void) {
- _imageStack.clear();
-}
-
void AgiEngine::pause(uint32 msec) {
uint32 endTime = _system->getMillis() + msec;
@@ -348,38 +306,6 @@ void AgiEngine::pause(uint32 msec) {
_gfx->setCursor(_renderMode == Common::kRenderAmiga);
}
-void AgiEngine::recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
- int16 p4, int16 p5, int16 p6, int16 p7) {
- ImageStackElement pnew;
-
- pnew.type = type;
- pnew.pad = 0;
- pnew.parm1 = p1;
- pnew.parm2 = p2;
- pnew.parm3 = p3;
- pnew.parm4 = p4;
- pnew.parm5 = p5;
- pnew.parm6 = p6;
- pnew.parm7 = p7;
-
- _imageStack.push(pnew);
-}
-
-void AgiEngine::replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
- int16 p4, int16 p5, int16 p6, int16 p7) {
- switch (type) {
- case ADD_PIC:
- debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1);
- agiLoadResource(rPICTURE, p1);
- _picture->decodePicture(p1, p2, p3 != 0);
- break;
- case ADD_VIEW:
- agiLoadResource(rVIEW, p1);
- _sprites->addToPic(p1, p2, p3, p4, p5, p6, p7);
- break;
- }
-}
-
void AgiEngine::initPriTable() {
int i, p, y = 0;
@@ -489,11 +415,6 @@ int AgiEngine::agiInit() {
_game.mouseFence.setWidth(0); // Reset
- _game.lastController = 0;
- for (i = 0; i < MAX_DIRS; i++)
- _game.controllerOccured[i] = false;
-
-
return ec;
}
@@ -530,21 +451,6 @@ int AgiEngine::agiDeinit() {
return ec;
}
-int AgiEngine::agiDetectGame() {
- int ec = errOK;
-
- assert(_gameDescription != NULL);
-
- if (getVersion() <= 0x2999) {
- _loader = new AgiLoader_v2(this);
- } else {
- _loader = new AgiLoader_v3(this);
- }
- ec = _loader->detectGame();
-
- return ec;
-}
-
int AgiEngine::agiLoadResource(int r, int n) {
int i;
@@ -587,67 +493,6 @@ static const GameSettings agiSettings[] = {
{NULL, NULL, 0, 0, NULL}
};
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
- if (_amigaStyle) {
- if (positive) {
- if (pressed) { // Positive pressed Amiga-style button
- if (_olderAgi) {
- return AgiTextColor(amigaBlack, amigaOrange);
- } else {
- return AgiTextColor(amigaBlack, amigaPurple);
- }
- } else { // Positive unpressed Amiga-style button
- return AgiTextColor(amigaWhite, amigaGreen);
- }
- } else { // _amigaStyle && !positive
- if (pressed) { // Negative pressed Amiga-style button
- return AgiTextColor(amigaBlack, amigaCyan);
- } else { // Negative unpressed Amiga-style button
- return AgiTextColor(amigaWhite, amigaRed);
- }
- }
- } else { // PC-style button
- if (hasFocus || pressed) { // A pressed or in focus PC-style button
- return AgiTextColor(pcWhite, pcBlack);
- } else { // An unpressed PC-style button without focus
- return AgiTextColor(pcBlack, pcWhite);
- }
- }
-}
-
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
- return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
-}
-
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
- if (hasFocus || pressed)
- return baseColor.swap();
- else
- return baseColor;
-}
-
-int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
- return (pressed && !_amigaStyle) ? 1 : 0;
-}
-
-bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
- return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
-}
-
-void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
- _amigaStyle = amigaStyle;
- _olderAgi = olderAgi;
- _authenticAmiga = authenticAmiga;
-}
-
-void AgiButtonStyle::setPcStyle(bool pcStyle) {
- setAmigaStyle(!pcStyle);
-}
-
-AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
- setAmigaStyle(renderMode == Common::kRenderAmiga);
-}
-
AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
_noSaveLoadAllowed = false;
@@ -671,7 +516,7 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
parseFeatures();
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "agi");
+ g_eventRec.registerRandomSource(*_rnd, "agi");
Common::addDebugChannel(kDebugLevelMain, "Main", "Generic debug level");
Common::addDebugChannel(kDebugLevelResources, "Resources", "Resources debugging");
@@ -718,6 +563,12 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_predictiveDictLine = NULL;
_predictiveDictLineCount = 0;
_firstSlot = 0;
+
+ // NOTE: On game reload the keys do not get set again,
+ // thus it is incorrect to reset it in agiInit(). Fixes bug #2823762
+ _game.lastController = 0;
+ for (int i = 0; i < MAX_DIRS; i++)
+ _game.controllerOccured[i] = false;
}
void AgiEngine::initialize() {
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 14e1fd448b..ab572b0dd0 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -760,8 +760,6 @@ public:
void initVersion(void);
void setVersion(uint16 version);
- Common::Error loadGameState(int slot);
- Common::Error saveGameState(int slot, const char *desc);
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
};
@@ -785,6 +783,8 @@ public:
return _gameId;
}
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const char *desc);
private:
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index bf4622bc08..d212f8c2e0 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -328,7 +328,7 @@ int AgiEngine::playGame() {
_game.vars[vKey] = 0;
debugC(2, kDebugLevelMain, "Entering main loop");
- bool firstLoop = true;
+ bool firstLoop = !getflag(fRestartGame); // Do not restore on game restart
do {
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 910f6e0e55..553e42f88e 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -1290,20 +1290,6 @@ const ADGameDescription *AgiMetaEngine::fallbackDetect(const Common::FSList &fsl
namespace Agi {
-Common::Error AgiBase::loadGameState(int slot) {
- static char saveLoadSlot[12];
- sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
- loadGame(saveLoadSlot);
- return Common::kNoError; // TODO: return success/failure
-}
-
-Common::Error AgiBase::saveGameState(int slot, const char *desc) {
- static char saveLoadSlot[12];
- sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
- saveGame(saveLoadSlot, desc);
- return Common::kNoError; // TODO: return success/failure
-}
-
bool AgiBase::canLoadGameStateCurrently() {
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed);
}
@@ -1312,4 +1298,19 @@ bool AgiBase::canSaveGameStateCurrently() {
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed && _game.inputEnabled);
}
+int AgiEngine::agiDetectGame() {
+ int ec = errOK;
+
+ assert(_gameDescription != NULL);
+
+ if (getVersion() <= 0x2999) {
+ _loader = new AgiLoader_v2(this);
+ } else {
+ _loader = new AgiLoader_v3(this);
+ }
+ ec = _loader->detectGame();
+
+ return ec;
+}
+
} // End of namespace Agi
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
index 6604587051..b47a39e592 100644
--- a/engines/agi/keyboard.cpp
+++ b/engines/agi/keyboard.cpp
@@ -393,6 +393,11 @@ int AgiEngine::waitKey() {
_gfx->doUpdate();
}
+
+ // Have to clear it as original did not set this variable, and we do it in doPollKeyboard()
+ // Fixes bug #2823759
+ _game.keypress = 0;
+
return key;
}
@@ -409,7 +414,33 @@ int AgiEngine::waitAnyKey() {
break;
_gfx->doUpdate();
}
+
+ // Have to clear it as original did not set this variable, and we do it in doPollKeyboard()
+ _game.keypress = 0;
+
return key;
}
+bool AgiEngine::isKeypress(void) {
+ processEvents();
+ return _keyQueueStart != _keyQueueEnd;
+}
+
+int AgiEngine::getKeypress(void) {
+ int k;
+
+ while (_keyQueueStart == _keyQueueEnd) // block
+ pollTimer();
+
+ keyDequeue(k);
+
+ return k;
+}
+
+void AgiEngine::clearKeyQueue(void) {
+ while (isKeypress()) {
+ getKeypress();
+ }
+}
+
} // End of namespace Agi
diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp
index 27e234ebc9..5d30eda81d 100644
--- a/engines/agi/menu.cpp
+++ b/engines/agi/menu.cpp
@@ -493,4 +493,66 @@ void Menu::enableAll() {
}
}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
+ if (_amigaStyle) {
+ if (positive) {
+ if (pressed) { // Positive pressed Amiga-style button
+ if (_olderAgi) {
+ return AgiTextColor(amigaBlack, amigaOrange);
+ } else {
+ return AgiTextColor(amigaBlack, amigaPurple);
+ }
+ } else { // Positive unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaGreen);
+ }
+ } else { // _amigaStyle && !positive
+ if (pressed) { // Negative pressed Amiga-style button
+ return AgiTextColor(amigaBlack, amigaCyan);
+ } else { // Negative unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaRed);
+ }
+ }
+ } else { // PC-style button
+ if (hasFocus || pressed) { // A pressed or in focus PC-style button
+ return AgiTextColor(pcWhite, pcBlack);
+ } else { // An unpressed PC-style button without focus
+ return AgiTextColor(pcBlack, pcWhite);
+ }
+ }
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
+ return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
+ if (hasFocus || pressed)
+ return baseColor.swap();
+ else
+ return baseColor;
+}
+
+int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
+ return (pressed && !_amigaStyle) ? 1 : 0;
+}
+
+bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
+ return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
+}
+
+void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
+ _amigaStyle = amigaStyle;
+ _olderAgi = olderAgi;
+ _authenticAmiga = authenticAmiga;
+}
+
+void AgiButtonStyle::setPcStyle(bool pcStyle) {
+ setAmigaStyle(!pcStyle);
+}
+
+AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
+ setAmigaStyle(renderMode == Common::kRenderAmiga);
+}
+
} // End of namespace Agi
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index e728f2f695..7a6608d0d0 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -1267,7 +1267,7 @@ void Mickey::pressOB(int iButton) {
}
// print pressed buttons
- printLine("MICKEY HAS PRESSED: ");
+ printLine("MICKEY HAS PRESSED: ");
_vm->drawStr(20, 22, IDA_DEFAULT, szButtons);
waitAnyKey();
}
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 7c84f1dd72..50b329c0b6 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -32,6 +32,7 @@
#include "common/file.h"
#include "graphics/thumbnail.h"
+#include "common/config-manager.h"
#include "agi/agi.h"
#include "agi/graphics.h"
@@ -925,4 +926,85 @@ int AgiEngine::loadGameSimple() {
return rc;
}
+void AgiEngine::recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
+ int16 p4, int16 p5, int16 p6, int16 p7) {
+ ImageStackElement pnew;
+
+ pnew.type = type;
+ pnew.pad = 0;
+ pnew.parm1 = p1;
+ pnew.parm2 = p2;
+ pnew.parm3 = p3;
+ pnew.parm4 = p4;
+ pnew.parm5 = p5;
+ pnew.parm6 = p6;
+ pnew.parm7 = p7;
+
+ _imageStack.push(pnew);
+}
+
+void AgiEngine::replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
+ int16 p4, int16 p5, int16 p6, int16 p7) {
+ switch (type) {
+ case ADD_PIC:
+ debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1);
+ agiLoadResource(rPICTURE, p1);
+ _picture->decodePicture(p1, p2, p3 != 0);
+ break;
+ case ADD_VIEW:
+ agiLoadResource(rVIEW, p1);
+ _sprites->addToPic(p1, p2, p3, p4, p5, p6, p7);
+ break;
+ }
+}
+
+void AgiEngine::clearImageStack(void) {
+ _imageStack.clear();
+}
+
+void AgiEngine::releaseImageStack(void) {
+ _imageStack.clear();
+}
+
+void AgiEngine::checkQuickLoad() {
+ if (ConfMan.hasKey("save_slot")) {
+ char saveNameBuffer[256];
+
+ snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot"));
+
+ _sprites->eraseBoth();
+ _sound->stopSound();
+
+ if (loadGame(saveNameBuffer, false) == errOK) { // Do not check game id
+ _game.exitAllLogics = 1;
+ _menu->enableAll();
+ }
+ }
+}
+
+Common::Error AgiEngine::loadGameState(int slot) {
+ static char saveLoadSlot[12];
+ sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
+
+ _sprites->eraseBoth();
+ _sound->stopSound();
+
+ if (loadGame(saveLoadSlot) == errOK) {
+ _game.exitAllLogics = 1;
+ _menu->enableAll();
+ return Common::kNoError;
+ } else {
+ return Common::kUnknownError;
+ }
+}
+
+Common::Error AgiEngine::saveGameState(int slot, const char *desc) {
+ static char saveLoadSlot[12];
+ sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
+ if (saveGame(saveLoadSlot, desc) == errOK)
+ return Common::kNoError;
+ else
+ return Common::kUnknownError;
+}
+
} // End of namespace Agi
diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp
index f3c0b7365c..63ac880267 100644
--- a/engines/agi/sprite.cpp
+++ b/engines/agi/sprite.cpp
@@ -56,9 +56,10 @@ struct Sprite {
void *SpritesMgr::poolAlloc(int size) {
uint8 *x;
- // Adjust size to 32-bit boundary to prevent data misalignment
+ // Adjust size to sizeof(void *) boundary to prevent data misalignment
// errors.
- size = (size + 3) & ~3;
+ const int alignPadding = sizeof(void*) - 1;
+ size = (size + alignPadding) & ~alignPadding;
x = _poolTop;
_poolTop += size;