aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/dataio.cpp262
-rw-r--r--engines/gob/dataio.h66
-rw-r--r--engines/gob/draw_v2.cpp2
-rw-r--r--engines/gob/game.cpp39
-rw-r--r--engines/gob/game.h10
-rw-r--r--engines/gob/hotspots.cpp5
-rw-r--r--engines/gob/inter_v2.cpp15
-rw-r--r--engines/gob/inter_v4.cpp5
-rw-r--r--engines/gob/inter_v6.cpp5
-rw-r--r--engines/gob/mult_v2.cpp11
-rw-r--r--engines/gob/save/saveload_playtoons.cpp2
-rw-r--r--engines/gob/util.cpp3
12 files changed, 233 insertions, 192 deletions
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp
index 99cf7c1193..3b7a61d485 100644
--- a/engines/gob/dataio.cpp
+++ b/engines/gob/dataio.cpp
@@ -35,21 +35,22 @@ namespace Gob {
DataStream::DataStream(DataIO &io, int16 handle, uint32 dSize, bool dispose) {
_io = &io;
- _handle = handle;
- _size = dSize;
+
+ _handle = handle;
+ _size = dSize;
_dispose = dispose;
- _data = 0;
+ _data = 0;
_stream = 0;
}
DataStream::DataStream(byte *buf, uint32 dSize, bool dispose) {
- _data = buf;
- _size = dSize;
- _stream = new Common::MemoryReadStream(_data, _size);
+ _data = buf;
+ _size = dSize;
+ _stream = new Common::MemoryReadStream(_data, _size);
_dispose = dispose;
- _io = 0;
+ _io = 0;
_handle = -1;
}
@@ -84,7 +85,7 @@ int32 DataStream::size() const {
bool DataStream::seek(int32 offset, int whence) {
if (_stream)
return _stream->seek(offset, whence);
- else if ((_handle < 50) || (_handle >= 128))
+ else if (!_io->isDataFileChunk(_handle))
return _io->file_getHandle(_handle)->seek(offset, whence);
else {
_io->seekChunk(_handle, offset, whence);
@@ -103,7 +104,7 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) {
if (_stream)
return _stream->read(dataPtr, dataSize);
- if ((_handle < 50) || (_handle >= 128))
+ if (!_io->isDataFileChunk(_handle))
return _io->file_getHandle(_handle)->read((byte *) dataPtr, dataSize);
byte *data = (byte *) dataPtr;
@@ -111,7 +112,7 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) {
while (dataSize > 0x3FFF) {
_io->readChunk(_handle, (byte *) data, 0x3FFF);
dataSize -= 0x3FFF;
- data += 0x3FFF;
+ data += 0x3FFF;
haveRead += 0x3FFF;
}
_io->readChunk(_handle, (byte *) data, dataSize);
@@ -121,11 +122,10 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) {
DataIO::DataIO(GobEngine *vm) : _vm(vm) {
for (int i = 0; i < MAX_DATA_FILES; i++) {
- _dataFiles[i] = 0;
- _numDataChunks[i] = 0;
+ _dataFiles[i] = 0;
+ _numDataChunks[i] = 0;
_dataFileHandles[i] = -1;
}
- _packedSize = 0;
}
DataIO::~DataIO() {
@@ -136,6 +136,46 @@ DataIO::~DataIO() {
}
}
+bool DataIO::isDataFileChunk(int16 handle) const {
+ return (handle >= 50) && (handle < 128);
+}
+
+bool DataIO::isPacked(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return false;
+
+ return _chunk[getIndex(handle)]->packed != 0;
+}
+
+int DataIO::getFile(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return -1;
+
+ return (handle - 50) / 10;
+}
+
+int DataIO::getSlot(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return -1;
+
+ return (handle - 50) % 10;
+}
+
+int DataIO::getIndex(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return -1;
+
+ return getIndex(getFile(handle), getSlot(handle));
+}
+
+int DataIO::getIndex(int file, int slot) const {
+ return file * MAX_SLOT_COUNT + slot;
+}
+
+int16 DataIO::getHandle(int file, int slot) const {
+ return file * 10 + slot + 50;
+}
+
int32 DataIO::unpackData(byte *src, byte *dest) {
uint32 realSize;
uint32 counter;
@@ -222,13 +262,11 @@ int16 DataIO::file_open(const char *path) {
}
int16 DataIO::getChunk(const char *chunkName) {
- int16 slot;
- struct ChunkDesc *dataDesc;
-
for (int16 file = 0; file < MAX_DATA_FILES; file++) {
if (_dataFiles[file] == 0)
return -1;
+ int16 slot;
for (slot = 0; slot < MAX_SLOT_COUNT; slot++)
if (_chunkPos[file * MAX_SLOT_COUNT + slot] == -1)
break;
@@ -238,59 +276,55 @@ int16 DataIO::getChunk(const char *chunkName) {
return -1;
}
- dataDesc = _dataFiles[file];
+ ChunkDesc *dataDesc = _dataFiles[file];
for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) {
if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0)
continue;
- _isCurrentSlot[file * MAX_SLOT_COUNT + slot] = false;
- _chunkSize[file * MAX_SLOT_COUNT + slot] = dataDesc->size;
- _chunkOffset[file * MAX_SLOT_COUNT + slot] = dataDesc->offset;
- _chunkPos[file * MAX_SLOT_COUNT + slot] = 0;
- return file * 10 + slot + 50;
+ int index = getIndex(file, slot);
+
+ _isCurrentSlot[index] = false;
+ _chunk [index] = dataDesc;
+ _chunkPos [index] = 0;
+
+ return getHandle(file, slot);
}
}
return -1;
}
char DataIO::freeChunk(int16 handle) {
- if ((handle >= 50) && (handle < 128)) {
- handle -= 50;
- _chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1;
+ if (isDataFileChunk(handle)) {
+ _chunkPos[getIndex(handle)] = -1;
return 0;
}
return 1;
}
int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) {
- int16 file;
- int16 slot;
- int16 i;
- int32 offset;
-
- if ((handle < 50) || (handle >= 128))
+ if (!isDataFileChunk(handle))
return -2;
- file = (handle - 50) / 10;
- slot = (handle - 50) % 10;
- int index = file * MAX_SLOT_COUNT + slot;
+ int file = getFile(handle);
+ int slot = getSlot(handle);
+ int index = getIndex(file, slot);
- _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunkSize[index]);
+ _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunk[index]->size);
if (!_isCurrentSlot[index]) {
- for (i = 0; i < MAX_SLOT_COUNT; i++)
+ for (int16 i = 0; i < MAX_SLOT_COUNT; i++)
_isCurrentSlot[file * MAX_SLOT_COUNT + i] = false;
- offset = _chunkOffset[index] + _chunkPos[index];
+ int32 offset = _chunk[index]->offset + _chunkPos[index];
- debugC(7, kDebugFileIO, "seek: %d, %d", _chunkOffset[index], _chunkPos[index]);
+ debugC(7, kDebugFileIO, "seek: %d, %d", _chunk[index]->offset, _chunkPos[index]);
file_getHandle(_dataFileHandles[file])->seek(offset, SEEK_SET);
}
_isCurrentSlot[index] = true;
- if ((_chunkPos[index] + size) > (_chunkSize[index]))
- size = _chunkSize[index] - _chunkPos[index];
+ if ((_chunkPos[index] + size) > (int32) (_chunk[index]->size))
+ size = _chunk[index]->size - _chunkPos[index];
file_getHandle(_dataFileHandles[file])->read(buf, size);
_chunkPos[index] += size;
@@ -298,15 +332,12 @@ int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) {
}
int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) {
- int16 file;
- int16 slot;
-
- if ((handle < 50) || (handle >= 128))
+ if (!isDataFileChunk(handle))
return -1;
- file = (handle - 50) / 10;
- slot = (handle - 50) % 10;
- int index = file * MAX_SLOT_COUNT + slot;
+ int file = getFile(handle);
+ int slot = getSlot(handle);
+ int index = getIndex(file, slot);
_isCurrentSlot[index] = false;
if (from == SEEK_SET)
@@ -314,50 +345,45 @@ int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) {
else if (from == SEEK_CUR)
_chunkPos[index] += pos;
else if (from == SEEK_END)
- _chunkPos[index] = _chunkSize[index] - pos;
+ _chunkPos[index] = _chunk[index]->size - pos;
return _chunkPos[index];
}
uint32 DataIO::getChunkPos(int16 handle) const {
- int16 file;
- int16 slot;
-
- if ((handle < 50) || (handle >= 128))
+ if (!isDataFileChunk(handle))
return 0xFFFFFFFF;
- file = (handle - 50) / 10;
- slot = (handle - 50) % 10;
+ int file = getFile(handle);
+ int slot = getSlot(handle);
return _chunkPos[file * MAX_SLOT_COUNT + slot];
}
-int32 DataIO::getChunkSize(const char *chunkName) {
- int16 file;
- struct ChunkDesc *dataDesc;
- int16 slot;
- int32 realSize;
-
- for (file = 0; file < MAX_DATA_FILES; file++) {
+int32 DataIO::getChunkSize(const char *chunkName, int32 &packSize) {
+ for (int16 file = 0; file < MAX_DATA_FILES; file++) {
if (_dataFiles[file] == 0)
return -1;
- dataDesc = _dataFiles[file];
+ ChunkDesc *dataDesc = _dataFiles[file];
for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) {
if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0)
continue;
if (dataDesc->packed == 0) {
- _packedSize = -1;
+ packSize = -1;
return dataDesc->size;
}
- for (slot = 0; slot < MAX_SLOT_COUNT; slot++)
+ for (int16 slot = 0; slot < MAX_SLOT_COUNT; slot++)
_isCurrentSlot[slot] = false;
+ int32 realSize;
+
file_getHandle(_dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET);
realSize = file_getHandle(_dataFileHandles[file])->readUint32LE();
- _packedSize = dataDesc->size;
+ packSize = dataDesc->size;
+
return realSize;
}
}
@@ -365,10 +391,7 @@ int32 DataIO::getChunkSize(const char *chunkName) {
}
void DataIO::openDataFile(const char *src, bool itk) {
- ChunkDesc *dataDesc;
char path[128];
- int16 file;
- char *fakeTotPtr;
strncpy0(path, src, 127);
if (!strchr(path, '.')) {
@@ -376,6 +399,7 @@ void DataIO::openDataFile(const char *src, bool itk) {
strcat(path, ".stk");
}
+ int16 file;
for (file = 0; file < MAX_DATA_FILES; file++)
if (_dataFiles[file] == 0)
break;
@@ -388,17 +412,17 @@ void DataIO::openDataFile(const char *src, bool itk) {
if (_dataFileHandles[file] == -1)
error("DataIO::openDataFile(): Can't open data file \"%s\"", path);
- _dataFileItk[file] = itk;
+ _dataFileItk [file] = itk;
_numDataChunks[file] = file_getHandle(_dataFileHandles[file])->readUint16LE();
debugC(7, kDebugFileIO, "DataChunks: %d [for %s]", _numDataChunks[file], path);
- dataDesc = new ChunkDesc[_numDataChunks[file]];
+ ChunkDesc *dataDesc = new ChunkDesc[_numDataChunks[file]];
_dataFiles[file] = dataDesc;
for (int i = 0; i < _numDataChunks[file]; i++) {
file_getHandle(_dataFileHandles[file])->read(dataDesc[i].chunkName, 13);
- dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE();
+ dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE();
dataDesc[i].offset = file_getHandle(_dataFileHandles[file])->readUint32LE();
dataDesc[i].packed = file_getHandle(_dataFileHandles[file])->readByte();
@@ -410,7 +434,7 @@ void DataIO::openDataFile(const char *src, bool itk) {
Util::replaceChar(dataDesc[i].chunkName, (char) 0x92, 'T');
// Geisha use 0ot files, which are compressed TOT files without the packed byte set.
- fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT");
+ char *fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT");
if (fakeTotPtr != 0) {
strncpy(fakeTotPtr, "TOT", 3);
dataDesc[i].packed = 1;
@@ -436,33 +460,29 @@ void DataIO::closeDataFile(bool itk) {
}
byte *DataIO::getUnpackedData(const char *name) {
- int32 realSize;
- int16 chunk;
- byte *unpackBuf;
- byte *packBuf;
- byte *ptr;
- int32 sizeLeft;
-
- realSize = getChunkSize(name);
- if ((_packedSize == -1) || (realSize == -1))
+ int32 realSize, packSize;
+
+ realSize = getChunkSize(name, packSize);
+
+ if ((packSize == -1) || (realSize == -1))
return 0;
- chunk = getChunk(name);
+ int16 chunk = getChunk(name);
if (chunk == -1)
return 0;
- unpackBuf = new byte[realSize];
+ byte *unpackBuf = new byte[realSize];
assert(unpackBuf);
- packBuf = new byte[_packedSize];
+ byte *packBuf = new byte[packSize];
assert(packBuf);
- sizeLeft = _packedSize;
- ptr = packBuf;
+ int32 sizeLeft = packSize;
+ byte *ptr = packBuf;
while (sizeLeft > 0x4000) {
readChunk(chunk, ptr, 0x4000);
sizeLeft -= 0x4000;
- ptr += 0x4000;
+ ptr += 0x4000;
}
readChunk(chunk, ptr, sizeLeft);
freeChunk(chunk);
@@ -478,9 +498,7 @@ void DataIO::closeData(int16 handle) {
}
int16 DataIO::openData(const char *path) {
- int16 handle;
-
- handle = getChunk(path);
+ int16 handle = getChunk(path);
if (handle >= 0)
return handle;
@@ -492,7 +510,6 @@ bool DataIO::existData(const char *path) {
return false;
int16 handle = openData(path);
-
if (handle < 0)
return false;
@@ -510,9 +527,7 @@ DataStream *DataIO::openAsStream(int16 handle, bool dispose) {
}
uint32 DataIO::getPos(int16 handle) {
- uint32 resPos;
-
- resPos = getChunkPos(handle);
+ uint32 resPos = getChunkPos(handle);
if (resPos != 0xFFFFFFFF)
return resPos;
@@ -520,9 +535,7 @@ uint32 DataIO::getPos(int16 handle) {
}
void DataIO::seekData(int16 handle, int32 pos, int16 from) {
- int32 resPos;
-
- resPos = seekChunk(handle, pos, from);
+ int32 resPos = seekChunk(handle, pos, from);
if (resPos != -1)
return;
@@ -530,9 +543,7 @@ void DataIO::seekData(int16 handle, int32 pos, int16 from) {
}
int32 DataIO::readData(int16 handle, byte *buf, uint16 size) {
- int32 res;
-
- res = readChunk(handle, buf, size);
+ int16 res = readChunk(handle, buf, size);
if (res >= 0)
return res;
@@ -541,45 +552,42 @@ int32 DataIO::readData(int16 handle, byte *buf, uint16 size) {
int32 DataIO::getDataSize(const char *name) {
char buf[128];
- int32 chunkSz;
- Common::File file;
strncpy0(buf, name, 127);
- chunkSz = getChunkSize(buf);
- if (chunkSz >= 0)
- return chunkSz;
+ int32 chunkSize, packSize;
+
+ chunkSize = getChunkSize(buf, packSize);
+ if (chunkSize >= 0)
+ return chunkSize;
+ Common::File file;
if (!file.open(buf))
error("DataIO::getDataSize(): Can't find data \"%s\"", name);
- chunkSz = file.size();
+ chunkSize = file.size();
file.close();
- return chunkSz;
+ return chunkSize;
}
byte *DataIO::getData(const char *path) {
- byte *data;
- byte *ptr;
- int32 size;
- int16 handle;
-
- data = getUnpackedData(path);
+ byte *data = getUnpackedData(path);
if (data)
return data;
- size = getDataSize(path);
+ int32 size = getDataSize(path);
+
data = new byte[size];
assert(data);
- handle = openData(path);
+ int16 handle = openData(path);
- ptr = data;
+ byte *ptr = data;
while (size > 0x4000) {
readData(handle, ptr, 0x4000);
size -= 0x4000;
- ptr += 0x4000;
+ ptr += 0x4000;
}
readData(handle, ptr, size);
closeData(handle);
@@ -588,12 +596,26 @@ byte *DataIO::getData(const char *path) {
DataStream *DataIO::getDataStream(const char *path) {
if (!existData(path))
+ return 0;
+
+ int16 handle = openData(path);
+ if (handle < 0)
return 0;
- uint32 size = getDataSize(path);
- byte *data = getData(path);
+ if (isDataFileChunk(handle) && isPacked(handle)) {
+ // It's a packed chunk in the data files, packed,
+ // so we have to read it in completely and unpack it
+
+ closeData(handle);
+
+ uint32 size = getDataSize(path);
+ byte *data = getData(path);
+
+ return new DataStream(data, size);
- return new DataStream(data, size);
+ } else
+ // Otherwise, we can just return a stream
+ return openAsStream(handle, true);
}
} // End of namespace Gob
diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h
index 1f55cac90d..6a86667e1b 100644
--- a/engines/gob/dataio.h
+++ b/engines/gob/dataio.h
@@ -26,16 +26,14 @@
#ifndef GOB_DATAIO_H
#define GOB_DATAIO_H
-
#include "common/endian.h"
-
#include "common/file.h"
namespace Gob {
-#define MAX_FILES 30
-#define MAX_DATA_FILES 8
-#define MAX_SLOT_COUNT 8
+#define MAX_FILES 30
+#define MAX_DATA_FILES 8
+#define MAX_SLOT_COUNT 8
class DataIO;
@@ -56,20 +54,20 @@ public:
private:
DataIO *_io;
- int16 _handle;
- uint32 _size;
- byte *_data;
+ int16 _handle;
+ uint32 _size;
+ byte *_data;
+ bool _dispose;
Common::MemoryReadStream *_stream;
- bool _dispose;
};
class DataIO {
public:
struct ChunkDesc {
- char chunkName[13];
+ char chunkName[13];
uint32 size;
uint32 offset;
- byte packed;
+ byte packed;
ChunkDesc() : size(0), offset(0), packed(0) { chunkName[0] = 0; }
};
@@ -77,10 +75,13 @@ public:
void openDataFile(const char *src, bool itk = 0);
void closeDataFile(bool itk = 0);
+
byte *getUnpackedData(const char *name);
- void closeData(int16 handle);
+
+ void closeData(int16 handle);
int16 openData(const char *path);
- bool existData(const char *path);
+ bool existData(const char *path);
+
DataStream *openAsStream(int16 handle, bool dispose = false);
int32 getDataSize(const char *name);
@@ -92,34 +93,47 @@ public:
protected:
Common::File _filesHandles[MAX_FILES];
- struct ChunkDesc *_dataFiles[MAX_DATA_FILES];
- uint16 _numDataChunks[MAX_DATA_FILES];
- int16 _dataFileHandles[MAX_DATA_FILES];
- bool _dataFileItk[MAX_DATA_FILES];
- int32 _chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES];
- int32 _chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES];
- int32 _chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES];
- bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES];
- int32 _packedSize;
+
+ ChunkDesc *_dataFiles [MAX_DATA_FILES];
+ uint16 _numDataChunks [MAX_DATA_FILES];
+ int16 _dataFileHandles[MAX_DATA_FILES];
+ bool _dataFileItk [MAX_DATA_FILES];
+
+ ChunkDesc *_chunk [MAX_SLOT_COUNT * MAX_DATA_FILES];
+ int32 _chunkPos [MAX_SLOT_COUNT * MAX_DATA_FILES];
+ bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES];
class GobEngine *_vm;
+ bool isDataFileChunk(int16 handle) const;
+ bool isPacked (int16 handle) const;
+
+ int getFile (int16 handle) const;
+ int getSlot (int16 handle) const;
+ int getIndex(int16 handle) const;
+
+ int getIndex (int file, int slot) const;
+ int16 getHandle(int file, int slot) const;
+
int16 file_open(const char *path);
Common::File *file_getHandle(int16 handle);
const Common::File *file_getHandle(int16 handle) const;
int16 getChunk(const char *chunkName);
- char freeChunk(int16 handle);
+ char freeChunk(int16 handle);
int32 readChunk(int16 handle, byte *buf, uint16 size);
int16 seekChunk(int16 handle, int32 pos, int16 from);
+
uint32 getChunkPos(int16 handle) const;
- int32 getChunkSize(const char *chunkName);
+
+ int32 getChunkSize(const char *chunkName, int32 &packSize);
uint32 getPos(int16 handle);
- void seekData(int16 handle, int32 pos, int16 from);
+ void seekData(int16 handle, int32 pos, int16 from);
+
int32 readData(int16 handle, byte *buf, uint16 size);
-friend class DataStream;
+ friend class DataStream;
};
} // End of namespace Gob
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index a1074d7ecb..486b12b022 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -46,6 +46,8 @@ Draw_v2::Draw_v2(GobEngine *vm) : Draw_v1(vm) {
}
void Draw_v2::initScreen() {
+ _vm->_game->_preventScroll = false;
+
_scrollOffsetX = 0;
_scrollOffsetY = 0;
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 4e2bd223b7..af9f03ecbf 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -181,10 +181,12 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_handleMouse = 0;
_forceHandleMouse = 0;
- _menuLevel = 0;
_noScroll = true;
_preventScroll = false;
- _scrollHandleMouse = false;
+
+ _wantScroll = false;
+ _wantScrollX = 0;
+ _wantScrollY = 0;
_tempStr[0] = 0;
@@ -360,9 +362,7 @@ void Game::playTot(int16 skipPlay) {
_vm->_scenery->_pCaptureCounter = oldCaptureCounter;
_script->seek(_script->getFunctionOffset(skipPlay + 1));
- _menuLevel++;
_vm->_inter->callSub(2);
- _menuLevel--;
if (_vm->_inter->_terminate != 0)
_vm->_inter->_terminate = 2;
@@ -439,22 +439,27 @@ void Game::freeSoundSlot(int16 slot) {
_vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot));
}
-void Game::evaluateScroll(int16 x, int16 y) {
- if (_preventScroll || !_scrollHandleMouse || (_menuLevel > 0))
+void Game::wantScroll(int16 x, int16 y) {
+ _wantScroll = true;
+ _wantScrollX = x;
+ _wantScrollY = y;
+}
+
+void Game::evaluateScroll() {
+ if (_noScroll || _preventScroll || !_wantScroll)
return;
- if (_noScroll ||
- ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18)))
+ if ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18))
return;
- if ((x == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
+ if ((_wantScrollX == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
uint16 off;
off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX);
off = MAX(off / 2, 1);
_vm->_draw->_scrollOffsetX -= off;
_vm->_video->dirtyRectsAll();
- } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
+ } else if ((_wantScrollY == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
uint16 off;
off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY);
@@ -463,9 +468,9 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_video->dirtyRectsAll();
}
- int16 cursorRight = x + _vm->_draw->_cursorWidth;
- int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
- int16 cursorBottom = y + _vm->_draw->_cursorHeight;
+ int16 cursorRight = _wantScrollX + _vm->_draw->_cursorWidth;
+ int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
+ int16 cursorBottom = _wantScrollY + _vm->_draw->_cursorHeight;
int16 screenBottom = _vm->_draw->_scrollOffsetY + _vm->_height;
if ((cursorRight >= _vm->_width) &&
@@ -479,7 +484,7 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_draw->_scrollOffsetX += off;
_vm->_video->dirtyRectsAll();
- _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, y);
+ _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, _wantScrollY);
} else if ((cursorBottom >= (_vm->_height - _vm->_video->_splitHeight2)) &&
(screenBottom < _vm->_video->_surfHeight)) {
uint16 off;
@@ -491,11 +496,13 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_draw->_scrollOffsetY += off;
_vm->_video->dirtyRectsAll();
- _vm->_util->setMousePos(x, _vm->_height - _vm->_video->_splitHeight2 -
- _vm->_draw->_cursorHeight);
+ _vm->_util->setMousePos(_wantScrollX,
+ _vm->_height - _vm->_video->_splitHeight2 - _vm->_draw->_cursorHeight);
}
_vm->_util->setScrollOffset();
+
+ _wantScroll = false;
}
int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
diff --git a/engines/gob/game.h b/engines/gob/game.h
index d3a758f014..8b8be90ef4 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -82,7 +82,10 @@ public:
bool _noScroll;
bool _preventScroll;
- bool _scrollHandleMouse;
+
+ bool _wantScroll;
+ int16 _wantScrollX;
+ int16 _wantScrollY;
byte _handleMouse;
char _forceHandleMouse;
@@ -99,7 +102,8 @@ public:
void freeSoundSlot(int16 slot);
- void evaluateScroll(int16 x, int16 y);
+ void wantScroll(int16 x, int16 y);
+ void evaluateScroll();
int16 checkKeys(int16 *pMousex = 0, int16 *pMouseY = 0,
MouseButtons *pButtons = 0, char handleMouse = 0);
@@ -109,8 +113,6 @@ public:
void switchTotSub(int16 index, int16 skipPlay);
protected:
- uint32 _menuLevel;
-
char _tempStr[256];
// Capture
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
index b218634d4e..d21eb906ee 100644
--- a/engines/gob/hotspots.cpp
+++ b/engines/gob/hotspots.cpp
@@ -628,8 +628,6 @@ bool Hotspots::checkHotspotChanged() {
}
uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) {
- _vm->_game->_scrollHandleMouse = handleMouse != 0;
-
if (delay >= -1) {
_currentKey = 0;
_currentId = 0;
@@ -679,6 +677,9 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index
_vm->_video->waitRetrace();
}
+ if (handleMouse)
+ _vm->_game->evaluateScroll();
+
// Update keyboard and mouse state
key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse);
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 19cac86465..b4e5bf7623 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -935,6 +935,8 @@ void Inter_v2::o2_setScrollOffset() {
offsetY = _vm->_game->_script->readValExpr();
if (offsetX == -1) {
+ _vm->_game->_preventScroll = !_vm->_game->_preventScroll;
+
WRITE_VAR(2, _vm->_draw->_scrollOffsetX);
WRITE_VAR(3, _vm->_draw->_scrollOffsetY);
} else {
@@ -996,11 +998,8 @@ void Inter_v2::o2_playImd() {
close = false;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
@@ -1306,8 +1305,14 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
char *file = _vm->_game->_script->getResultStr();
+ // WORKAROUND: In some games (at least all the Playtoons), some files are
+ // read on CD (and only on CD). "@:\" is replaced by the CD drive letter.
+ // As the files are copied on the HDD, those characters are skipped.
+ if (strncmp(file, "@:\\", 3) ==0 )
+ file += 3;
+
// WORKAROUND: For some reason, the variable indicating which TOT to load next
- // is overwritten in the guard house card game in Woodruff
+ // is overwritten in the guard house card game in Woodruff.
if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(file, "6.TOT"))
strcpy(file, "EMAP2011.TOT");
diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp
index 48378a5987..1f6899d85c 100644
--- a/engines/gob/inter_v4.cpp
+++ b/engines/gob/inter_v4.cpp
@@ -233,11 +233,8 @@ void Inter_v4::o4_playVmdOrMusic() {
return;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index aa4721ff0a..4e2ec69cf2 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -164,12 +164,9 @@ void Inter_v6::o6_playVmdOrMusic() {
return;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey,
palCmd, palStart, palEnd, 0, -1, false, -1, true);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index 135c50c92c..bad4723159 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -1105,8 +1105,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
int16 baseFrame, palFrame, lastFrame;
uint16 flags;
- _vm->_game->_preventScroll = true;
-
if (_vm->_draw->_renderFlags & 0x100) {
x = VAR(55);
y = VAR(56);
@@ -1115,7 +1113,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
if (key.imdFile == -1) {
_vm->_vidPlayer->primaryClose();
- _vm->_game->_preventScroll = false;
return;
}
@@ -1131,15 +1128,12 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
if ((palFrame != -1) && (lastFrame != -1))
if ((lastFrame - palFrame) < startFrame)
if (!(key.flags & 0x4000)) {
- _vm->_game->_preventScroll = false;
_vm->_vidPlayer->primaryClose();
return;
}
- if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) {
- _vm->_game->_preventScroll = false;
+ if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags))
return;
- }
if (palFrame == -1)
palFrame = 0;
@@ -1265,9 +1259,6 @@ void Mult_v2::advanceObjects(int16 index) {
}
}
- if (!hasImds && (_vm->_draw->_showCursor == 3))
- _vm->_game->_preventScroll = false;
-
doSoundAnim(stop, frame);
WRITE_VAR(22, frame);
diff --git a/engines/gob/save/saveload_playtoons.cpp b/engines/gob/save/saveload_playtoons.cpp
index 97da909e7c..3014e3f2bf 100644
--- a/engines/gob/save/saveload_playtoons.cpp
+++ b/engines/gob/save/saveload_playtoons.cpp
@@ -47,6 +47,8 @@ SaveLoad_Playtoons::SaveFile SaveLoad_Playtoons::_saveFiles[] = {
{ "titre.007", kSaveModeExists, 0, 0}, // Playtoons CK 2 empty title (???)
{ "titre.008", kSaveModeExists, 0, 0}, // Playtoons CK 3 empty title (???)
{ "mdo.def", kSaveModeExists, 0, 0},
+ { "dan.itk", kSaveModeNone, 0, 0},
+ { "did.inf", kSaveModeSave, 0, 0},
};
SaveLoad::SaveMode SaveLoad_Playtoons::getSaveMode(const char *fileName) const {
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 1a8668b1c2..d51cbad6b3 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -141,7 +141,8 @@ void Util::processInput(bool scroll) {
y -= _vm->_video->_screenDeltaY;
_vm->_util->setMousePos(x, y);
- _vm->_game->evaluateScroll(x, y);
+
+ _vm->_game->wantScroll(x, y);
}
}