Fix bug #1726909 - HE Games: Glitches after loading saved games, by restircting HE games to their original load/save interface.

svn-id: r42675
This commit is contained in:
Travis Howell 2009-07-23 10:33:13 +00:00
parent 68a75c2170
commit c8d7b677f8
9 changed files with 42 additions and 21 deletions

1
README
View file

@ -772,6 +772,7 @@ site, please see the section on reporting bugs.
- Amiga versions aren't supported - Amiga versions aren't supported
Humongous Entertainment games: Humongous Entertainment games:
- Only the original load and save interface can be used.
- No support for printing images - No support for printing images

View file

@ -78,7 +78,7 @@ protected:
int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2); int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2);
void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2); void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2);
int convertFilePath(byte *dst); int convertFilePath(byte *dst, int dstSize);
virtual void decodeParseString(int a, int b); virtual void decodeParseString(int a, int b);
void swapObjects(int object1, int object2); void swapObjects(int object1, int object2);

View file

@ -1621,7 +1621,7 @@ void ScummEngine_v100he::o100_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer)); copyScriptString((byte *)buffer, sizeof(buffer));
r = convertFilePath(buffer); r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r); memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o100_roomOps: case 137: filename %s", _saveLoadFileName); debug(1, "o100_roomOps: case 137: filename %s", _saveLoadFileName);
@ -2239,7 +2239,7 @@ void ScummEngine_v100he::o100_videoOps() {
if (_videoParams.flags == 0) if (_videoParams.flags == 0)
_videoParams.flags = 4; _videoParams.flags = 4;
const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename); const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags == 2) { if (_videoParams.flags == 2) {
VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum); VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
} else { } else {

View file

@ -93,7 +93,7 @@ void ScummEngine_v60he::setupOpcodes() {
_opcodes[0xed].setProc(0, 0); _opcodes[0xed].setProc(0, 0);
} }
int ScummEngine_v60he::convertFilePath(byte *dst) { int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
debug(1, "convertFilePath: original filePath is %s", dst); debug(1, "convertFilePath: original filePath is %s", dst);
int len = resStrLen(dst); int len = resStrLen(dst);
@ -113,16 +113,25 @@ int ScummEngine_v60he::convertFilePath(byte *dst) {
// Strip path // Strip path
int r = 0; int r = 0;
if (dst[0] == '.' && dst[1] == '/') { // Game Data Path if (dst[len - 3] == 's' && dst[len - 2] == 'g') { // Save Game File
// Change filename prefix to target name, for save game files.
char saveName[20];
sprintf(saveName, "%s.sg%c", _targetName.c_str(), dst[len - 1]);
memcpy(dst, saveName, 20);
} else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
// The default game data path is set to './' by ScummVM
r = 2; r = 2;
} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100) } else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100)
// The default save game path is set to '*/' by ScummVM
r = 2; r = 2;
} else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71) } else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71)
// The default save path is game path (DOS) or 'c:/hegames/' (Windows)
for (r = len; r != 0; r--) { for (r = len; r != 0; r--) {
if (dst[r - 1] == '/') if (dst[r - 1] == '/')
break; break;
} }
} else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander) } else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander)
// The default save path is 'user/'
r = 5; r = 5;
} }
@ -269,7 +278,7 @@ void ScummEngine_v60he::o60_roomOps() {
len = resStrLen(_scriptPointer); len = resStrLen(_scriptPointer);
_scriptPointer += len + 1; _scriptPointer += len + 1;
r = convertFilePath(buffer); r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r); memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName); debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName);
@ -684,7 +693,7 @@ void ScummEngine_v60he::o60_openFile() {
len = resStrLen(_scriptPointer); len = resStrLen(_scriptPointer);
_scriptPointer += len + 1; _scriptPointer += len + 1;
filename = (char *)buffer + convertFilePath(buffer); filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "Final filename to %s", filename); debug(1, "Final filename to %s", filename);
mode = pop(); mode = pop();
@ -738,7 +747,7 @@ void ScummEngine_v60he::o60_deleteFile() {
len = resStrLen(_scriptPointer); len = resStrLen(_scriptPointer);
_scriptPointer += len + 1; _scriptPointer += len + 1;
filename = (char *)buffer + convertFilePath(buffer); filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "o60_deleteFile (\"%s\")", filename); debug(1, "o60_deleteFile (\"%s\")", filename);
@ -760,8 +769,8 @@ void ScummEngine_v60he::o60_rename() {
len = resStrLen(_scriptPointer); len = resStrLen(_scriptPointer);
_scriptPointer += len + 1; _scriptPointer += len + 1;
oldFilename = (char *)buffer1 + convertFilePath(buffer1); oldFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
newFilename = (char *)buffer2 + convertFilePath(buffer2); newFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
debug(1, "o60_rename (\"%s\" to \"%s\")", oldFilename, newFilename); debug(1, "o60_rename (\"%s\" to \"%s\")", oldFilename, newFilename);

View file

@ -713,7 +713,7 @@ void ScummEngine_v72he::o72_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer)); copyScriptString((byte *)buffer, sizeof(buffer));
r = convertFilePath(buffer); r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r); memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o72_roomOps: case 221: filename %s", _saveLoadFileName); debug(1, "o72_roomOps: case 221: filename %s", _saveLoadFileName);
@ -1401,7 +1401,7 @@ void ScummEngine_v72he::o72_openFile() {
strcpy((char *)buffer, "moonbase.ini"); strcpy((char *)buffer, "moonbase.ini");
} }
const char *filename = (char *)buffer + convertFilePath(buffer); const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "Final filename to %s", filename); debug(1, "Final filename to %s", filename);
slot = -1; slot = -1;
@ -1547,7 +1547,7 @@ void ScummEngine_v72he::o72_deleteFile() {
byte buffer[256]; byte buffer[256];
copyScriptString(buffer, sizeof(buffer)); copyScriptString(buffer, sizeof(buffer));
const char *filename = (char *)buffer + convertFilePath(buffer); const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "o72_deleteFile(%s)", filename); debug(1, "o72_deleteFile(%s)", filename);
@ -1562,8 +1562,8 @@ void ScummEngine_v72he::o72_rename() {
copyScriptString(buffer1, sizeof(buffer1)); copyScriptString(buffer1, sizeof(buffer1));
copyScriptString(buffer2, sizeof(buffer2)); copyScriptString(buffer2, sizeof(buffer2));
const char *newFilename = (char *)buffer1 + convertFilePath(buffer1); const char *newFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2); const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
_saveFileMan->renameSavefile(oldFilename, newFilename); _saveFileMan->renameSavefile(oldFilename, newFilename);

