aboutsummaryrefslogtreecommitdiff
path: root/engines/macventure
diff options
context:
space:
mode:
authorBorja Lorente2016-07-16 19:57:36 +0200
committerBorja Lorente2016-08-14 18:55:17 +0200
commita06f291280e0897beed18e63e269938dfa45ccef (patch)
treefa589f2c5cdda38677f343c89429aa8cce71a903 /engines/macventure
parent734b453c86bb20b2cb52c4f695f8a770b97be459 (diff)
downloadscummvm-rg350-a06f291280e0897beed18e63e269938dfa45ccef.tar.gz
scummvm-rg350-a06f291280e0897beed18e63e269938dfa45ccef.tar.bz2
scummvm-rg350-a06f291280e0897beed18e63e269938dfa45ccef.zip
MACVENTURE: Add basic game save/load feature
Diffstat (limited to 'engines/macventure')
-rw-r--r--engines/macventure/dialog.cpp11
-rw-r--r--engines/macventure/dialog.h3
-rw-r--r--engines/macventure/gui.cpp38
-rw-r--r--engines/macventure/gui.h4
-rw-r--r--engines/macventure/image.cpp4
-rw-r--r--engines/macventure/macventure.cpp52
-rw-r--r--engines/macventure/macventure.h13
-rw-r--r--engines/macventure/world.cpp55
-rw-r--r--engines/macventure/world.h12
9 files changed, 144 insertions, 48 deletions
diff --git a/engines/macventure/dialog.cpp b/engines/macventure/dialog.cpp
index 3a09feffd5..ba489d4bad 100644
--- a/engines/macventure/dialog.cpp
+++ b/engines/macventure/dialog.cpp
@@ -43,7 +43,7 @@ PrebuiltDialog prebuiltDialogs[kPrebuiltDialogCount] = {
{/* kSaveAsDialog */
Common::Rect(0, 146, 456, 254),
{
- {kDEButton, "YES", kDANone, Common::Point(24, 68), 120, 22},
+ {kDEButton, "YES", kDASaveAs, Common::Point(24, 68), 120, 22},
{kDEButton, "NO", kDACloseDialog, Common::Point(168, 68), 120, 22},
{kDEButton, "CANCEL", kDACloseDialog, Common::Point(312, 68), 120, 22},
{kDEPlainText, "Save As...", kDANone, Common::Point(100, 10), 340, 38},
@@ -92,6 +92,10 @@ void Dialog::handleDialogAction(DialogElement *trigger, DialogAction action) {
_gui->setTextInput(_userInput);
_gui->closeDialog();
break;
+ case kDASaveAs:
+ _gui->saveInto(0);
+ _gui->closeDialog();
+ break;
}
}
@@ -169,11 +173,6 @@ DialogElement::DialogElement(Dialog *dialog, Common::String title, DialogAction
}
bool DialogElement::processEvent(MacVenture::Dialog *dialog, Common::Event event) {
- // HACK for test, please delete me
- Common::Point mouse = event.mouse;
- dialog->localize(mouse);
- if (_bounds.contains(mouse)) debug(1, "Hovering over: %s", _text.c_str());
-
return doProcessEvent(dialog, event);
}
diff --git a/engines/macventure/dialog.h b/engines/macventure/dialog.h
index 1dbebf77f2..e773956b09 100644
--- a/engines/macventure/dialog.h
+++ b/engines/macventure/dialog.h
@@ -38,7 +38,8 @@ class DialogElement;
enum DialogAction {
kDANone,
kDACloseDialog,
- kDASubmit
+ kDASubmit,
+ kDASaveAs
};
enum PrebuiltDialogs {
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp
index d8deb4b568..6c9ccf6a2f 100644
--- a/engines/macventure/gui.cpp
+++ b/engines/macventure/gui.cpp
@@ -335,8 +335,8 @@ WindowReference Gui::createInventoryWindow(ObjID objRef) {
newWindow->setDimensions(newData.bounds);
newWindow->setCallback(inventoryWindowCallback, this);
- //loadBorder(newWindow, "border_no_scroll_inac.bmp", false);
- //loadBorder(newWindow, "border_no_scroll_act.bmp", true);
+ loadBorder(newWindow, "border_no_scroll_inac.bmp", false);
+ loadBorder(newWindow, "border_no_scroll_act.bmp", true);
_inventoryWindows.push_back(newWindow);
debug("Create new inventory window. Reference: %d", newData.refcon);
@@ -686,13 +686,12 @@ void Gui::drawWindowTitle(WindowReference target, Graphics::ManagedSurface * sur
}
void Gui::drawDraggedObject() {
- if (_draggedObj.id != 0) {
+ if (_draggedObj.id != 0 &&
+ _engine->isObjVisible(_draggedObj.id)) {
ensureAssetLoaded(_draggedObj.id);
ImageAsset *asset = _assets[_draggedObj.id];
_draggedSurface.create(asset->getWidth(), asset->getHeight(), _screen.format);
- _screen.copyRectToSurface(_draggedSurface, _draggedObj.pos.x, _draggedObj.pos.y,
- Common::Rect(asset->getWidth() - 1, asset->getHeight() - 1));
asset->blitInto(&_draggedSurface, 0, 0, kBlitBIC);
@@ -820,6 +819,14 @@ void Gui::getTextFromUser() {
_engine->clickToContinue();
}
+void Gui::loadGame(int slot) {
+ _engine->loadGameState(slot);
+}
+
+void Gui::saveInto(int slot) {
+ _engine->saveGameState(slot, "desc");
+ _engine->preparedToRun();
+}
void Gui::moveDraggedObject(Common::Point target) {
Common::Point newPos = target + _draggedObj.mouseOffset;
@@ -857,9 +864,11 @@ WindowReference Gui::findWindowAtPoint(Common::Point point) {
Graphics::MacWindow *win;
for (it = _windowData->begin(); it != _windowData->end(); it++) {
win = findWindow(it->refcon);
- if (win && win->getDimensions().contains(point) && it->refcon != kDiplomaWindow) { //HACK, diploma should be cosnidered
- if (win->isActive())
- return it->refcon;
+ if (win && it->refcon != kDiplomaWindow) { //HACK, diploma should be cosnidered
+ if (win->getDimensions().contains(point)) {
+ if (win->isActive())
+ return it->refcon;
+ }
}
}
return kNoWindow;
@@ -869,6 +878,7 @@ Common::Point Gui::getWindowSurfacePos(WindowReference reference) {
const WindowData &data = getWindowData(reference);
BorderBounds border = borderBounds(data.type);
Graphics::MacWindow *win = findWindow(reference);
+ if (!win) return Common::Point(0, 0);
return Common::Point(win->getDimensions().left + border.leftOffset, win->getDimensions().top + border.topOffset);
}
@@ -976,9 +986,9 @@ void Gui::selectDraggable(ObjID child, WindowReference origin, Common::Point cli
}
void Gui::handleDragRelease(Common::Point pos, bool shiftPressed, bool isDoubleClick) {
- WindowReference destinationWindow = findWindowAtPoint(pos);
- if (destinationWindow == kNoWindow) return;
if (_draggedObj.id != 0) {
+ WindowReference destinationWindow = findWindowAtPoint(pos);
+ if (destinationWindow == kNoWindow) return;
if (_draggedObj.hasMoved) {
ObjID destObject = getWindowData(destinationWindow).objRef;
pos -= (_draggedObj.startPos - _draggedObj.mouseOffset);
@@ -1027,9 +1037,11 @@ void Gui::handleMenuAction(MenuAction action) {
break;
case MacVenture::kMenuActionOpen:
debug("MacVenture Menu Action: Open");
+ loadGame(0);
break;
case MacVenture::kMenuActionSave:
debug("MacVenture Menu Action: Save");
+ saveInto(0);
break;
case MacVenture::kMenuActionSaveAs:
debug("MacVenture Menu Action: Save As");
@@ -1139,8 +1151,8 @@ bool Gui::tryCloseWindow(WindowReference winID) {
Common::Point Gui::getObjMeasures(ObjID obj) {
ensureAssetLoaded(obj);
- int w = MAX(0, (int)_assets[obj]->getWidth());
- int h = MAX(0, (int)_assets[obj]->getHeight());
+ int w = _assets[obj]->getWidth();
+ int h = _assets[obj]->getHeight();
return Common::Point(w, h);
}
@@ -1296,7 +1308,7 @@ void Gui::processCursorTick() {
void Gui::handleSingleClick(Common::Point pos) {
debug("Single Click");
- // HACK
+ // HACK THERE HAS TO BE A MORE ELEGANT WAY
if (_dialog) return;
handleDragRelease(pos, false, false);
}
diff --git a/engines/macventure/gui.h b/engines/macventure/gui.h
index f800aeb835..b03ca2afe9 100644
--- a/engines/macventure/gui.h
+++ b/engines/macventure/gui.h
@@ -247,10 +247,14 @@ public:
void printText(const Common::String &text);
+ //Dialog interactions
void getTextFromUser();
void setTextInput(Common::String str);
void closeDialog();
+ void loadGame(int slot);
+ void saveInto(int slot);
+
// Ugly switches
BorderBounds borderBounds(MVWindowType type);
diff --git a/engines/macventure/image.cpp b/engines/macventure/image.cpp
index cbe3cc910d..fa281eb19a 100644
--- a/engines/macventure/image.cpp
+++ b/engines/macventure/image.cpp
@@ -387,11 +387,11 @@ bool ImageAsset::isRectInside(Common::Rect rect) {
}
uint ImageAsset::getWidth() {
- return _bitWidth;
+ return MAX(0, (int)_bitWidth);
}
uint ImageAsset::getHeight() {
- return _bitHeight;
+ return MAX(0, (int)_bitHeight);
}
void ImageAsset::blitDirect(Graphics::ManagedSurface * target, uint32 ox, uint32 oy, const Common::Array<byte>& data) {
diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp
index 1fca4288e8..9b764d9856 100644
--- a/engines/macventure/macventure.cpp
+++ b/engines/macventure/macventure.cpp
@@ -82,7 +82,6 @@ Common::Error MacVentureEngine::run() {
// Additional setup.
debug("MacVentureEngine::init");
-
_resourceManager = new Common::MacResManager();
if (!_resourceManager->open(getGameFileName()))
error("Could not open %s as a resource fork", getGameFileName());
@@ -113,7 +112,6 @@ Common::Error MacVentureEngine::run() {
_destObject = 0;
_prepared = true;
- //if !savegame
_cmdReady = true;
_selectedControl = kStartOrResume;
ObjID playerParent = _world->getObjAttr(1, kAttrParentObject);
@@ -162,6 +160,42 @@ Common::Error MacVentureEngine::run() {
return Common::kNoError;
}
+Common::Error MacVentureEngine::loadGameState(int slot) {
+ Common::InSaveFile *file = getSaveFileManager()->openForLoading("Shadowgate.1");
+ _world->loadGameFrom(file);
+ reset();
+ return Common::kNoError;
+}
+
+Common::Error MacVentureEngine::saveGameState(int slot, const Common::String &desc) {
+ Common::SaveFileManager *manager = getSaveFileManager();
+ // HACK Get a real name!
+ Common::OutSaveFile *file = manager->openForSaving("Shadowgate.1");
+ _world->saveGameInto(file);
+ delete file;
+}
+
+void MacVentureEngine::reset() {
+ resetInternals();
+ resetGui();
+}
+
+void MacVentureEngine::resetInternals() {
+ _scriptEngine->reset();
+ _currentSelection.clear();
+ _selectedObjs.clear();
+ _objQueue.clear();
+ _textQueue.clear();
+}
+
+void MacVentureEngine::resetGui() {
+ _gui->updateWindowInfo(kMainGameWindow, getParent(1), _world->getChildren(getParent(1), true));
+ // HACK! should update all inventories
+ _gui->updateWindowInfo(kInventoryStart, 1, _world->getChildren(1, true));
+ _gui->updateWindowInfo(kExitsWindow, getParent(1), _world->getChildren(getParent(1), true));
+}
+
+
void MacVentureEngine::requestQuit() {
// TODO: Display save game dialog and such
_gameState = kGameStateQuitting;
@@ -391,6 +425,20 @@ Common::String MacVentureEngine::getUserInput() {
return _userInput;
}
+
+Common::String MacVentureEngine::getStartGameFileName() {
+ Common::SeekableReadStream *res;
+ res = _resourceManager->getResource(MKTAG('S', 'T', 'R', ' '), kStartGameFilenameID);
+ if (!res)
+ return "";
+
+ byte length = res->readByte();
+ char *fileName = new char[length + 1];
+ res->read(fileName, length);
+ fileName[length] = '\0';
+ return Common::String(fileName, length);
+}
+
const GlobalSettings& MacVentureEngine::getGlobalSettings() const {
return _globalSettings;
}
diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h
index f6a3ea66af..167abcc351 100644
--- a/engines/macventure/macventure.h
+++ b/engines/macventure/macventure.h
@@ -24,10 +24,13 @@
#define MACVENTURE_H
#include "engines/engine.h"
+#include "common/scummsys.h"
+#include "common/system.h"
#include "common/debug.h"
#include "common/random.h"
#include "common/macresman.h"
#include "common/huffman.h"
+#include "common/savefile.h"
#include "gui/debugger.h"
@@ -41,6 +44,8 @@ struct ADGameDescription;
namespace MacVenture {
+class SaveFileManager;
+
class Console;
class World;
class ScriptEngine;
@@ -158,6 +163,12 @@ public:
~MacVentureEngine();
virtual Common::Error run();
+ virtual Common::Error loadGameState(int slot);
+ virtual Common::Error saveGameState(int slot, const Common::String &desc);
+
+ void reset();
+ void resetInternals();
+ void resetGui();
void requestQuit();
void requestUnpause();
@@ -189,7 +200,9 @@ public:
void setTextInput(Common::String content);
Common::String getUserInput();
+
// Data retrieval
+ Common::String getStartGameFileName();
bool isPaused();
bool needsClickToContinue();
Common::String getCommandsPausedString() const;
diff --git a/engines/macventure/world.cpp b/engines/macventure/world.cpp
index e247404eb6..cf13b78e48 100644
--- a/engines/macventure/world.cpp
+++ b/engines/macventure/world.cpp
@@ -9,7 +9,7 @@ World::World(MacVentureEngine *engine, Common::MacResManager *resMan) {
_resourceManager = resMan;
_engine = engine;
- if (!loadStartGameFileName())
+ if ((_startGameFileName = _engine->getStartGameFileName()) == "")
error("Could not load initial game configuration");
Common::File saveGameFile;
@@ -150,9 +150,11 @@ void World::updateObj(ObjID objID) {
}
void World::captureChildren(ObjID objID) {
+ warning("Capture children unimplemented!");
}
void World::releaseChildren(ObjID objID) {
+ warning("Release children unimplemented!");
}
Common::String World::getText(ObjID objID, ObjID source, ObjID target) {
@@ -175,23 +177,8 @@ bool World::intersects(ObjID objID, Common::Rect rect) {
return _engine->getObjBounds(objID).intersects(rect);
}
-bool World::loadStartGameFileName() {
- Common::SeekableReadStream *res;
-
- res = _resourceManager->getResource(MKTAG('S', 'T', 'R', ' '), kStartGameFilenameID);
- if (!res)
- return false;
-
- byte length = res->readByte();
- char *fileName = new char[length + 1];
- res->read(fileName, length);
- fileName[length] = '\0';
- _startGameFileName = Common::String(fileName, length);
-
- return true;
-}
-
void World::calculateObjectRelations() {
+ _relations.clear();
ObjID val, next;
uint32 numObjs = _engine->getGlobalSettings().numObjects;
const AttributeGroup &parents = *_saveGame->getGroup(0);
@@ -228,6 +215,16 @@ void World::setParent(ObjID child, ObjID newParent) {
_relations[oldNdx] = child;
}
+void World::loadGameFrom(Common::InSaveFile *file) {
+ if (_saveGame) delete _saveGame;
+ _saveGame = new SaveGame(_engine, file);
+ calculateObjectRelations();
+}
+
+void World::saveGameInto(Common::OutSaveFile *file) {
+ _saveGame->saveInto(file);
+}
+
// SaveGame
SaveGame::SaveGame(MacVentureEngine *engine, Common::SeekableReadStream *res) {
_groups = Common::Array<AttributeGroup>();
@@ -263,14 +260,34 @@ void SaveGame::setGlobal(uint32 attrID, Attribute value) {
_globals[attrID] = value;
}
-const Common::Array<uint16>& MacVenture::SaveGame::getGlobals() {
+const Common::Array<uint16>& SaveGame::getGlobals() {
return _globals;
}
-const Common::String & MacVenture::SaveGame::getText() {
+const Common::String & SaveGame::getText() {
return _text;
}
+void SaveGame::saveInto(Common::OutSaveFile *file) {
+ warning("Saving the game not yet tested!");
+ // Save attibutes
+ Common::Array<AttributeGroup>::const_iterator itg;
+ for(itg = _groups.begin(); itg != _groups.end(); itg++) {
+ Common::Array<Attribute>::const_iterator ita;
+ for (ita = itg->begin(); ita != itg->end(); ita++) {
+ file->writeUint16BE((*ita));
+ }
+ }
+ // Save globals
+ Common::Array<uint16>::const_iterator global;
+ for (global = _globals.begin(); global != _globals.end(); global++) {
+ file->writeUint16BE((*global));
+ }
+ // Save text
+ _text = "Hello";
+ file->write(_text.c_str(), _text.size());
+}
+
void SaveGame::loadGroups(MacVentureEngine *engine, Common::SeekableReadStream * res) {
GlobalSettings settings = engine->getGlobalSettings();
for (int i = 0; i < settings.numGroups; ++i) {
diff --git a/engines/macventure/world.h b/engines/macventure/world.h
index c023c70ec6..f3933c5f7e 100644
--- a/engines/macventure/world.h
+++ b/engines/macventure/world.h
@@ -74,6 +74,8 @@ public:
const AttributeGroup *getGroup(uint32 groupID);
const Common::String &getText();
+ void saveInto(Common::OutSaveFile *file);
+
private:
void loadGroups(MacVentureEngine *engine, Common::SeekableReadStream *res);
void loadGlobals(MacVentureEngine *engine, Common::SeekableReadStream *res);
@@ -90,7 +92,6 @@ public:
World(MacVentureEngine *engine, Common::MacResManager *resMan);
~World();
-
void setObjAttr(ObjID objID, uint32 attrID, Attribute value);
void setGlobal(uint32 attrID, Attribute value);
void updateObj(ObjID objID);
@@ -105,13 +106,15 @@ public:
ObjID getAncestor(ObjID objID);
Common::Array<ObjID> getFamily(ObjID objID, bool recursive);
- Common::Array<ObjID> getChildren(ObjID objID, bool recursive);
+ Common::Array<ObjID> getChildren(ObjID objID, bool recursive);
+
+ void loadGameFrom(Common::InSaveFile *file);
+ void saveGameInto(Common::OutSaveFile *file);
private:
bool isObjDraggable(ObjID objID);
bool intersects(ObjID objID, Common::Rect rect);
- bool loadStartGameFileName();
void calculateObjectRelations();
void setParent(ObjID child, ObjID newParent);
@@ -119,7 +122,7 @@ private:
MacVentureEngine *_engine;
Common::MacResManager *_resourceManager;
- Common::String _startGameFileName;
+ Common::String _startGameFileName;
SaveGame *_saveGame;
@@ -132,4 +135,3 @@ private:
} // End of namespace MacVenture
#endif
-