aboutsummaryrefslogtreecommitdiff
path: root/engines/made
diff options
context:
space:
mode:
authorBenjamin Haisch2008-04-30 20:36:19 +0000
committerBenjamin Haisch2008-04-30 20:36:19 +0000
commit7509d66caf516d87f938f66a20f4ce81367a8305 (patch)
tree3ce463b2c13d8d0c1ad5259279f49e3e4f10a300 /engines/made
parente866aefdfdf7386cd3f5c94a058dd329c44b8fde (diff)
downloadscummvm-rg350-7509d66caf516d87f938f66a20f4ce81367a8305.tar.gz
scummvm-rg350-7509d66caf516d87f938f66a20f4ce81367a8305.tar.bz2
scummvm-rg350-7509d66caf516d87f938f66a20f4ce81367a8305.zip
Implemented savegame loading/saving and sprite clipping
Fixed bug in Screen::printTextEx Implemented opcodes: - o1_DRAWTEXT - o1_DRAWMENU - o1_MENUCOUNT - o1_SAVEGAME - o1_LOADGAME - o1_GAMENAME svn-id: r31794
Diffstat (limited to 'engines/made')
-rw-r--r--engines/made/database.cpp84
-rw-r--r--engines/made/database.h5
-rw-r--r--engines/made/screen.cpp47
-rw-r--r--engines/made/scriptfuncs.cpp91
4 files changed, 189 insertions, 38 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index 7c6afda197..d5c45fa1b9 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -23,8 +23,10 @@
*
*/
+#include "common/system.h"
#include "common/endian.h"
#include "common/util.h"
+#include "common/savefile.h"
#include "made/database.h"
@@ -222,8 +224,7 @@ void GameDatabase::load(Common::SeekableReadStream &sourceS) {
uint32 objectsSize = sourceS.readUint32LE();
_mainCodeObjectIndex = sourceS.readUint16LE();
- debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n",
- objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
+ //debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
_gameState = new byte[_gameStateSize];
sourceS.seek(gameStateOffs);
@@ -241,14 +242,14 @@ void GameDatabase::load(Common::SeekableReadStream &sourceS) {
// Constant objects are loaded from disk, while variable objects exist
// in the _gameState buffer.
- debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]);
+ //debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]);
if (objectOffsets[i] & 1) {
- debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
+ //debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
sourceS.seek(objectsOffs + objectOffsets[i] - 1);
obj->load(sourceS);
} else {
- debug(2, "-> var\n");
+ //debug(2, "-> var\n");
obj->load(_gameState + objectOffsets[i]);
}
_objects.push_back(obj);
@@ -256,6 +257,79 @@ void GameDatabase::load(Common::SeekableReadStream &sourceS) {
}
+bool GameDatabase::getSavegameDescription(const char *filename, Common::String &description) {
+
+ Common::InSaveFile *in;
+
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ return false;
+ }
+
+ char desc[64];
+
+ in->skip(4); // TODO: Verify marker 'SGAM'
+ in->skip(4); // TODO: Verify size
+ in->skip(2); // TODO: Verify version
+ in->read(desc, 64);
+ description = desc;
+
+ printf("description = %s\n", description.c_str()); fflush(stdout);
+
+ delete in;
+
+ return true;
+
+}
+
+int16 GameDatabase::savegame(const char *filename, const char *description, int16 version) {
+
+ Common::OutSaveFile *out;
+
+ if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
+ warning("Can't create file '%s', game not saved", filename);
+ return 6;
+ }
+
+ uint32 size = 4 + 4 + 2 + _gameStateSize;
+ char desc[64];
+
+ strncpy(desc, description, 64);
+
+ out->writeUint32BE(MKID_BE('SGAM'));
+ out->writeUint32LE(size);
+ out->writeUint16LE(version);
+ out->write(desc, 64);
+ out->write(_gameState, _gameStateSize);
+
+ delete out;
+
+ return 0;
+
+}
+
+int16 GameDatabase::loadgame(const char *filename, int16 version) {
+
+ Common::InSaveFile *in;
+
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ warning("Can't open file '%s', game not loaded", filename);
+ return 1;
+ }
+
+ //uint32 expectedSize = 4 + 4 + 2 + _gameStateSize;
+
+ in->skip(4); // TODO: Verify marker 'SGAM'
+ in->skip(4); // TODO: Verify size
+ in->skip(2); // TODO: Verify version
+ in->skip(64); // skip savegame description
+ in->read(_gameState, _gameStateSize);
+
+ delete in;
+
+ return 0;
+
+}
+
int16 GameDatabase::getVar(int16 index) {
return (int16)READ_LE_UINT16(_gameState + index * 2);
}
diff --git a/engines/made/database.h b/engines/made/database.h
index 5e88b0919f..c5d3916e25 100644
--- a/engines/made/database.h
+++ b/engines/made/database.h
@@ -30,6 +30,7 @@
#include "common/util.h"
#include "common/file.h"
#include "common/stream.h"
+#include "common/str.h"
#include "made/redreader.h"
@@ -78,6 +79,10 @@ public:
void open(const char *filename);
void openFromRed(const char *redFilename, const char *filename);
+ bool getSavegameDescription(const char *filename, Common::String &description);
+ int16 savegame(const char *filename, const char *description, int16 version);
+ int16 loadgame(const char *filename, int16 version);
+
Object *getObject(int16 index) const {
if (index >= 1)
return _objects[index - 1];
diff --git a/engines/made/screen.cpp b/engines/made/screen.cpp
index ad1627c6df..74053e70a2 100644
--- a/engines/made/screen.cpp
+++ b/engines/made/screen.cpp
@@ -92,23 +92,41 @@ void Screen::clearScreen() {
_screen1->fillRect(Common::Rect(0, 0, 320, 200), 0);
_screen2->fillRect(Common::Rect(0, 0, 320, 200), 0);
_needPalette = true;
- //_vm->_system->clearScreen();
}
void Screen::drawSurface(Graphics::Surface *sourceSurface, int x, int y, const ClipInfo &clipInfo) {
- byte *source = (byte*)sourceSurface->getBasePtr(0, 0);
- byte *dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
+ byte *source, *dest;
+ int startX = 0;
+ int startY = 0;
+ int clipWidth = sourceSurface->w;
+ int clipHeight = sourceSurface->h;
+
+ if (x < 0) {
+ startX = -x;
+ clipWidth -= startX;
+ x = 0;
+ }
- // FIXME: Implement actual clipping
- if (x + sourceSurface->w > clipInfo.destSurface->w || y + sourceSurface->h > clipInfo.destSurface->h) {
- debug(2, "CLIPPING PROBLEM: x = %d; y = %d; w = %d; h = %d; x+w = %d; y+h = %d\n",
- x, y, sourceSurface->w, sourceSurface->h, x + sourceSurface->w, y + sourceSurface->h);
- return;
+ if (y < 0) {
+ startY = -y;
+ clipHeight -= startY;
+ y = 0;
}
- for (int16 yc = 0; yc < sourceSurface->h; yc++) {
- for (int16 xc = 0; xc < sourceSurface->w; xc++) {
+ if (x + clipWidth > clipInfo.x + clipInfo.w) {
+ clipWidth = clipInfo.x + clipInfo.w - x;
+ }
+
+ if (y + clipHeight > clipInfo.y + clipInfo.h) {
+ clipHeight = clipInfo.y + clipInfo.h - y;
+ }
+
+ source = (byte*)sourceSurface->getBasePtr(startX, startY);
+ dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
+
+ for (int16 yc = 0; yc < clipHeight; yc++) {
+ for (int16 xc = 0; xc < clipWidth; xc++) {
if (source[xc])
dest[xc] = source[xc];
}
@@ -133,7 +151,7 @@ void Screen::setRGBPalette(byte *palRGB, int start, int count) {
}
uint16 Screen::updateChannel(uint16 channelIndex) {
- return 0;
+ return channelIndex;
}
void Screen::deleteChannel(uint16 channelIndex) {
@@ -303,10 +321,6 @@ void Screen::drawAnimFrame(uint16 animIndex, int16 x, int16 y, int16 frameNum, u
}
uint16 Screen::drawPic(uint16 index, int16 x, int16 y, uint16 flag1, uint16 flag2) {
-
- //HACK (until clipping is implemented)
- if (y > 200) y = 0;
-
drawFlex(index, x, y, flag1, flag2, _clipInfo1);
return 0;
}
@@ -624,7 +638,6 @@ void Screen::printText(const char *text) {
linePos = 1;
x = _textRect.left;
} else if (c == 32) {
- // TODO: Word-wrap
int wrapPos = textPos + 1;
int wrapX = x + charWidth;
while (wrapPos < textLen && text[wrapPos] != 0 && text[wrapPos] != 32 && text[wrapPos] >= 28) {
@@ -682,6 +695,7 @@ void Screen::printTextEx(const char *text, int16 x, int16 y, int16 fontNum, int1
int16 oldFontNum = _currentFontNum;
Common::Rect oldTextRect;
+ ClipInfo oldFontDrawCtx = _fontDrawCtx;
_fontDrawCtx = clipInfo;
@@ -693,6 +707,7 @@ void Screen::printTextEx(const char *text, int16 x, int16 y, int16 fontNum, int1
printText(text);
setTextRect(oldTextRect);
setFont(oldFontNum);
+ _fontDrawCtx = oldFontDrawCtx;
}
diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp
index 5ab748953b..4b2d7e696b 100644
--- a/engines/made/scriptfuncs.cpp
+++ b/engines/made/scriptfuncs.cpp
@@ -408,9 +408,9 @@ int16 ScriptFunctionsRtz::o1_FONT(int16 argc, int16 *argv) {
}
int16 ScriptFunctionsRtz::o1_DRAWTEXT(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_DRAWTEXT");
Object *obj = _vm->_dat->getObject(argv[argc - 1]);
- warning("argc = %d; drawText = %s", argc, obj->getString());
+ const char *text = obj->getString();
+ _vm->_screen->printText(text);
return 0;
}
@@ -420,7 +420,6 @@ int16 ScriptFunctionsRtz::o1_HOMETEXT(int16 argc, int16 *argv) {
}
int16 ScriptFunctionsRtz::o1_TEXTRECT(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_TEXTRECT");
int16 x1 = CLIP<int16>(argv[4], 1, 318);
int16 y1 = CLIP<int16>(argv[3], 1, 198);
int16 x2 = CLIP<int16>(argv[2], 1, 318);
@@ -536,7 +535,9 @@ int16 ScriptFunctionsRtz::o1_CDPLAYSEG(int16 argc, int16 *argv) {
}
int16 ScriptFunctionsRtz::o1_PRINTF(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_PRINTF");
+ Object *obj = _vm->_dat->getObject(argv[argc - 1]);
+ const char *text = obj->getString();
+ debug(4, "--> text = %s", text);
return 0;
}
@@ -556,7 +557,7 @@ int16 ScriptFunctionsRtz::o1_SNDENERGY(int16 argc, int16 *argv) {
int16 ScriptFunctionsRtz::o1_CLEARTEXT(int16 argc, int16 *argv) {
warning("Unimplemented opcode: o1_CLEARTEXT");
- return 0;
+ return 1;
}
int16 ScriptFunctionsRtz::o1_ANIMTEXT(int16 argc, int16 *argv) {
@@ -746,33 +747,89 @@ int16 ScriptFunctionsRtz::o1_READMENU(int16 argc, int16 *argv) {
}
int16 ScriptFunctionsRtz::o1_DRAWMENU(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_DRAWMENU");
+ int16 menuIndex = argv[1];
+ int16 textIndex = argv[0];
+ MenuResource *menu = _vm->_res->getMenu(menuIndex);
+ if (menu) {
+ const char *text = menu->getString(textIndex);
+ if (text)
+ _vm->_screen->printText(text);
+ _vm->_res->freeResource(menu);
+ }
return 0;
}
int16 ScriptFunctionsRtz::o1_MENUCOUNT(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_MENUCOUNT");
- return 0;
+ int16 menuIndex = argv[0];
+ int16 count = 0;
+ MenuResource *menu = _vm->_res->getMenu(menuIndex);
+ if (menu) {
+ count = menu->getCount();
+ _vm->_res->freeResource(menu);
+ }
+ return count;
}
int16 ScriptFunctionsRtz::o1_SAVEGAME(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_SAVEGAME");
- return 0;
+
+ int16 saveNum = argv[2];
+ int16 descObjectIndex = argv[1];
+ int16 version = argv[0];
+
+ if (saveNum > 999)
+ return 6;
+
+ Object *obj = _vm->_dat->getObject(descObjectIndex);
+ const char *description = obj->getString();
+
+ // TODO: Use better filename
+ char filename[256];
+ snprintf(filename, 256, "rtz.%03d", saveNum);
+
+ return _vm->_dat->savegame(filename, description, version);
+
}
int16 ScriptFunctionsRtz::o1_LOADGAME(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_LOADGAME");
- return 0;
+
+ int16 saveNum = argv[1];
+ int16 version = argv[0];
+
+ if (saveNum > 999)
+ return 1;
+
+ // TODO: Use better filename
+ char filename[256];
+ snprintf(filename, 256, "rtz.%03d", saveNum);
+
+ return _vm->_dat->loadgame(filename, version);
+
}
int16 ScriptFunctionsRtz::o1_GAMENAME(int16 argc, int16 *argv) {
- warning("Unimplemented opcode: o1_GAMENAME");
- warning("GAMENAME: 1) %d\n", argv[2]);
- warning("GAMENAME: 2) %d\n", argv[1]);
- warning("GAMENAME: 3) %d\n", argv[0]);
+ int16 descObjectIndex = argv[2];
+ int16 saveNum = argv[1];
+ int16 version = argv[0];
+ Common::String description;
+
+ if (saveNum > 999)
+ return 1;
+
+ // TODO: Use better filename
+ char filename[256];
+ snprintf(filename, 256, "rtz.%03d", saveNum);
+
+ Object *obj = _vm->_dat->getObject(descObjectIndex);
+
+ if (_vm->_dat->getSavegameDescription(filename, description)) {
+ obj->setString(description.c_str());
+ return 0;
+ } else {
+ obj->setString("");
+ return 1;
+ }
- return 0;
}
int16 ScriptFunctionsRtz::o1_SHAKESCREEN(int16 argc, int16 *argv) {