View file

@ -89,7 +89,7 @@ void ScummEngine_v80he::o80_getFileSize() {
byte buffer[256]; byte buffer[256];
copyScriptString(buffer, sizeof(buffer)); copyScriptString(buffer, sizeof(buffer));
const char *filename = (char *)buffer + convertFilePath(buffer); const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
Common::SeekableReadStream *f = 0; Common::SeekableReadStream *f = 0;
if (!_saveFileMan->listSavefiles(filename).empty()) { if (!_saveFileMan->listSavefiles(filename).empty()) {
@ -154,7 +154,7 @@ void ScummEngine_v80he::o80_readConfigFile() {
copyScriptString(section, sizeof(section)); copyScriptString(section, sizeof(section));
copyScriptString(filename, sizeof(filename)); copyScriptString(filename, sizeof(filename));
r = convertFilePath(filename); r = convertFilePath(filename, sizeof(filename));
if (_game.id == GID_TREASUREHUNT) { if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters // WORKAROUND: Remove invalid characters
@ -222,7 +222,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
error("o80_writeConfigFile: default type %d", subOp); error("o80_writeConfigFile: default type %d", subOp);
} }
r = convertFilePath(filename); r = convertFilePath(filename, sizeof(filename));
if (_game.id == GID_TREASUREHUNT) { if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters // WORKAROUND: Remove invalid characters

View file

@ -1426,7 +1426,7 @@ void ScummEngine_v90he::o90_videoOps() {
if (_videoParams.flags == 0) if (_videoParams.flags == 0)
_videoParams.flags = 4; _videoParams.flags = 4;
const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename); const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags & 2) { if (_videoParams.flags & 2) {
VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum); VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
} else { } else {

View file

@ -2083,7 +2083,7 @@ void Wiz::processWizImage(const WizParameters *params) {
Common::File f; Common::File f;
memcpy(filename, params->filename, 260); memcpy(filename, params->filename, 260);
_vm->convertFilePath(filename); _vm->convertFilePath(filename, sizeof(filename));
if (f.open((const char *)filename)) { if (f.open((const char *)filename)) {
uint32 id = f.readUint32BE(); uint32 id = f.readUint32BE();
@ -2126,7 +2126,7 @@ void Wiz::processWizImage(const WizParameters *params) {
break; break;
case 0: case 0:
memcpy(filename, params->filename, 260); memcpy(filename, params->filename, 260);
_vm->convertFilePath(filename); _vm->convertFilePath(filename, sizeof(filename));
if (!f.open((const char *)filename)) { if (!f.open((const char *)filename)) {
debug(0, "Unable to open for write '%s'", filename); debug(0, "Unable to open for write '%s'", filename);

View file

@ -86,6 +86,12 @@ bool ScummEngine::canLoadGameStateCurrently() {
// FIXME: Actually, we might wish to support loading in more places. // FIXME: Actually, we might wish to support loading in more places.
// As long as we are sure it won't cause any problems... Are we // As long as we are sure it won't cause any problems... Are we
// aware of *any* spots where loading is not supported? // aware of *any* spots where loading is not supported?
// HE games are limited to original load and save interface only,
// due to numerous glitches (see bug #1726909) that can occur.
if (_game.heversion >= 60)
return false;
return (VAR_MAINMENU_KEY == 0xFF || VAR(VAR_MAINMENU_KEY) != 0); return (VAR_MAINMENU_KEY == 0xFF || VAR(VAR_MAINMENU_KEY) != 0);
} }
@ -100,6 +106,11 @@ bool ScummEngine::canSaveGameStateCurrently() {
// e.g. when a SAN movie is playing? Not sure whether the // e.g. when a SAN movie is playing? Not sure whether the
// original EXE allowed this. // original EXE allowed this.
// HE games are limited to original load and save interface only,
// due to numerous glitches (see bug #1726909) that can occur.
if (_game.heversion >= 60)
return false;
// SCUMM v4+ doesn't allow saving in room 0 or if // SCUMM v4+ doesn't allow saving in room 0 or if
// VAR(VAR_MAINMENU_KEY) to set to zero. // VAR(VAR_MAINMENU_KEY) to set to zero.
return (VAR_MAINMENU_KEY == 0xFF || (VAR(VAR_MAINMENU_KEY) != 0 && _currentRoom != 0)); return (VAR_MAINMENU_KEY == 0xFF || (VAR(VAR_MAINMENU_KEY) != 0 && _currentRoom != 0));