From aa7c44a070ac6b33411749b66014f80a953b70c5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 29 May 2012 14:16:31 +0200 Subject: GOB: Hook up the PE cursors to v7 loadCursor Addy Junior / Adibou2 now shows proper cursors. Thanks to clone2727 for the constant nagging. :P --- engines/gob/draw.cpp | 14 ++++++ engines/gob/draw.h | 7 +++ engines/gob/draw_v2.cpp | 39 ++++++++++----- engines/gob/inter.h | 10 +++- engines/gob/inter_v7.cpp | 125 +++++++++++++++++++++++++++++++++++++++++------ engines/gob/surface.cpp | 12 +++++ engines/gob/surface.h | 1 + engines/gob/video.cpp | 5 +- 8 files changed, 182 insertions(+), 31 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 4b659f51de..545c790fb8 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -117,6 +117,13 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _cursorAnimDelays[i] = 0; } + _cursorPalettes = 0; + _cursorKeyColors = 0; + _cursorPaletteStarts = 0; + _cursorPaletteCounts = 0; + _cursorHotspotsX = 0; + _cursorHotspotsY = 0; + _palLoadData1[0] = 0; _palLoadData1[1] = 17; _palLoadData1[2] = 34; @@ -134,6 +141,13 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { } Draw::~Draw() { + delete[] _cursorPalettes; + delete[] _cursorKeyColors; + delete[] _cursorPaletteStarts; + delete[] _cursorPaletteCounts; + delete[] _cursorHotspotsX; + delete[] _cursorHotspotsY; + for (int i = 0; i < kFontCount; i++) delete _fonts[i]; } diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 393822c33a..2d2c7fd0e7 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -145,6 +145,13 @@ public: int8 _cursorAnimHigh[40]; int8 _cursorAnimDelays[40]; + byte *_cursorPalettes; + byte *_cursorKeyColors; + uint16 *_cursorPaletteStarts; + uint16 *_cursorPaletteCounts; + int32 *_cursorHotspotsX; + int32 *_cursorHotspotsY; + int16 _palLoadData1[4]; int16 _palLoadData2[4]; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 78702f2ec9..cf82df9c71 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -83,7 +83,7 @@ void Draw_v2::blitCursor() { void Draw_v2::animateCursor(int16 cursor) { int16 cursorIndex = cursor; int16 newX = 0, newY = 0; - uint16 hotspotX = 0, hotspotY = 0; + uint16 hotspotX, hotspotY; _showCursor |= 1; @@ -133,27 +133,42 @@ void Draw_v2::animateCursor(int16 cursor) { } // '------ - newX = _vm->_global->_inter_mouseX; - newY = _vm->_global->_inter_mouseY; + hotspotX = 0; + hotspotY = 0; + if (_cursorHotspotXVar != -1) { - newX -= hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar); - newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); + hotspotX = (uint16) VAR(_cursorIndex + _cursorHotspotXVar); + hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); } else if (_cursorHotspotX != -1) { - newX -= hotspotX = _cursorHotspotX; - newY -= hotspotY = _cursorHotspotY; + hotspotX = _cursorHotspotX; + hotspotY = _cursorHotspotY; + } else if (_cursorHotspotsX != 0) { + hotspotX = _cursorHotspotsX[_cursorIndex]; + hotspotY = _cursorHotspotsY[_cursorIndex]; } + newX = _vm->_global->_inter_mouseX - hotspotX; + newY = _vm->_global->_inter_mouseY - hotspotY; + _scummvmCursor->clear(); _scummvmCursor->blit(*_cursorSprites, cursorIndex * _cursorWidth, 0, (cursorIndex + 1) * _cursorWidth - 1, _cursorHeight - 1, 0, 0); - if ((_vm->getGameType() != kGameTypeAdibou2) && - (_vm->getGameType() != kGameTypeAdi2) && - (_vm->getGameType() != kGameTypeAdi4)) - CursorMan.replaceCursor(_scummvmCursor->getData(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat()); + uint32 keyColor = 0; + if (_cursorKeyColors) + keyColor = _cursorKeyColors[cursorIndex]; + + CursorMan.replaceCursor(_scummvmCursor->getData(), + _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat()); + + if (_cursorPalettes) { + CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3), + _cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]); + CursorMan.disableCursorPalette(false); + } else + CursorMan.disableCursorPalette(true); if (_frontSurface != _backSurface) { if (!_noInvalidated) { diff --git a/engines/gob/inter.h b/engines/gob/inter.h index c79b6e2260..ded016543e 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -31,6 +31,10 @@ #include "gob/iniconfig.h" #include "gob/databases.h" +namespace Common { + class PEResources; +} + namespace Gob { class Cheater_Geisha; @@ -648,7 +652,7 @@ private: class Inter_v7 : public Inter_Playtoons { public: Inter_v7(GobEngine *vm); - virtual ~Inter_v7() {} + virtual ~Inter_v7(); protected: virtual void setupOpcodesDraw(); @@ -684,7 +688,11 @@ private: INIConfig _inis; Databases _databases; + Common::PEResources *_cursors; + Common::String findFile(const Common::String &mask); + + bool loadCursorFile(); }; } // End of namespace Gob diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp index 81547f7362..71e4ac07ad 100644 --- a/engines/gob/inter_v7.cpp +++ b/engines/gob/inter_v7.cpp @@ -22,8 +22,11 @@ #include "common/endian.h" #include "common/archive.h" +#include "common/winexe.h" +#include "common/winexe_pe.h" #include "graphics/cursorman.h" +#include "graphics/wincursor.h" #include "gob/gob.h" #include "gob/global.h" @@ -42,7 +45,11 @@ namespace Gob { #define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) #define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) -Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm) { +Inter_v7::Inter_v7(GobEngine *vm) : Inter_Playtoons(vm), _cursors(0) { +} + +Inter_v7::~Inter_v7() { + delete _cursors; } void Inter_v7::setupOpcodesDraw() { @@ -88,25 +95,100 @@ void Inter_v7::o7_draw0x0C() { void Inter_v7::o7_loadCursor() { int16 cursorIndex = _vm->_game->_script->readValExpr(); - Common::String cursorFile = _vm->_game->_script->evalString(); + Common::String cursorName = _vm->_game->_script->evalString(); + + // Clear the cursor sprite at that index + _vm->_draw->_cursorSprites->fillRect(cursorIndex * _vm->_draw->_cursorWidth, 0, + cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, + _vm->_draw->_cursorHeight - 1, 0); + + Graphics::WinCursorGroup *cursorGroup = 0; + Graphics::Cursor *defaultCursor = 0; + + // Load the cursor file and cursor group + if (loadCursorFile()) + cursorGroup = Graphics::WinCursorGroup::createCursorGroup(*_cursors, Common::WinResourceID(cursorName)); + + // If the requested cursor does not exist, create a default one + const Graphics::Cursor *cursor = 0; + if (!cursorGroup || cursorGroup->cursors.empty() || !cursorGroup->cursors[0].cursor) { + defaultCursor = Graphics::makeDefaultWinCursor(); - warning("Addy Stub: Load cursor \"%s\" to %d", cursorFile.c_str(), cursorIndex); + cursor = defaultCursor; + } else + cursor = cursorGroup->cursors[0].cursor; - byte cursor[9]; - byte palette[6]; + // Cursor sprite dimensions mismatch, recreate the cursor sprites + if ((cursor->getWidth() > _vm->_draw->_cursorWidth ) || + (cursor->getHeight() > _vm->_draw->_cursorHeight) || + (_vm->_draw->_cursorSprites->getWidth() < ((cursorIndex + 1) * _vm->_draw->_cursorWidth)) || + !_vm->_draw->_cursorPalettes) { - cursor[0] = 0; cursor[1] = 0; cursor[2] = 0; - cursor[3] = 0; cursor[4] = 1; cursor[5] = 0; - cursor[6] = 0; cursor[7] = 0; cursor[8] = 0; + const int count = cursorIndex + 1; - palette[0] = 0; palette[1] = 0; palette[2] = 0; - palette[3] = 255; palette[4] = 255; palette[5] = 255; + _vm->_draw->freeSprite(Draw::kCursorSurface); + _vm->_draw->_cursorSprites.reset(); + _vm->_draw->_cursorSpritesBack.reset(); + _vm->_draw->_scummvmCursor.reset(); - CursorMan.pushCursorPalette(palette, 0, 2); - CursorMan.disableCursorPalette(false); - CursorMan.replaceCursor(cursor, 3, 3, 1, 1, 255); + _vm->_draw->_cursorWidth = MAX(cursor->getWidth() , _vm->_draw->_cursorWidth); + _vm->_draw->_cursorHeight = MAX(cursor->getHeight(), _vm->_draw->_cursorHeight); - CursorMan.showMouse(true); + _vm->_draw->_transparentCursor = 1; + + _vm->_draw->initSpriteSurf(Draw::kCursorSurface, _vm->_draw->_cursorWidth * count, + _vm->_draw->_cursorHeight, 2); + + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; + + _vm->_draw->_scummvmCursor = + _vm->_video->initSurfDesc(_vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); + + for (int i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + _vm->_draw->_cursorAnimLow[1] = 0; + + delete[] _vm->_draw->_cursorPalettes; + delete[] _vm->_draw->_cursorKeyColors; + delete[] _vm->_draw->_cursorPaletteStarts; + delete[] _vm->_draw->_cursorPaletteCounts; + delete[] _vm->_draw->_cursorHotspotsX; + delete[] _vm->_draw->_cursorHotspotsY; + + _vm->_draw->_cursorPalettes = new byte[256 * 3 * count]; + _vm->_draw->_cursorKeyColors = new byte[count]; + _vm->_draw->_cursorPaletteStarts = new uint16[count]; + _vm->_draw->_cursorPaletteCounts = new uint16[count]; + _vm->_draw->_cursorHotspotsX = new int32[count]; + _vm->_draw->_cursorHotspotsY = new int32[count]; + + memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3); + memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte)); + memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32)); + memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32)); + } + + Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface()); + + _vm->_draw->_cursorSprites->blit(cursorSurf, 0, 0, cursor->getWidth() - 1, cursor->getHeight() - 1, + cursorIndex * _vm->_draw->_cursorWidth, 0, 0); + + memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3); + + _vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor(); + _vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex(); + _vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount(); + _vm->_draw->_cursorHotspotsX [cursorIndex] = cursor->getHotspotX(); + _vm->_draw->_cursorHotspotsY [cursorIndex] = cursor->getHotspotY(); + + delete cursorGroup; + delete defaultCursor; } void Inter_v7::o7_displayWarning() { @@ -529,4 +611,19 @@ Common::String Inter_v7::findFile(const Common::String &mask) { return files.front()->getName(); } +bool Inter_v7::loadCursorFile() { + if (_cursors) + return true; + + _cursors = new Common::PEResources(); + + if (_cursors->loadFromEXE("cursor32.dll")) + return true; + + delete _cursors; + _cursors = 0; + + return false; +} + } // End of namespace Gob diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index e294209ed7..3af19f891d 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -280,6 +280,18 @@ Surface::Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem) : _ownVidMem = false; } +Surface::Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem) : + _width(width), _height(height), _bpp(bpp), _vidMem(0) { + + assert((_width > 0) && (_height > 0)); + assert((_bpp == 1) || (_bpp == 2)); + + _vidMem = new byte[_bpp * _width * _height]; + _ownVidMem = true; + + memcpy(_vidMem, vidMem, _bpp * _width * _height); +} + Surface::~Surface() { if (_ownVidMem) delete[] _vidMem; diff --git a/engines/gob/surface.h b/engines/gob/surface.h index 866e63490f..5376603801 100644 --- a/engines/gob/surface.h +++ b/engines/gob/surface.h @@ -122,6 +122,7 @@ private: class Surface { public: Surface(uint16 width, uint16 height, uint8 bpp, byte *vidMem = 0); + Surface(uint16 width, uint16 height, uint8 bpp, const byte *vidMem); ~Surface(); uint16 getWidth () const; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index ee5ff4abff..c865b2b40e 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -226,10 +226,7 @@ void Video::setSize(bool defaultTo1XScaler) { void Video::retrace(bool mouse) { if (mouse) - if ((_vm->getGameType() != kGameTypeAdibou2) && - (_vm->getGameType() != kGameTypeAdi2) && - (_vm->getGameType() != kGameTypeAdi4)) - CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); + CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); if (_vm->_global->_primarySurfDesc) { int screenX = _screenDeltaX; -- cgit v1.2.3 From be25e31a0a2da25c586a16a16ba9d55053f21524 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 29 May 2012 17:12:06 +0200 Subject: GOB: Fix v7 cursors drawn by the scripts When the cursor name is "", then that cursor is drawn by the scripts instead of loaded from cursor32.dll. That cursor does not have its own palette then. Fixes the cursors in the "paint" game in Adibou2. --- engines/gob/draw.cpp | 3 ++ engines/gob/draw.h | 2 + engines/gob/draw_v2.cpp | 4 +- engines/gob/inter.h | 1 + engines/gob/inter_v7.cpp | 133 +++++++++++++++++++++++++++-------------------- 5 files changed, 84 insertions(+), 59 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 545c790fb8..fe59b11f76 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -117,6 +117,8 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _cursorAnimDelays[i] = 0; } + _cursorCount = 0; + _doCursorPalettes = 0; _cursorPalettes = 0; _cursorKeyColors = 0; _cursorPaletteStarts = 0; @@ -142,6 +144,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { Draw::~Draw() { delete[] _cursorPalettes; + delete[] _doCursorPalettes; delete[] _cursorKeyColors; delete[] _cursorPaletteStarts; delete[] _cursorPaletteCounts; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 2d2c7fd0e7..24c5550ea5 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -145,6 +145,8 @@ public: int8 _cursorAnimHigh[40]; int8 _cursorAnimDelays[40]; + int32 _cursorCount; + bool *_doCursorPalettes; byte *_cursorPalettes; byte *_cursorKeyColors; uint16 *_cursorPaletteStarts; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index cf82df9c71..ab9a90de8f 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -157,13 +157,13 @@ void Draw_v2::animateCursor(int16 cursor) { _cursorHeight - 1, 0, 0); uint32 keyColor = 0; - if (_cursorKeyColors) + if (_doCursorPalettes && _cursorKeyColors && _doCursorPalettes[cursorIndex]) keyColor = _cursorKeyColors[cursorIndex]; CursorMan.replaceCursor(_scummvmCursor->getData(), _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat()); - if (_cursorPalettes) { + if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) { CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3), _cursorPaletteStarts[cursorIndex], _cursorPaletteCounts[cursorIndex]); CursorMan.disableCursorPalette(false); diff --git a/engines/gob/inter.h b/engines/gob/inter.h index ded016543e..1e6f74db4e 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -693,6 +693,7 @@ private: Common::String findFile(const Common::String &mask); bool loadCursorFile(); + void resizeCursors(int16 width, int16 height, int16 count, bool transparency); }; } // End of namespace Gob diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp index 71e4ac07ad..6cf69ed9df 100644 --- a/engines/gob/inter_v7.cpp +++ b/engines/gob/inter_v7.cpp @@ -93,6 +93,70 @@ void Inter_v7::o7_draw0x0C() { WRITE_VAR(17, 0); } +void Inter_v7::resizeCursors(int16 width, int16 height, int16 count, bool transparency) { + if (width <= 0) + width = _vm->_draw->_cursorWidth; + if (height <= 0) + height = _vm->_draw->_cursorHeight; + + width = MAX(width , _vm->_draw->_cursorWidth); + height = MAX(height, _vm->_draw->_cursorHeight); + + _vm->_draw->_transparentCursor = transparency; + + // Cursors sprite already big enough + if ((_vm->_draw->_cursorWidth >= width) && (_vm->_draw->_cursorHeight >= height) && + (_vm->_draw->_cursorCount >= count)) + return; + + _vm->_draw->_cursorCount = count; + _vm->_draw->_cursorWidth = width; + _vm->_draw->_cursorHeight = height; + + _vm->_draw->freeSprite(Draw::kCursorSurface); + _vm->_draw->_cursorSprites.reset(); + _vm->_draw->_cursorSpritesBack.reset(); + _vm->_draw->_scummvmCursor.reset(); + + _vm->_draw->initSpriteSurf(Draw::kCursorSurface, width * count, height, 2); + + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; + _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; + + _vm->_draw->_scummvmCursor = _vm->_video->initSurfDesc(width, height, SCUMMVM_CURSOR); + + for (int i = 0; i < 40; i++) { + _vm->_draw->_cursorAnimLow[i] = -1; + _vm->_draw->_cursorAnimDelays[i] = 0; + _vm->_draw->_cursorAnimHigh[i] = 0; + } + _vm->_draw->_cursorAnimLow[1] = 0; + + delete[] _vm->_draw->_doCursorPalettes; + delete[] _vm->_draw->_cursorPalettes; + delete[] _vm->_draw->_cursorKeyColors; + delete[] _vm->_draw->_cursorPaletteStarts; + delete[] _vm->_draw->_cursorPaletteCounts; + delete[] _vm->_draw->_cursorHotspotsX; + delete[] _vm->_draw->_cursorHotspotsY; + + _vm->_draw->_cursorPalettes = new byte[256 * 3 * count]; + _vm->_draw->_doCursorPalettes = new bool[count]; + _vm->_draw->_cursorKeyColors = new byte[count]; + _vm->_draw->_cursorPaletteStarts = new uint16[count]; + _vm->_draw->_cursorPaletteCounts = new uint16[count]; + _vm->_draw->_cursorHotspotsX = new int32[count]; + _vm->_draw->_cursorHotspotsY = new int32[count]; + + memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3); + memset(_vm->_draw->_doCursorPalettes , 0, count * sizeof(bool)); + memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte)); + memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16)); + memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32)); + memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32)); +} + void Inter_v7::o7_loadCursor() { int16 cursorIndex = _vm->_game->_script->readValExpr(); Common::String cursorName = _vm->_game->_script->evalString(); @@ -102,6 +166,14 @@ void Inter_v7::o7_loadCursor() { cursorIndex * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, _vm->_draw->_cursorHeight - 1, 0); + // If the cursor name is empty, that cursor will be drawn by the scripts + if (cursorName.empty()) { + // Make sure the cursors sprite is big enough and set to non-extern palette + resizeCursors(-1, -1, cursorIndex + 1, true); + _vm->_draw->_doCursorPalettes[cursorIndex] = false; + return; + } + Graphics::WinCursorGroup *cursorGroup = 0; Graphics::Cursor *defaultCursor = 0; @@ -118,69 +190,16 @@ void Inter_v7::o7_loadCursor() { } else cursor = cursorGroup->cursors[0].cursor; - // Cursor sprite dimensions mismatch, recreate the cursor sprites - if ((cursor->getWidth() > _vm->_draw->_cursorWidth ) || - (cursor->getHeight() > _vm->_draw->_cursorHeight) || - (_vm->_draw->_cursorSprites->getWidth() < ((cursorIndex + 1) * _vm->_draw->_cursorWidth)) || - !_vm->_draw->_cursorPalettes) { - - const int count = cursorIndex + 1; - - _vm->_draw->freeSprite(Draw::kCursorSurface); - _vm->_draw->_cursorSprites.reset(); - _vm->_draw->_cursorSpritesBack.reset(); - _vm->_draw->_scummvmCursor.reset(); - - _vm->_draw->_cursorWidth = MAX(cursor->getWidth() , _vm->_draw->_cursorWidth); - _vm->_draw->_cursorHeight = MAX(cursor->getHeight(), _vm->_draw->_cursorHeight); - - _vm->_draw->_transparentCursor = 1; - - _vm->_draw->initSpriteSurf(Draw::kCursorSurface, _vm->_draw->_cursorWidth * count, - _vm->_draw->_cursorHeight, 2); - - _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; - _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; - - _vm->_draw->_scummvmCursor = - _vm->_video->initSurfDesc(_vm->_draw->_cursorWidth, _vm->_draw->_cursorHeight, SCUMMVM_CURSOR); - - for (int i = 0; i < 40; i++) { - _vm->_draw->_cursorAnimLow[i] = -1; - _vm->_draw->_cursorAnimDelays[i] = 0; - _vm->_draw->_cursorAnimHigh[i] = 0; - } - _vm->_draw->_cursorAnimLow[1] = 0; - - delete[] _vm->_draw->_cursorPalettes; - delete[] _vm->_draw->_cursorKeyColors; - delete[] _vm->_draw->_cursorPaletteStarts; - delete[] _vm->_draw->_cursorPaletteCounts; - delete[] _vm->_draw->_cursorHotspotsX; - delete[] _vm->_draw->_cursorHotspotsY; - - _vm->_draw->_cursorPalettes = new byte[256 * 3 * count]; - _vm->_draw->_cursorKeyColors = new byte[count]; - _vm->_draw->_cursorPaletteStarts = new uint16[count]; - _vm->_draw->_cursorPaletteCounts = new uint16[count]; - _vm->_draw->_cursorHotspotsX = new int32[count]; - _vm->_draw->_cursorHotspotsY = new int32[count]; - - memset(_vm->_draw->_cursorPalettes , 0, count * 256 * 3); - memset(_vm->_draw->_cursorKeyColors , 0, count * sizeof(byte)); - memset(_vm->_draw->_cursorPaletteStarts, 0, count * sizeof(uint16)); - memset(_vm->_draw->_cursorPaletteCounts, 0, count * sizeof(uint16)); - memset(_vm->_draw->_cursorHotspotsX , 0, count * sizeof(int32)); - memset(_vm->_draw->_cursorHotspotsY , 0, count * sizeof(int32)); - } + // Make sure the cursors sprite it big enough + resizeCursors(cursor->getWidth(), cursor->getHeight(), cursorIndex + 1, true); Surface cursorSurf(cursor->getWidth(), cursor->getHeight(), 1, cursor->getSurface()); - _vm->_draw->_cursorSprites->blit(cursorSurf, 0, 0, cursor->getWidth() - 1, cursor->getHeight() - 1, - cursorIndex * _vm->_draw->_cursorWidth, 0, 0); + _vm->_draw->_cursorSprites->blit(cursorSurf, cursorIndex * _vm->_draw->_cursorWidth, 0); memcpy(_vm->_draw->_cursorPalettes + cursorIndex * 256 * 3, cursor->getPalette(), cursor->getPaletteCount() * 3); + _vm->_draw->_doCursorPalettes [cursorIndex] = true; _vm->_draw->_cursorKeyColors [cursorIndex] = cursor->getKeyColor(); _vm->_draw->_cursorPaletteStarts[cursorIndex] = cursor->getPaletteStartIndex(); _vm->_draw->_cursorPaletteCounts[cursorIndex] = cursor->getPaletteCount(); -- cgit v1.2.3 From 3eeb3d74163f2682bc27968df5e5e389174cdc1e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 2 Jun 2012 20:50:18 +0200 Subject: GOB: Correctly name the Penetration script variables --- engines/gob/inter_geisha.cpp | 10 +++++----- engines/gob/minigames/geisha/penetration.cpp | 2 +- engines/gob/minigames/geisha/penetration.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 7f21ceb91d..99f834d4d7 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -272,12 +272,12 @@ void Inter_Geisha::oGeisha_writeData(OpFuncParams ¶ms) { } void Inter_Geisha::oGeisha_gamePenetration(OpGobParams ¶ms) { - uint16 var1 = _vm->_game->_script->readUint16(); - uint16 var2 = _vm->_game->_script->readUint16(); - uint16 var3 = _vm->_game->_script->readUint16(); - uint16 resultVar = _vm->_game->_script->readUint16(); + uint16 hasAccessPass = _vm->_game->_script->readUint16(); + uint16 hasMaxEnergy = _vm->_game->_script->readUint16(); + uint16 testMode = _vm->_game->_script->readUint16(); + uint16 resultVar = _vm->_game->_script->readUint16(); - bool result = _penetration->play(var1, var2, var3); + bool result = _penetration->play(hasAccessPass, hasMaxEnergy, testMode); WRITE_VAR_UINT32(resultVar, result ? 1 : 0); } diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 121a45bc40..153f2a6766 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -62,7 +62,7 @@ Penetration::~Penetration() { delete _background; } -bool Penetration::play(uint16 var1, uint16 var2, uint16 var3) { +bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { init(); initScreen(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index c346a7bf5a..3f9aac7963 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -39,7 +39,7 @@ public: Penetration(GobEngine *vm); ~Penetration(); - bool play(uint16 var1, uint16 var2, uint16 var3); + bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode); private: GobEngine *_vm; -- cgit v1.2.3 From 585ceb566f27880ae7ea426efc70192b03a26d8d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 2 Jun 2012 22:12:25 +0200 Subject: GOB: Add animation handling frame to Penetration --- engines/gob/minigames/geisha/penetration.cpp | 60 ++++++++++++++++++++++++++-- engines/gob/minigames/geisha/penetration.h | 9 +++++ 2 files changed, 65 insertions(+), 4 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 153f2a6766..1bdc574aa3 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -25,7 +25,9 @@ #include "gob/draw.h" #include "gob/video.h" #include "gob/decfile.h" +#include "gob/cmpfile.h" #include "gob/anifile.h" +#include "gob/aniobject.h" #include "gob/minigames/geisha/penetration.h" @@ -52,7 +54,7 @@ static const byte kPalette[48] = { 0x15, 0x3F, 0x15 }; -Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _objects(0) { +Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0) { _background = new Surface(320, 200, 1); } @@ -68,11 +70,28 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_draw->blitInvalidated(); _vm->_video->retrace(); - while (!_vm->_util->keyPressed() && !_vm->shouldQuit()) - _vm->_util->longDelay(1); + + while (!_vm->shouldQuit()) { + updateAnims(); + + // Draw and wait for the end of the frame + _vm->_draw->blitInvalidated(); + _vm->_util->waitEndFrame(); + + // Handle input + _vm->_util->processInput(); + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + // Aborting the game + if (key == kKeyEscape) + break; + } deinit(); - return true; + return false; } void Penetration::init() { @@ -80,13 +99,18 @@ void Penetration::init() { _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background); + _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200); _objects = new ANIFile(_vm, "tcite.ani", 320); } void Penetration::deinit() { + _anims.clear(); + delete _objects; + delete _sprites; _objects = 0; + _sprites = 0; } void Penetration::initScreen() { @@ -101,6 +125,34 @@ void Penetration::initScreen() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } +int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) { + _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons); + + return _vm->_util->checkKey(); +} + +void Penetration::updateAnims() { + int16 left, top, right, bottom; + + // Clear the previous animation frames + for (Common::List::iterator a = _anims.reverse_begin(); + a != _anims.end(); --a) { + + (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + } + + // Draw the current animation frames + for (Common::List::iterator a = _anims.begin(); + a != _anims.end(); ++a) { + + (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + (*a)->advance(); + } +} + } // End of namespace Geisha } // End of namespace Gob diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 3f9aac7963..9bf87503f0 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -24,11 +24,13 @@ #define GOB_MINIGAMES_GEISHA_PENETRATION_H #include "common/system.h" +#include "common/list.h" namespace Gob { class GobEngine; class Surface; +class CMPFile; class ANIFile; namespace Geisha { @@ -45,13 +47,20 @@ private: GobEngine *_vm; Surface *_background; + CMPFile *_sprites; ANIFile *_objects; + Common::List _anims; + void init(); void deinit(); void initScreen(); + + void updateAnims(); + + int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); }; } // End of namespace Geisha -- cgit v1.2.3 From 030509c8eb4544885dabf67b85f83d3b296230de Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 2 Jun 2012 23:12:25 +0200 Subject: GOB: Draw the shield and health meters in Penetration --- engines/gob/minigames/geisha/meter.cpp | 4 +++ engines/gob/minigames/geisha/meter.h | 2 ++ engines/gob/minigames/geisha/penetration.cpp | 39 +++++++++++++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 8 ++++++ 4 files changed, 52 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp index e3b9bd1ccf..9dcc717e48 100644 --- a/engines/gob/minigames/geisha/meter.cpp +++ b/engines/gob/minigames/geisha/meter.cpp @@ -42,6 +42,10 @@ Meter::~Meter() { delete _surface; } +int32 Meter::getMaxValue() const { + return _maxValue; +} + int32 Meter::getValue() const { return _value; } diff --git a/engines/gob/minigames/geisha/meter.h b/engines/gob/minigames/geisha/meter.h index a9bdb14d0f..d3e82cb32e 100644 --- a/engines/gob/minigames/geisha/meter.h +++ b/engines/gob/minigames/geisha/meter.h @@ -44,6 +44,8 @@ public: Direction direction); ~Meter(); + /** Return the max value the meter is measuring. */ + int32 getMaxValue() const; /** Return the current value the meter is measuring. */ int32 getValue() const; diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 1bdc574aa3..8b5de27ad2 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -30,6 +30,7 @@ #include "gob/aniobject.h" #include "gob/minigames/geisha/penetration.h" +#include "gob/minigames/geisha/meter.h" namespace Gob { @@ -54,17 +55,29 @@ static const byte kPalette[48] = { 0x15, 0x3F, 0x15 }; -Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0) { +Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), + _shieldMeter(0), _healthMeter(0) { + _background = new Surface(320, 200, 1); + + _shieldMeter = new Meter(11, 119, 92, 3, 11, 10, 1020, Meter::kFillToRight); + _healthMeter = new Meter(11, 137, 92, 3, 15, 10, 1020, Meter::kFillToRight); } Penetration::~Penetration() { deinit(); + delete _shieldMeter; + delete _healthMeter; + delete _background; } bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { + _hasAccessPass = hasAccessPass; + _hasMaxEnergy = hasMaxEnergy; + _testMode = testMode; + init(); initScreen(); @@ -101,6 +114,23 @@ void Penetration::init() { _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200); _objects = new ANIFile(_vm, "tcite.ani", 320); + + // Draw the shield meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame + _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield + + // Draw the health meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame + _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart + + // The shield starts down + _shieldMeter->setValue(0); + + // If we don't have the max energy tokens, the health starts at 1/3 strength + if (_hasMaxEnergy) + _healthMeter->setMaxValue(); + else + _healthMeter->setValue(_healthMeter->getMaxValue() / 3); } void Penetration::deinit() { @@ -151,6 +181,13 @@ void Penetration::updateAnims() { (*a)->advance(); } + + // Draw the meters + _shieldMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + _healthMeter->draw(*_vm->_draw->_backSurface, left, top, right, bottom); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } } // End of namespace Geisha diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 9bf87503f0..6c32d28942 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -35,6 +35,8 @@ class ANIFile; namespace Geisha { +class Meter; + /** Geisha's "Penetration" minigame. */ class Penetration { public: @@ -46,12 +48,18 @@ public: private: GobEngine *_vm; + bool _hasAccessPass; + bool _hasMaxEnergy; + bool _testMode; + Surface *_background; CMPFile *_sprites; ANIFile *_objects; Common::List _anims; + Meter *_shieldMeter; + Meter *_healthMeter; void init(); void deinit(); -- cgit v1.2.3 From 43abb525d4004cb0816c8ea506b0b963d784ccf3 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 00:20:39 +0200 Subject: GOB: Draw the map in a separate surface Still hidden for now. --- engines/gob/minigames/geisha/penetration.cpp | 236 +++++++++++++++++++++++++-- engines/gob/minigames/geisha/penetration.h | 15 ++ 2 files changed, 241 insertions(+), 10 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 8b5de27ad2..77edebce48 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -55,18 +55,137 @@ static const byte kPalette[48] = { 0x15, 0x3F, 0x15 }; +static const int kColorShield = 11; +static const int kColorHealth = 15; +static const int kColorBlack = 10; +static const int kColorFloor = 13; + +static const int kMapTileWidth = 24; +static const int kMapTileHeight = 24; + +static const int kPlayAreaX = 120; +static const int kPlayAreaY = 7; +static const int kPlayAreaWidth = 192; +static const int kPlayAreaHeight = 113; + +static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2; +static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2; + +const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = { + { + { // Real mode, floor 0 + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 50, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, + 50, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 0, 50, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 50, 0, 0, 50, 50, 50, 50, 0, 54, 55, 0, 0, 50, 0, 50, + 50, 0, 50, 49, 0, 50, 0, 52, 53, 0, 50, 50, 50, 0, 0, 0, 50, + 50, 57, 0, 50, 0, 0, 0, 50, 50, 50, 0, 0, 56, 50, 54, 55, 50, + 50, 50, 0, 0, 50, 50, 50, 0, 0, 0, 0, 50, 0, 0, 50, 0, 50, + 50, 51, 50, 0, 54, 55, 0, 0, 50, 50, 50, 50, 52, 53, 50, 0, 50, + 50, 0, 50, 0, 0, 0, 0, 0, 54, 55, 0, 0, 0, 50, 0, 0, 50, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 50, + 50, 50, 0, 52, 53, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 50, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0 + }, + { // Real mode, floor 1 + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 50, 51, 52, 53, 0, 0, 52, 53, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 50, 0, 50, 0, 50, 0, 50, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 52, 53, 0, 0, 0, 0, 0, 52, 53, 0, 52, 53, 50, + 50, 57, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 50, 52, 53, 0, 0, 52, 53, 0, 0, 0, 0, 0, 54, 55, 50, + 50, 0, 50, 0, 50, 0, 50, 50, 0, 50, 50, 0, 50, 0, 50, 50, 50, + 50, 0, 50, 49, 0, 0, 52, 53, 0, 52, 53, 0, 0, 0, 50, 56, 50, + 50, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 0, 0, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0 + }, + { // Real mode, floor 2 + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, + 50, 52, 53, 0, 0, 0, 0, 50, 50, 50, 0, 0, 0, 0, 52, 53, 50, + 50, 0, 50, 50, 50, 0, 0, 0, 50, 0, 0, 0, 50, 50, 50, 0, 50, + 50, 0, 50, 52, 53, 50, 50, 52, 53, 0, 50, 50, 54, 55, 50, 0, 50, + 50, 0, 50, 0, 0, 0, 0, 50, 0, 50, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 52, 53, 50, + 0, 50, 0, 50, 50, 50, 0, 57, 50, 51, 0, 50, 50, 50, 0, 50, 0, + 50, 0, 0, 0, 50, 0, 0, 0, 50, 0, 52, 53, 50, 0, 0, 0, 50, + 50, 0, 50, 0, 0, 0, 0, 50, 56, 50, 0, 0, 0, 0, 50, 0, 50, + 50, 0, 50, 54, 55, 50, 50, 0, 0, 0, 50, 50, 54, 55, 50, 0, 50, + 50, 0, 50, 50, 50, 0, 0, 0, 50, 0, 0, 0, 50, 50, 50, 0, 50, + 50, 52, 53, 0, 0, 0, 0, 50, 50, 50, 0, 0, 0, 0, 52, 53, 50, + 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0 + } + }, + { + { // Test mode, floor 0 + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 56, 0, 50, 0, 0, 52, 53, 0, 0, 0, 0, 52, 53, 0, 51, 50, + 50, 0, 0, 50, 0, 0, 0, 50, 0, 54, 55, 50, 0, 50, 50, 50, 50, + 50, 52, 53, 50, 50, 0, 0, 50, 50, 50, 50, 50, 0, 50, 0, 0, 50, + 50, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 50, 49, 50, 0, 0, 50, + 50, 0, 54, 55, 0, 50, 50, 54, 55, 0, 50, 50, 50, 0, 0, 0, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0, 54, 55, 50, + 50, 0, 50, 0, 50, 0, 0, 50, 0, 0, 0, 50, 0, 0, 0, 0, 50, + 50, 0, 50, 0, 50, 54, 55, 50, 0, 50, 50, 50, 0, 50, 0, 0, 50, + 50, 50, 50, 50, 50, 0, 0, 50, 0, 0, 0, 0, 0, 50, 54, 55, 50, + 50, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 0, 0, 0, 50, + 50, 57, 0, 52, 53, 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + }, + { // Test mode, floor 1 + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, + 50, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 54, 55, 0, 50, + 50, 0, 50, 52, 53, 0, 0, 50, 0, 0, 54, 55, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 0, 52, 53, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 50, 50, 50, 50, 49, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 0, 50, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 51, 0, 0, 52, 53, 50, 0, 50, 0, 50, + 50, 57, 50, 0, 50, 0, 50, 50, 50, 50, 50, 50, 50, 0, 50, 0, 50, + 50, 50, 50, 0, 50, 56, 0, 0, 0, 54, 55, 0, 0, 0, 50, 0, 50, + 50, 56, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 50, + 50, 50, 50, 50, 0, 0, 0, 0, 52, 53, 0, 0, 0, 0, 0, 0, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + }, + { // Test mode, floor 2 + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 57, 50, 54, 55, 0, 50, 54, 55, 0, 50, 0, 52, 53, 50, 51, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 52, 53, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, 0, 50, + 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50, + 50, 0, 0, 0, 50, 52, 53, 0, 50, 52, 53, 56, 50, 0, 54, 55, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50 + } + } +}; + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _shieldMeter(0), _healthMeter(0) { _background = new Surface(320, 200, 1); - _shieldMeter = new Meter(11, 119, 92, 3, 11, 10, 1020, Meter::kFillToRight); - _healthMeter = new Meter(11, 137, 92, 3, 15, 10, 1020, Meter::kFillToRight); + _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 1020, Meter::kFillToRight); + _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 1020, Meter::kFillToRight); + + _map = new Surface(kMapWidth * kMapTileWidth + kPlayAreaWidth , + kMapHeight * kMapTileHeight + kPlayAreaHeight, 1); } Penetration::~Penetration() { deinit(); + delete _map; + delete _shieldMeter; delete _healthMeter; @@ -115,14 +234,6 @@ void Penetration::init() { _sprites = new CMPFile(_vm, "tcifplai.cmp", 320, 200); _objects = new ANIFile(_vm, "tcite.ani", 320); - // Draw the shield meter - _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame - _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield - - // Draw the health meter - _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame - _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart - // The shield starts down _shieldMeter->setValue(0); @@ -131,6 +242,10 @@ void Penetration::init() { _healthMeter->setMaxValue(); else _healthMeter->setValue(_healthMeter->getMaxValue() / 3); + + _floor = 0; + + createMap(); } void Penetration::deinit() { @@ -143,6 +258,99 @@ void Penetration::deinit() { _sprites = 0; } +void Penetration::createMap() { + if (_floor >= kFloorCount) + error("Geisha: Invalid floor %d in minigame penetration", _floor); + + // Copy the correct map + memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); + + _map->fill(kColorBlack); + + // Draw the map tiles + for (int y = 0; y < kMapHeight; y++) { + for (int x = 0; x < kMapWidth; x++) { + byte *mapTile = _mapTiles + (y * kMapWidth + x); + + const int posX = kPlayAreaBorderWidth + x * kMapTileWidth; + const int posY = kPlayAreaBorderHeight + y * kMapTileHeight; + + switch (*mapTile) { + case 0: // Floor + _sprites->draw(*_map, 30, posX, posY); + break; + + case 49: // Emergency exit (needs access pass) + + if (_hasAccessPass) { + // Draw an exit. Now works like a regular exit + _sprites->draw(*_map, 29, posX, posY); + *mapTile = 51; + } else + // Draw a wall + _sprites->draw(*_map, 31, posX, posY); + + break; + + case 50: // Wall + _sprites->draw(*_map, 31, posX, posY); + break; + + case 51: // Regular exit + + if (!_testMode) { + // When we're not in test mode, the last exit only works with an access pass + + if (_floor == 2) { + if (!_hasAccessPass) { + // It's now a wall + _sprites->draw(*_map, 31, posX, posY); + *mapTile = 50; + } else + _sprites->draw(*_map, 29, posX, posY); + + } else + _sprites->draw(*_map, 29, posX, posY); + + } else + // Always works in test mode + _sprites->draw(*_map, 29, posX, posY); + + break; + + case 52: // Left side of biting mouth + _sprites->draw(*_map, 32, posX, posY); + break; + + case 53: // Right side of biting mouth + *mapTile = 0; // Works like a floor + break; + + case 54: // Left side of kissing mouth + _sprites->draw(*_map, 33, posX, posY); + break; + + case 55: // Right side of kissing mouth + *mapTile = 0; // Works like a floor + break; + + case 56: // Shield lying on the floor + _sprites->draw(*_map, 30, posX , posY ); // Floor + _sprites->draw(*_map, 25, posX + 4, posY + 8); // Shield + + _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield + _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield + break; + + case 57: // Start position + _sprites->draw(*_map, 30, posX, posY); + *mapTile = 0; + break; + } + } + } +} + void Penetration::initScreen() { _vm->_util->setFrameRate(15); @@ -151,6 +359,14 @@ void Penetration::initScreen() { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + // Draw the shield meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame + _sprites->draw(*_background, 271, 176, 282, 183, 9, 108, 0); // Shield + + // Draw the health meter + _sprites->draw(*_background, 0, 0, 95, 6, 9, 135, 0); // Meter frame + _sprites->draw(*_background, 283, 176, 292, 184, 9, 126, 0); // Heart + _vm->_draw->_backSurface->blit(*_background); _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 6c32d28942..897b10940c 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -46,6 +46,14 @@ public: bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode); private: + static const int kModeCount = 2; + static const int kFloorCount = 3; + + static const int kMapWidth = 17; + static const int kMapHeight = 13; + + static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; + GobEngine *_vm; bool _hasAccessPass; @@ -61,9 +69,16 @@ private: Meter *_shieldMeter; Meter *_healthMeter; + uint8 _floor; + + Surface *_map; + byte _mapTiles[kMapWidth * kMapHeight]; + void init(); void deinit(); + void createMap(); + void initScreen(); void updateAnims(); -- cgit v1.2.3 From 8dcb93f2ce04df49dea38f56bc97aef900a05122 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 01:12:21 +0200 Subject: GOB: Draw the Penetration map and do basic movement --- engines/gob/minigames/geisha/penetration.cpp | 44 +++++++++++++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 10 +++++++ 2 files changed, 53 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 77edebce48..41346a896f 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -170,7 +170,8 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), - _shieldMeter(0), _healthMeter(0) { + _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), + _subTileX(0), _subTileY(0) { _background = new Surface(320, 200, 1); @@ -220,6 +221,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Aborting the game if (key == kKeyEscape) break; + + // Handle the sub movement + handleSub(key); } deinit(); @@ -345,10 +349,18 @@ void Penetration::createMap() { case 57: // Start position _sprites->draw(*_map, 30, posX, posY); *mapTile = 0; + + _subTileX = x; + _subTileY = y; + + _mapX = _subTileX * kMapTileWidth; + _mapY = _subTileY * kMapTileHeight; break; } } } + + _mapUpdate = true; } void Penetration::initScreen() { @@ -377,6 +389,27 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB return _vm->_util->checkKey(); } +void Penetration::handleSub(int16 key) { + if (key == kKeyLeft) + moveSub(-5, 0); + else if (key == kKeyRight) + moveSub( 5, 0); + else if (key == kKeyUp) + moveSub( 0, -5); + else if (key == kKeyDown) + moveSub( 0, 5); +} + +void Penetration::moveSub(int x, int y) { + _mapX = CLIP(_mapX + x, 0, kMapWidth * kMapTileWidth); + _mapY = CLIP(_mapY + y, 0, kMapHeight * kMapTileHeight); + + _subTileX = _mapX / kMapTileWidth; + _subTileY = _mapY / kMapTileHeight; + + _mapUpdate = true; +} + void Penetration::updateAnims() { int16 left, top, right, bottom; @@ -388,6 +421,15 @@ void Penetration::updateAnims() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } + if (_mapUpdate) { + _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, + _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, + kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); + } + + _mapUpdate = false; + // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); a != _anims.end(); ++a) { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 897b10940c..72201d21d8 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -74,6 +74,13 @@ private: Surface *_map; byte _mapTiles[kMapWidth * kMapHeight]; + bool _mapUpdate; + uint16 _mapX; + uint16 _mapY; + + uint8 _subTileX; + uint8 _subTileY; + void init(); void deinit(); @@ -84,6 +91,9 @@ private: void updateAnims(); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + + void handleSub(int16 key); + void moveSub(int x, int y); }; } // End of namespace Geisha -- cgit v1.2.3 From 95e467d82cb36ee0d98624dd2cdd6d79b544c50c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 01:29:09 +0200 Subject: GOB: Display the Penetration submarine --- engines/gob/minigames/geisha/penetration.cpp | 49 ++++++++++++++++++++++++---- engines/gob/minigames/geisha/penetration.h | 4 ++- 2 files changed, 46 insertions(+), 7 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 41346a896f..377835c45f 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -60,6 +60,30 @@ static const int kColorHealth = 15; static const int kColorBlack = 10; static const int kColorFloor = 13; +enum Animation { + kAnimationDriveS = 4, + kAnimationDriveE = 5, + kAnimationDriveN = 6, + kAnimationDriveW = 7, + kAnimationDriveSE = 8, + kAnimationDriveNE = 9, + kAnimationDriveSW = 10, + kAnimationDriveNW = 11, + kAnimationShootS = 12, + kAnimationShootN = 13, + kAnimationShootW = 14, + kAnimationShootE = 15, + kAnimationShootNE = 16, + kAnimationShootSE = 17, + kAnimationShootSW = 18, + kAnimationShootNW = 19, + kAnimationExplodeN = 28, + kAnimationExplodeS = 29, + kAnimationExplodeW = 30, + kAnimationExplodeE = 31, + kAnimationExit = 32 +}; + static const int kMapTileWidth = 24; static const int kMapTileHeight = 24; @@ -169,7 +193,7 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = }; -Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), +Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), _subTileX(0), _subTileY(0) { @@ -250,11 +274,21 @@ void Penetration::init() { _floor = 0; createMap(); + + _sub = new ANIObject(*_objects); + + _sub->setAnimation(kAnimationDriveN); + _sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight); + _sub->setVisible(true); + + _anims.push_back(_sub); } void Penetration::deinit() { _anims.clear(); + delete _sub; + delete _objects; delete _sprites; @@ -391,16 +425,16 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB void Penetration::handleSub(int16 key) { if (key == kKeyLeft) - moveSub(-5, 0); + moveSub(-5, 0, kAnimationDriveW); else if (key == kKeyRight) - moveSub( 5, 0); + moveSub( 5, 0, kAnimationDriveE); else if (key == kKeyUp) - moveSub( 0, -5); + moveSub( 0, -5, kAnimationDriveN); else if (key == kKeyDown) - moveSub( 0, 5); + moveSub( 0, 5, kAnimationDriveS); } -void Penetration::moveSub(int x, int y) { +void Penetration::moveSub(int x, int y, uint16 animation) { _mapX = CLIP(_mapX + x, 0, kMapWidth * kMapTileWidth); _mapY = CLIP(_mapY + y, 0, kMapHeight * kMapTileHeight); @@ -408,6 +442,9 @@ void Penetration::moveSub(int x, int y) { _subTileY = _mapY / kMapTileHeight; _mapUpdate = true; + + if (_sub->getAnimation() != animation) + _sub->setAnimation(animation); } void Penetration::updateAnims() { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 72201d21d8..28a288928b 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -64,6 +64,8 @@ private: CMPFile *_sprites; ANIFile *_objects; + ANIObject *_sub; + Common::List _anims; Meter *_shieldMeter; @@ -93,7 +95,7 @@ private: int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); void handleSub(int16 key); - void moveSub(int x, int y); + void moveSub(int x, int y, uint16 animation); }; } // End of namespace Geisha -- cgit v1.2.3 From a401f0a19e09d7d00a3ee94d928db82e658b7b48 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 3 Jun 2012 02:02:57 +0200 Subject: ALL: Replace cursorTargetScale in OSystem API with a simple "do not scale" logic. All uses of the old target scale API actually wanted to disallow scaling of the mouse cursor. This commit adapts our API to this and thus simplifies backend implementations. Some backends, most notable the Wii and Android, did some implementation of the cursor target scale, which I didn't adapt yet. I added a TODO for the porters there. --- engines/gob/draw_v1.cpp | 2 +- engines/gob/draw_v2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index fb15fdbc19..878c1dc265 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -123,7 +123,7 @@ void Draw_v1::animateCursor(int16 cursor) { (cursorIndex + 1) * _cursorWidth - 1, _cursorHeight - 1, 0, 0); CursorMan.replaceCursor(_scummvmCursor->getData(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, 1, &_vm->getPixelFormat()); + _cursorWidth, _cursorHeight, hotspotX, hotspotY, 0, false, &_vm->getPixelFormat()); if (_frontSurface != _backSurface) { _showCursor = 3; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index ab9a90de8f..d9b7a12639 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -161,7 +161,7 @@ void Draw_v2::animateCursor(int16 cursor) { keyColor = _cursorKeyColors[cursorIndex]; CursorMan.replaceCursor(_scummvmCursor->getData(), - _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, 1, &_vm->getPixelFormat()); + _cursorWidth, _cursorHeight, hotspotX, hotspotY, keyColor, false, &_vm->getPixelFormat()); if (_doCursorPalettes && _doCursorPalettes[cursorIndex]) { CursorMan.replaceCursorPalette(_cursorPalettes + (cursorIndex * 256 * 3), -- cgit v1.2.3 From 627e870629cdab1009d3279453d082a3c44acd03 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 03:29:35 +0200 Subject: GOB: Limit Penetration movement to walkable tiles --- engines/gob/minigames/geisha/penetration.cpp | 36 ++++++++++++++++++++++++---- engines/gob/minigames/geisha/penetration.h | 2 ++ 2 files changed, 34 insertions(+), 4 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 377835c45f..c8fbe31249 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -423,6 +423,15 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB return _vm->_util->checkKey(); } +bool Penetration::isWalkable(byte tile) const { + // Only walls are nonwalkable + + if (tile == 50) + return false; + + return true; +} + void Penetration::handleSub(int16 key) { if (key == kKeyLeft) moveSub(-5, 0, kAnimationDriveW); @@ -435,11 +444,30 @@ void Penetration::handleSub(int16 key) { } void Penetration::moveSub(int x, int y, uint16 animation) { - _mapX = CLIP(_mapX + x, 0, kMapWidth * kMapTileWidth); - _mapY = CLIP(_mapY + y, 0, kMapHeight * kMapTileHeight); + // Limit the movement to walkable tiles + + int16 minX = 0; + if ((_subTileX > 0) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX - 1)])) + minX = _subTileX * kMapTileWidth; + + int16 maxX = kMapWidth * kMapTileWidth; + if ((_subTileX < (kMapWidth - 1)) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX + 1)])) + maxX = _subTileX * kMapTileWidth; + + int16 minY = 0; + if ((_subTileY > 0) && !isWalkable(_mapTiles[(_subTileY - 1) * kMapWidth + _subTileX])) + minY = _subTileY * kMapTileHeight; + + int16 maxY = kMapHeight * kMapTileHeight; + if ((_subTileY < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_subTileY + 1) * kMapWidth + _subTileX])) + maxY = _subTileY * kMapTileHeight; + + _mapX = CLIP(_mapX + x, minX, maxX); + _mapY = CLIP(_mapY + y, minY, maxY); - _subTileX = _mapX / kMapTileWidth; - _subTileY = _mapY / kMapTileHeight; + // The tile the sub is on is where its mid-point is + _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth; + _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight; _mapUpdate = true; diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 28a288928b..9109cb5c68 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -96,6 +96,8 @@ private: void handleSub(int16 key); void moveSub(int x, int y, uint16 animation); + + bool isWalkable(byte tile) const; }; } // End of namespace Geisha -- cgit v1.2.3 From 5a245bd4f2cbac8aee4efe7220533f41d6418312 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 03:40:04 +0200 Subject: GOB: Consume shields in Penetration --- engines/gob/minigames/geisha/penetration.cpp | 27 +++++++++++++++++++++++++++ engines/gob/minigames/geisha/penetration.h | 12 ++++++++++++ 2 files changed, 39 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index c8fbe31249..e4e7798216 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -193,6 +193,10 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = }; +Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), _subTileX(0), _subTileY(0) { @@ -303,6 +307,8 @@ void Penetration::createMap() { // Copy the correct map memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); + _shields.clear(); + _map->fill(kColorBlack); // Draw the map tiles @@ -378,6 +384,8 @@ void Penetration::createMap() { _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield + + _shields.push_back(Position(x, y)); break; case 57: // Start position @@ -473,6 +481,25 @@ void Penetration::moveSub(int x, int y, uint16 animation) { if (_sub->getAnimation() != animation) _sub->setAnimation(animation); + + checkShields(); +} + +void Penetration::checkShields() { + for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { + if ((pos->x == _subTileX) && (pos->y == _subTileY)) { + // Charge shields + _shieldMeter->setMaxValue(); + + // Erase the shield from the map + const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth; + const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight; + _sprites->draw(*_map, 30, mapX, mapY); + + _shields.erase(pos); + break; + } + } } void Penetration::updateAnims() { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 9109cb5c68..4d3455b638 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -54,6 +54,13 @@ private: static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; + struct Position { + uint16 x; + uint16 y; + + Position(uint16 pX, uint16 pY); + }; + GobEngine *_vm; bool _hasAccessPass; @@ -83,6 +90,9 @@ private: uint8 _subTileX; uint8 _subTileY; + Common::List _shields; + + void init(); void deinit(); @@ -98,6 +108,8 @@ private: void moveSub(int x, int y, uint16 animation); bool isWalkable(byte tile) const; + + void checkShields(); }; } // End of namespace Geisha -- cgit v1.2.3 From d124b87649c14e1851228821fcb6d3a523f1e0ae Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 17:15:18 +0200 Subject: GOB: Remove unnecessary include A remnant of when we were still doing dithering color LUT creation at startup --- engines/gob/video.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index c865b2b40e..3b1c6423bb 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -25,7 +25,6 @@ #include "engines/util.h" #include "graphics/cursorman.h" -#include "graphics/fontman.h" #include "graphics/palette.h" #include "graphics/surface.h" -- cgit v1.2.3 From db99d23717ce4f39f9d9f55ce1abf0d8b73cc630 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 3 Jun 2012 18:58:03 +0200 Subject: GOB: Fix invalid reads in Geisha's minigames --- engines/gob/aniobject.cpp | 26 +++++++++++++++++--------- engines/gob/aniobject.h | 8 ++++---- engines/gob/minigames/geisha/diving.cpp | 8 ++++---- engines/gob/minigames/geisha/penetration.cpp | 12 +++++++----- 4 files changed, 32 insertions(+), 22 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index 154f8e04ed..54534cd60b 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -167,19 +167,21 @@ bool ANIObject::isIn(const ANIObject &obj) const { obj.isIn(frameX + frameWidth - 1, frameY + frameHeight - 1); } -void ANIObject::draw(Surface &dest, int16 &left, int16 &top, +bool ANIObject::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_visible) - return; + return false; if (_cmp) - drawCMP(dest, left, top, right, bottom); + return drawCMP(dest, left, top, right, bottom); else if (_ani) - drawANI(dest, left, top, right, bottom); + return drawANI(dest, left, top, right, bottom); + + return false; } -void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, +bool ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_background) { @@ -209,9 +211,11 @@ void ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, top = _backgroundTop; right = _backgroundRight; bottom = _backgroundBottom; + + return true; } -void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, +bool ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_background) { @@ -224,7 +228,7 @@ void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation); if (_frame >= animation.frameCount) - return; + return false; const ANIFile::FrameArea &area = animation.frameAreas[_frame]; @@ -244,13 +248,15 @@ void ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, top = _backgroundTop; right = _backgroundRight; bottom = _backgroundBottom; + + return true; } -void ANIObject::clear(Surface &dest, int16 &left, int16 &top, +bool ANIObject::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { if (!_drawn) - return; + return false; const int16 bgRight = _backgroundRight - _backgroundLeft; const int16 bgBottom = _backgroundBottom - _backgroundTop; @@ -263,6 +269,8 @@ void ANIObject::clear(Surface &dest, int16 &left, int16 &top, top = _backgroundTop; right = _backgroundRight; bottom = _backgroundBottom; + + return true; } void ANIObject::advance() { diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index c101d747b7..bd4cf791a8 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -93,9 +93,9 @@ public: bool lastFrame() const; /** Draw the current frame onto the surface and return the affected rectangle. */ - void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); /** Draw the current frame from the surface and return the affected rectangle. */ - void clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom); + bool clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom); /** Advance the animation to the next frame. */ virtual void advance(); @@ -123,8 +123,8 @@ private: int16 _backgroundRight; ///< The right position of the saved background. int16 _backgroundBottom; ///< The bottom position of the saved background. - void drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); - void drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); }; } // End of namespace Gob diff --git a/engines/gob/minigames/geisha/diving.cpp b/engines/gob/minigames/geisha/diving.cpp index 6f4c6e168a..56c7b5213c 100644 --- a/engines/gob/minigames/geisha/diving.cpp +++ b/engines/gob/minigames/geisha/diving.cpp @@ -706,16 +706,16 @@ void Diving::updateAnims() { for (Common::List::iterator a = _anims.reverse_begin(); a != _anims.end(); --a) { - (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); a != _anims.end(); ++a) { - (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); (*a)->advance(); } diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index e4e7798216..35802e6733 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -298,6 +298,8 @@ void Penetration::deinit() { _objects = 0; _sprites = 0; + + _sub = 0; } void Penetration::createMap() { @@ -503,14 +505,14 @@ void Penetration::checkShields() { } void Penetration::updateAnims() { - int16 left, top, right, bottom; + int16 left = 0, top = 0, right = 0, bottom = 0; // Clear the previous animation frames for (Common::List::iterator a = _anims.reverse_begin(); a != _anims.end(); --a) { - (*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } if (_mapUpdate) { @@ -526,8 +528,8 @@ void Penetration::updateAnims() { for (Common::List::iterator a = _anims.begin(); a != _anims.end(); ++a) { - (*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if ((*a)->draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); (*a)->advance(); } -- cgit v1.2.3 From 25938316a881679a923bce1986f3a978432b0e76 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 5 Jun 2012 16:18:05 +0200 Subject: GOB: Animate mouths in Geisha's Penetration --- engines/gob/aniobject.h | 8 +- engines/gob/minigames/geisha/mouth.cpp | 170 +++++++++++++++++++++++++++ engines/gob/minigames/geisha/mouth.h | 75 ++++++++++++ engines/gob/minigames/geisha/penetration.cpp | 164 ++++++++++++++++++-------- engines/gob/minigames/geisha/penetration.h | 20 +++- engines/gob/module.mk | 1 + 6 files changed, 380 insertions(+), 58 deletions(-) create mode 100644 engines/gob/minigames/geisha/mouth.cpp create mode 100644 engines/gob/minigames/geisha/mouth.h (limited to 'engines/gob') diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index bd4cf791a8..5ea1f75401 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -61,9 +61,9 @@ public: void setMode(Mode mode); /** Set the current position to the animation's default. */ - void setPosition(); + virtual void setPosition(); /** Set the current position. */ - void setPosition(int16 x, int16 y); + virtual void setPosition(int16 x, int16 y); /** Return the current position. */ void getPosition(int16 &x, int16 &y) const; @@ -93,9 +93,9 @@ public: bool lastFrame() const; /** Draw the current frame onto the surface and return the affected rectangle. */ - bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + virtual bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); /** Draw the current frame from the surface and return the affected rectangle. */ - bool clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom); + virtual bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); /** Advance the animation to the next frame. */ virtual void advance(); diff --git a/engines/gob/minigames/geisha/mouth.cpp b/engines/gob/minigames/geisha/mouth.cpp new file mode 100644 index 0000000000..605ffe420f --- /dev/null +++ b/engines/gob/minigames/geisha/mouth.cpp @@ -0,0 +1,170 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/util.h" +#include "common/textconsole.h" + +#include "gob/minigames/geisha/mouth.h" + +namespace Gob { + +namespace Geisha { + +Mouth::Mouth(const ANIFile &ani, const CMPFile &cmp, + uint16 mouthAnim, uint16 mouthSprite, uint16 floorSprite) : ANIObject(ani) { + + _sprite = new ANIObject(cmp); + _sprite->setAnimation(mouthSprite); + _sprite->setVisible(true); + + for (int i = 0; i < kFloorCount; i++) { + _floor[i] = new ANIObject(cmp); + _floor[i]->setAnimation(floorSprite); + _floor[i]->setVisible(true); + } + + _state = kStateDeactivated; + + setAnimation(mouthAnim); + setMode(kModeOnce); + setPause(true); + setVisible(true); +} + +Mouth::~Mouth() { + for (int i = 0; i < kFloorCount; i++) + delete _floor[i]; + + delete _sprite; +} + +void Mouth::advance() { + if (_state != kStateActivated) + return; + + // Animation finished, set state to dead + if (isPaused()) { + _state = kStateDead; + return; + } + + ANIObject::advance(); +} + +void Mouth::activate() { + if (_state != kStateDeactivated) + return; + + _state = kStateActivated; + + setPause(false); +} + +bool Mouth::isDeactivated() const { + return _state == kStateDeactivated; +} + +void Mouth::setPosition(int16 x, int16 y) { + ANIObject::setPosition(x, y); + + int16 floorWidth, floorHeight; + _floor[0]->getFrameSize(floorWidth, floorHeight); + + _sprite->setPosition(x, y); + + for (int i = 0; i < kFloorCount; i++) + _floor[i]->setPosition(x + (i * floorWidth), y); +} + +bool Mouth::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + // If the mouth is deactivated, draw the default mouth sprite + if (_state == kStateDeactivated) + return _sprite->draw(dest, left, top, right, bottom); + + // If the mouth is activated, draw the current mouth animation sprite + if (_state == kStateActivated) + return ANIObject::draw(dest, left, top, right, bottom); + + // If the mouth is dead, draw the floor tiles + if (_state == kStateDead) { + int16 fLeft, fRight, fTop, fBottom; + bool drawn = false; + + left = 0x7FFF; + top = 0x7FFF; + right = 0; + bottom = 0; + + for (int i = 0; i < kFloorCount; i++) { + if (_floor[i]->draw(dest, fLeft, fTop, fRight, fBottom)) { + drawn = true; + left = MIN(left , fLeft); + top = MIN(top , fTop); + right = MAX(right , fRight); + bottom = MAX(bottom, fBottom); + } + } + + return drawn; + } + + return false; +} + +bool Mouth::clear(Surface &dest, int16 &left , int16 &top, int16 &right, int16 &bottom) { + // If the mouth is deactivated, clear the default mouth sprite + if (_state == kStateDeactivated) + return _sprite->clear(dest, left, top, right, bottom); + + // If the mouth is activated, clear the current mouth animation sprite + if (_state == kStateActivated) + return ANIObject::clear(dest, left, top, right, bottom); + + // If the mouth is clear, draw the floor tiles + if (_state == kStateDead) { + int16 fLeft, fRight, fTop, fBottom; + bool cleared = false; + + left = 0x7FFF; + top = 0x7FFF; + right = 0; + bottom = 0; + + for (int i = 0; i < kFloorCount; i++) { + if (_floor[i]->clear(dest, fLeft, fTop, fRight, fBottom)) { + cleared = true; + left = MIN(left , fLeft); + top = MIN(top , fTop); + right = MAX(right , fRight); + bottom = MAX(bottom, fBottom); + } + } + + return cleared; + } + + return false; +} + +} // End of namespace Geisha + +} // End of namespace Gob diff --git a/engines/gob/minigames/geisha/mouth.h b/engines/gob/minigames/geisha/mouth.h new file mode 100644 index 0000000000..2e0cfcd5d0 --- /dev/null +++ b/engines/gob/minigames/geisha/mouth.h @@ -0,0 +1,75 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_MINIGAMES_GEISHA_MOUTH_H +#define GOB_MINIGAMES_GEISHA_MOUTH_H + +#include "gob/aniobject.h" + +namespace Gob { + +namespace Geisha { + +/** A kissing/biting mouth in Geisha's "Penetration" minigame. */ +class Mouth : public ANIObject { +public: + Mouth(const ANIFile &ani, const CMPFile &cmp, + uint16 mouthAnim, uint16 mouthSprite, uint16 floorSprite); + ~Mouth(); + + /** Advance the animation to the next frame. */ + void advance(); + + /** Active the mouth's animation. */ + void activate(); + + /** Is the mouth deactivated? */ + bool isDeactivated() const; + + /** Set the current position. */ + void setPosition(int16 x, int16 y); + + /** Draw the current frame onto the surface and return the affected rectangle. */ + bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + /** Draw the current frame from the surface and return the affected rectangle. */ + bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + +private: + static const int kFloorCount = 2; + + enum State { + kStateDeactivated, + kStateActivated, + kStateDead + }; + + ANIObject *_sprite; + ANIObject *_floor[kFloorCount]; + + State _state; +}; + +} // End of namespace Geisha + +} // End of namespace Gob + +#endif // GOB_MINIGAMES_GEISHA_MOUTH_H diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 35802e6733..c8f96f825a 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -31,6 +31,7 @@ #include "gob/minigames/geisha/penetration.h" #include "gob/minigames/geisha/meter.h" +#include "gob/minigames/geisha/mouth.h" namespace Gob { @@ -60,28 +61,39 @@ static const int kColorHealth = 15; static const int kColorBlack = 10; static const int kColorFloor = 13; +enum Sprite { + kSpriteFloorShield = 25, + kSpriteExit = 29, + kSpriteFloor = 30, + kSpriteWall = 31, + kSpriteMouthBite = 32, + kSpriteMouthKiss = 33 +}; + enum Animation { - kAnimationDriveS = 4, - kAnimationDriveE = 5, - kAnimationDriveN = 6, - kAnimationDriveW = 7, - kAnimationDriveSE = 8, - kAnimationDriveNE = 9, - kAnimationDriveSW = 10, - kAnimationDriveNW = 11, - kAnimationShootS = 12, - kAnimationShootN = 13, - kAnimationShootW = 14, - kAnimationShootE = 15, - kAnimationShootNE = 16, - kAnimationShootSE = 17, - kAnimationShootSW = 18, - kAnimationShootNW = 19, - kAnimationExplodeN = 28, - kAnimationExplodeS = 29, - kAnimationExplodeW = 30, - kAnimationExplodeE = 31, - kAnimationExit = 32 + kAnimationDriveS = 4, + kAnimationDriveE = 5, + kAnimationDriveN = 6, + kAnimationDriveW = 7, + kAnimationDriveSE = 8, + kAnimationDriveNE = 9, + kAnimationDriveSW = 10, + kAnimationDriveNW = 11, + kAnimationShootS = 12, + kAnimationShootN = 13, + kAnimationShootW = 14, + kAnimationShootE = 15, + kAnimationShootNE = 16, + kAnimationShootSE = 17, + kAnimationShootSW = 18, + kAnimationShootNW = 19, + kAnimationExplodeN = 28, + kAnimationExplodeS = 29, + kAnimationExplodeW = 30, + kAnimationExplodeE = 31, + kAnimationExit = 32, + kAnimationMouthKiss = 33, + kAnimationMouthBite = 34 }; static const int kMapTileWidth = 24; @@ -197,8 +209,17 @@ Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { } +Penetration::ManagedMouth::ManagedMouth(uint16 pX, uint16 pY, MouthType t) : + Position(pX, pY), mouth(0), type(t) { +} + +Penetration::ManagedMouth::~ManagedMouth() { + delete mouth; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), - _shieldMeter(0), _healthMeter(0), _floor(0), _mapUpdate(false), _mapX(0), _mapY(0), + _shieldMeter(0), _healthMeter(0), _floor(0), _mapX(0), _mapY(0), _subTileX(0), _subTileY(0) { _background = new Surface(320, 200, 1); @@ -279,6 +300,9 @@ void Penetration::init() { createMap(); + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) + _mapAnims.push_back(m->mouth); + _sub = new ANIObject(*_objects); _sub->setAnimation(kAnimationDriveN); @@ -289,8 +313,13 @@ void Penetration::init() { } void Penetration::deinit() { + _mapAnims.clear(); _anims.clear(); + _shields.clear(); + + _mouths.clear(); + delete _sub; delete _objects; @@ -311,6 +340,8 @@ void Penetration::createMap() { _shields.clear(); + _mouths.clear(); + _map->fill(kColorBlack); // Draw the map tiles @@ -323,23 +354,21 @@ void Penetration::createMap() { switch (*mapTile) { case 0: // Floor - _sprites->draw(*_map, 30, posX, posY); + _sprites->draw(*_map, kSpriteFloor, posX, posY); break; case 49: // Emergency exit (needs access pass) if (_hasAccessPass) { - // Draw an exit. Now works like a regular exit - _sprites->draw(*_map, 29, posX, posY); - *mapTile = 51; + _sprites->draw(*_map, kSpriteExit, posX, posY); + *mapTile = 51; // Now works like a normal exit } else - // Draw a wall - _sprites->draw(*_map, 31, posX, posY); + _sprites->draw(*_map, kSpriteWall, posX, posY); break; case 50: // Wall - _sprites->draw(*_map, 31, posX, posY); + _sprites->draw(*_map, kSpriteWall, posX, posY); break; case 51: // Regular exit @@ -349,23 +378,27 @@ void Penetration::createMap() { if (_floor == 2) { if (!_hasAccessPass) { - // It's now a wall - _sprites->draw(*_map, 31, posX, posY); - *mapTile = 50; + _sprites->draw(*_map, kSpriteWall, posX, posY); + *mapTile = 50; // It's now a wall } else - _sprites->draw(*_map, 29, posX, posY); + _sprites->draw(*_map, kSpriteExit, posX, posY); } else - _sprites->draw(*_map, 29, posX, posY); + _sprites->draw(*_map, kSpriteExit, posX, posY); } else // Always works in test mode - _sprites->draw(*_map, 29, posX, posY); + _sprites->draw(*_map, kSpriteExit, posX, posY); break; case 52: // Left side of biting mouth - _sprites->draw(*_map, 32, posX, posY); + _mouths.push_back(ManagedMouth(x, y, kMouthTypeBite)); + + _mouths.back().mouth = + new Mouth(*_objects, *_sprites, kAnimationMouthBite, kSpriteMouthBite, kSpriteFloor); + + _mouths.back().mouth->setPosition(posX, posY); break; case 53: // Right side of biting mouth @@ -373,7 +406,12 @@ void Penetration::createMap() { break; case 54: // Left side of kissing mouth - _sprites->draw(*_map, 33, posX, posY); + _mouths.push_back(ManagedMouth(x, y, kMouthTypeKiss)); + + _mouths.back().mouth = + new Mouth(*_objects, *_sprites, kAnimationMouthKiss, kSpriteMouthKiss, kSpriteFloor); + + _mouths.back().mouth->setPosition(posX, posY); break; case 55: // Right side of kissing mouth @@ -381,8 +419,8 @@ void Penetration::createMap() { break; case 56: // Shield lying on the floor - _sprites->draw(*_map, 30, posX , posY ); // Floor - _sprites->draw(*_map, 25, posX + 4, posY + 8); // Shield + _sprites->draw(*_map, kSpriteFloor , posX , posY ); // Floor + _sprites->draw(*_map, kSpriteFloorShield, posX + 4, posY + 8); // Shield _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield @@ -391,7 +429,7 @@ void Penetration::createMap() { break; case 57: // Start position - _sprites->draw(*_map, 30, posX, posY); + _sprites->draw(*_map, kSpriteFloor, posX, posY); *mapTile = 0; _subTileX = x; @@ -403,8 +441,6 @@ void Penetration::createMap() { } } } - - _mapUpdate = true; } void Penetration::initScreen() { @@ -479,12 +515,11 @@ void Penetration::moveSub(int x, int y, uint16 animation) { _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth; _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight; - _mapUpdate = true; - if (_sub->getAnimation() != animation) _sub->setAnimation(animation); checkShields(); + checkMouths(); } void Penetration::checkShields() { @@ -504,9 +539,37 @@ void Penetration::checkShields() { } } +void Penetration::checkMouths() { + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); ++m) { + if (!m->mouth->isDeactivated()) + continue; + + if ((( m->x == _subTileX) && (m->y == _subTileY)) || + (((m->x + 1) == _subTileX) && (m->y == _subTileY))) { + + m->mouth->activate(); + } + } +} + void Penetration::updateAnims() { int16 left = 0, top = 0, right = 0, bottom = 0; + // Clear the previous map animation frames + for (Common::List::iterator a = _mapAnims.reverse_begin(); + a != _mapAnims.end(); --a) { + + (*a)->clear(*_map, left, top, right, bottom); + } + + // Draw the current map animation frames + for (Common::List::iterator a = _mapAnims.begin(); + a != _mapAnims.end(); ++a) { + + (*a)->draw(*_map, left, top, right, bottom); + (*a)->advance(); + } + // Clear the previous animation frames for (Common::List::iterator a = _anims.reverse_begin(); a != _anims.end(); --a) { @@ -515,14 +578,11 @@ void Penetration::updateAnims() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } - if (_mapUpdate) { - _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, - _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, - kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); - } - - _mapUpdate = false; + // Draw the map + _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, + _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, + kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 4d3455b638..ef0e3b10f0 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -36,6 +36,7 @@ class ANIFile; namespace Geisha { class Meter; +class Mouth; /** Geisha's "Penetration" minigame. */ class Penetration { @@ -61,6 +62,19 @@ private: Position(uint16 pX, uint16 pY); }; + enum MouthType { + kMouthTypeBite, + kMouthTypeKiss + }; + + struct ManagedMouth : public Position { + Mouth *mouth; + MouthType type; + + ManagedMouth(uint16 pX, uint16 pY, MouthType t); + ~ManagedMouth(); + }; + GobEngine *_vm; bool _hasAccessPass; @@ -74,6 +88,7 @@ private: ANIObject *_sub; Common::List _anims; + Common::List _mapAnims; Meter *_shieldMeter; Meter *_healthMeter; @@ -83,14 +98,14 @@ private: Surface *_map; byte _mapTiles[kMapWidth * kMapHeight]; - bool _mapUpdate; uint16 _mapX; uint16 _mapY; uint8 _subTileX; uint8 _subTileY; - Common::List _shields; + Common::List _shields; + Common::List _mouths; void init(); @@ -110,6 +125,7 @@ private: bool isWalkable(byte tile) const; void checkShields(); + void checkMouths(); }; } // End of namespace Geisha diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 9da5a82de2..c5ae947a1c 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -80,6 +80,7 @@ MODULE_OBJS := \ minigames/geisha/oko.o \ minigames/geisha/meter.o \ minigames/geisha/diving.o \ + minigames/geisha/mouth.o \ minigames/geisha/penetration.o \ save/savefile.o \ save/savehandler.o \ -- cgit v1.2.3 From 73776406686709bc79ff9c6423937dce0e43c5d6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 5 Jun 2012 16:21:36 +0200 Subject: GOB: Play sounds for mouths and shields in Penetration --- engines/gob/minigames/geisha/penetration.cpp | 20 ++++++++++++++++++++ engines/gob/minigames/geisha/penetration.h | 6 ++++++ 2 files changed, 26 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index c8f96f825a..1321842d07 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -29,6 +29,8 @@ #include "gob/anifile.h" #include "gob/aniobject.h" +#include "gob/sound/sound.h" + #include "gob/minigames/geisha/penetration.h" #include "gob/minigames/geisha/meter.h" #include "gob/minigames/geisha/mouth.h" @@ -280,6 +282,11 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { } void Penetration::init() { + // Load sounds + _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); + _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); + _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); + _background->clear(); _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background); @@ -313,6 +320,10 @@ void Penetration::init() { } void Penetration::deinit() { + _soundShield.free(); + _soundBite.free(); + _soundKiss.free(); + _mapAnims.clear(); _anims.clear(); @@ -528,6 +539,9 @@ void Penetration::checkShields() { // Charge shields _shieldMeter->setMaxValue(); + // Play the shield sound + _vm->_sound->blasterPlay(&_soundShield, 1, 0); + // Erase the shield from the map const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth; const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight; @@ -548,6 +562,12 @@ void Penetration::checkMouths() { (((m->x + 1) == _subTileX) && (m->y == _subTileY))) { m->mouth->activate(); + + // Play the mouth sound + if (m->type == kMouthTypeBite) + _vm->_sound->blasterPlay(&_soundBite, 1, 0); + else if (m->type == kMouthTypeKiss) + _vm->_sound->blasterPlay(&_soundKiss, 1, 0); } } } diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index ef0e3b10f0..00ddb4bdba 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -26,6 +26,8 @@ #include "common/system.h" #include "common/list.h" +#include "gob/sound/sounddesc.h" + namespace Gob { class GobEngine; @@ -107,6 +109,10 @@ private: Common::List _shields; Common::List _mouths; + SoundDesc _soundShield; + SoundDesc _soundBite; + SoundDesc _soundKiss; + void init(); void deinit(); -- cgit v1.2.3 From 4392e4d7aab9114ff66a1fcda34d21f404b4ebcd Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 5 Jun 2012 17:01:40 +0200 Subject: GOB: Implement health gain/loss for mouths --- engines/gob/minigames/geisha/meter.cpp | 22 ++++++++++++++++++---- engines/gob/minigames/geisha/meter.h | 8 ++++---- engines/gob/minigames/geisha/penetration.cpp | 24 +++++++++++++++++++----- engines/gob/minigames/geisha/penetration.h | 3 +++ 4 files changed, 44 insertions(+), 13 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp index 9dcc717e48..719ecf3d18 100644 --- a/engines/gob/minigames/geisha/meter.cpp +++ b/engines/gob/minigames/geisha/meter.cpp @@ -63,22 +63,36 @@ void Meter::setMaxValue() { setValue(_maxValue); } -void Meter::increase(int32 n) { +int32 Meter::increase(int32 n) { + if (n < 0) + return decrease(-n); + + int32 overflow = MAX(0, (_value + n) - _maxValue); + int32 value = CLIP(_value + n, 0, _maxValue); if (_value == value) - return; + return overflow; _value = value; _needUpdate = true; + + return overflow; } -void Meter::decrease(int32 n) { +int32 Meter::decrease(int32 n) { + if (n < 0) + return increase(-n); + + int32 underflow = -MIN(0, _value - n); + int32 value = CLIP(_value - n, 0, _maxValue); if (_value == value) - return; + return underflow; _value = value; _needUpdate = true; + + return underflow; } void Meter::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { diff --git a/engines/gob/minigames/geisha/meter.h b/engines/gob/minigames/geisha/meter.h index d3e82cb32e..30dc826de0 100644 --- a/engines/gob/minigames/geisha/meter.h +++ b/engines/gob/minigames/geisha/meter.h @@ -55,10 +55,10 @@ public: /** Set the current value the meter is measuring to the max value. */ void setMaxValue(); - /** Increase the current value the meter is measuring. */ - void increase(int32 n = 1); - /** Decrease the current value the meter is measuring. */ - void decrease(int32 n = 1); + /** Increase the current value the meter is measuring, returning the overflow. */ + int32 increase(int32 n = 1); + /** Decrease the current value the meter is measuring, returning the underflow. */ + int32 decrease(int32 n = 1); /** Draw the meter onto the surface and return the affected rectangle. */ void draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 1321842d07..a188995372 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -226,8 +226,8 @@ Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _background = new Surface(320, 200, 1); - _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 1020, Meter::kFillToRight); - _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 1020, Meter::kFillToRight); + _shieldMeter = new Meter(11, 119, 92, 3, kColorShield, kColorBlack, 920, Meter::kFillToRight); + _healthMeter = new Meter(11, 137, 92, 3, kColorHealth, kColorBlack, 920, Meter::kFillToRight); _map = new Surface(kMapWidth * kMapTileWidth + kPlayAreaWidth , kMapHeight * kMapTileHeight + kPlayAreaHeight, 1); @@ -563,15 +563,29 @@ void Penetration::checkMouths() { m->mouth->activate(); - // Play the mouth sound - if (m->type == kMouthTypeBite) + // Play the mouth sound and do health gain/loss + if (m->type == kMouthTypeBite) { _vm->_sound->blasterPlay(&_soundBite, 1, 0); - else if (m->type == kMouthTypeKiss) + healthLose(230); + } else if (m->type == kMouthTypeKiss) { _vm->_sound->blasterPlay(&_soundKiss, 1, 0); + healthGain(120); + } } } } +void Penetration::healthGain(int amount) { + if (_shieldMeter->getValue() > 0) + _healthMeter->increase(_shieldMeter->increase(amount)); + else + _healthMeter->increase(amount); +} + +void Penetration::healthLose(int amount) { + _healthMeter->decrease(_shieldMeter->decrease(amount)); +} + void Penetration::updateAnims() { int16 left = 0, top = 0, right = 0, bottom = 0; diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 00ddb4bdba..488396ea32 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -132,6 +132,9 @@ private: void checkShields(); void checkMouths(); + + void healthGain(int amount); + void healthLose(int amount); }; } // End of namespace Geisha -- cgit v1.2.3 From 93dda1b227fa11d1da2d923ca63a580343f6ba4e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 01:47:43 +0200 Subject: GOB: const correctness --- engines/gob/minigames/geisha/evilfish.cpp | 2 +- engines/gob/minigames/geisha/evilfish.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/evilfish.cpp b/engines/gob/minigames/geisha/evilfish.cpp index c7ef9d5622..05ae9d0ad4 100644 --- a/engines/gob/minigames/geisha/evilfish.cpp +++ b/engines/gob/minigames/geisha/evilfish.cpp @@ -171,7 +171,7 @@ void EvilFish::mutate(uint16 animSwimLeft, uint16 animSwimRight, } } -bool EvilFish::isDead() { +bool EvilFish::isDead() const { return !isVisible() || (_state == kStateNone) || (_state == kStateDie); } diff --git a/engines/gob/minigames/geisha/evilfish.h b/engines/gob/minigames/geisha/evilfish.h index 81efb676e2..4c82629461 100644 --- a/engines/gob/minigames/geisha/evilfish.h +++ b/engines/gob/minigames/geisha/evilfish.h @@ -58,7 +58,7 @@ public: uint16 animTurnLeft, uint16 animTurnRight, uint16 animDie); /** Is the fish dead? */ - bool isDead(); + bool isDead() const; private: enum State { -- cgit v1.2.3 From b83ac21f6008287414d59ad7f9c88b63bd93bac5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 02:52:19 +0200 Subject: GOB: Implement Penetration submarine shooting and dying Shots don't result in bullets yet, though --- engines/gob/minigames/geisha/mouth.cpp | 1 - engines/gob/minigames/geisha/penetration.cpp | 149 +++++++++-------- engines/gob/minigames/geisha/penetration.h | 29 +++- engines/gob/minigames/geisha/submarine.cpp | 233 +++++++++++++++++++++++++++ engines/gob/minigames/geisha/submarine.h | 96 +++++++++++ engines/gob/module.mk | 1 + 6 files changed, 435 insertions(+), 74 deletions(-) create mode 100644 engines/gob/minigames/geisha/submarine.cpp create mode 100644 engines/gob/minigames/geisha/submarine.h (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/mouth.cpp b/engines/gob/minigames/geisha/mouth.cpp index 605ffe420f..7ba9f86f8c 100644 --- a/engines/gob/minigames/geisha/mouth.cpp +++ b/engines/gob/minigames/geisha/mouth.cpp @@ -21,7 +21,6 @@ */ #include "common/util.h" -#include "common/textconsole.h" #include "gob/minigames/geisha/mouth.h" diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index a188995372..2c1a4918b9 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -73,27 +73,6 @@ enum Sprite { }; enum Animation { - kAnimationDriveS = 4, - kAnimationDriveE = 5, - kAnimationDriveN = 6, - kAnimationDriveW = 7, - kAnimationDriveSE = 8, - kAnimationDriveNE = 9, - kAnimationDriveSW = 10, - kAnimationDriveNW = 11, - kAnimationShootS = 12, - kAnimationShootN = 13, - kAnimationShootW = 14, - kAnimationShootE = 15, - kAnimationShootNE = 16, - kAnimationShootSE = 17, - kAnimationShootSW = 18, - kAnimationShootNW = 19, - kAnimationExplodeN = 28, - kAnimationExplodeS = 29, - kAnimationExplodeW = 30, - kAnimationExplodeE = 31, - kAnimationExit = 32, kAnimationMouthKiss = 33, kAnimationMouthBite = 34 }; @@ -220,9 +199,18 @@ Penetration::ManagedMouth::~ManagedMouth() { } +Penetration::ManagedSub::ManagedSub(uint16 pX, uint16 pY) : Position(pX, pY), sub(0) { + mapX = x * kMapTileWidth; + mapY = y * kMapTileHeight; +} + +Penetration::ManagedSub::~ManagedSub() { + delete sub; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), - _shieldMeter(0), _healthMeter(0), _floor(0), _mapX(0), _mapY(0), - _subTileX(0), _subTileY(0) { + _shieldMeter(0), _healthMeter(0), _floor(0) { _background = new Surface(320, 200, 1); @@ -255,7 +243,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_draw->blitInvalidated(); _vm->_video->retrace(); - while (!_vm->shouldQuit()) { + while (!_vm->shouldQuit() && !isDead() && !hasWon()) { updateAnims(); // Draw and wait for the end of the frame @@ -278,7 +266,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { } deinit(); - return false; + + return hasWon(); } void Penetration::init() { @@ -286,6 +275,7 @@ void Penetration::init() { _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); + _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); _background->clear(); @@ -310,19 +300,14 @@ void Penetration::init() { for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) _mapAnims.push_back(m->mouth); - _sub = new ANIObject(*_objects); - - _sub->setAnimation(kAnimationDriveN); - _sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight); - _sub->setVisible(true); - - _anims.push_back(_sub); + _anims.push_back(_sub->sub); } void Penetration::deinit() { _soundShield.free(); _soundBite.free(); _soundKiss.free(); + _soundShoot.free(); _mapAnims.clear(); _anims.clear(); @@ -349,8 +334,10 @@ void Penetration::createMap() { // Copy the correct map memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); - _shields.clear(); + delete _sub; + _sub = 0; + _shields.clear(); _mouths.clear(); _map->fill(kColorBlack); @@ -441,17 +428,22 @@ void Penetration::createMap() { case 57: // Start position _sprites->draw(*_map, kSpriteFloor, posX, posY); + *mapTile = 0; - _subTileX = x; - _subTileY = y; + delete _sub; + + _sub = new ManagedSub(x, y); - _mapX = _subTileX * kMapTileWidth; - _mapY = _subTileY * kMapTileHeight; + _sub->sub = new Submarine(*_objects); + _sub->sub->setPosition(kPlayAreaX + kPlayAreaBorderWidth, kPlayAreaY + kPlayAreaBorderHeight); break; } } } + + if (!_sub) + error("Geisha: No starting position in floor %d (testmode: %d", _floor, _testMode); } void Penetration::initScreen() { @@ -491,51 +483,64 @@ bool Penetration::isWalkable(byte tile) const { void Penetration::handleSub(int16 key) { if (key == kKeyLeft) - moveSub(-5, 0, kAnimationDriveW); + subMove(-5, 0, Submarine::kDirectionW); else if (key == kKeyRight) - moveSub( 5, 0, kAnimationDriveE); + subMove( 5, 0, Submarine::kDirectionE); else if (key == kKeyUp) - moveSub( 0, -5, kAnimationDriveN); + subMove( 0, -5, Submarine::kDirectionN); else if (key == kKeyDown) - moveSub( 0, 5, kAnimationDriveS); + subMove( 0, 5, Submarine::kDirectionS); + else if (key == kKeySpace) + subShoot(); } -void Penetration::moveSub(int x, int y, uint16 animation) { +void Penetration::subMove(int x, int y, Submarine::Direction direction) { + if (!_sub->sub->canMove()) + return; + // Limit the movement to walkable tiles int16 minX = 0; - if ((_subTileX > 0) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX - 1)])) - minX = _subTileX * kMapTileWidth; + if ((_sub->x > 0) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x - 1)])) + minX = _sub->x * kMapTileWidth; int16 maxX = kMapWidth * kMapTileWidth; - if ((_subTileX < (kMapWidth - 1)) && !isWalkable(_mapTiles[_subTileY * kMapWidth + (_subTileX + 1)])) - maxX = _subTileX * kMapTileWidth; + if ((_sub->x < (kMapWidth - 1)) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x + 1)])) + maxX = _sub->x * kMapTileWidth; int16 minY = 0; - if ((_subTileY > 0) && !isWalkable(_mapTiles[(_subTileY - 1) * kMapWidth + _subTileX])) - minY = _subTileY * kMapTileHeight; + if ((_sub->y > 0) && !isWalkable(_mapTiles[(_sub->y - 1) * kMapWidth + _sub->x])) + minY = _sub->y * kMapTileHeight; int16 maxY = kMapHeight * kMapTileHeight; - if ((_subTileY < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_subTileY + 1) * kMapWidth + _subTileX])) - maxY = _subTileY * kMapTileHeight; + if ((_sub->y < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_sub->y + 1) * kMapWidth + _sub->x])) + maxY = _sub->y * kMapTileHeight; - _mapX = CLIP(_mapX + x, minX, maxX); - _mapY = CLIP(_mapY + y, minY, maxY); + _sub->mapX = CLIP(_sub->mapX + x, minX, maxX); + _sub->mapY = CLIP(_sub->mapY + y, minY, maxY); // The tile the sub is on is where its mid-point is - _subTileX = (_mapX + (kMapTileWidth / 2)) / kMapTileWidth; - _subTileY = (_mapY + (kMapTileHeight / 2)) / kMapTileHeight; + _sub->x = (_sub->mapX + (kMapTileWidth / 2)) / kMapTileWidth; + _sub->y = (_sub->mapY + (kMapTileHeight / 2)) / kMapTileHeight; - if (_sub->getAnimation() != animation) - _sub->setAnimation(animation); + _sub->sub->turn(direction); checkShields(); checkMouths(); } +void Penetration::subShoot() { + if (!_sub->sub->canMove()) + return; + + _sub->sub->shoot(); + + _vm->_sound->blasterPlay(&_soundShoot, 1, 0); +} + void Penetration::checkShields() { for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { - if ((pos->x == _subTileX) && (pos->y == _subTileY)) { + if ((pos->x == _sub->x) && (pos->y == _sub->y)) { // Charge shields _shieldMeter->setMaxValue(); @@ -558,13 +563,13 @@ void Penetration::checkMouths() { if (!m->mouth->isDeactivated()) continue; - if ((( m->x == _subTileX) && (m->y == _subTileY)) || - (((m->x + 1) == _subTileX) && (m->y == _subTileY))) { + if ((( m->x == _sub->x) && (m->y == _sub->y)) || + (((m->x + 1) == _sub->x) && (m->y == _sub->y))) { m->mouth->activate(); // Play the mouth sound and do health gain/loss - if (m->type == kMouthTypeBite) { + if (m->type == kMouthTypeBite) { _vm->_sound->blasterPlay(&_soundBite, 1, 0); healthLose(230); } else if (m->type == kMouthTypeKiss) { @@ -584,6 +589,17 @@ void Penetration::healthGain(int amount) { void Penetration::healthLose(int amount) { _healthMeter->decrease(_shieldMeter->decrease(amount)); + + if (_healthMeter->getValue() == 0) + _sub->sub->die(); +} + +bool Penetration::isDead() const { + return _sub && _sub->sub->isDead(); +} + +bool Penetration::hasWon() const { + return _floor > kFloorCount; } void Penetration::updateAnims() { @@ -612,11 +628,14 @@ void Penetration::updateAnims() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } - // Draw the map - _vm->_draw->_backSurface->blit(*_map, _mapX, _mapY, - _mapX + kPlayAreaWidth - 1, _mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, - kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); + if (_sub) { + // Draw the map + + _vm->_draw->_backSurface->blit(*_map, _sub->mapX, _sub->mapY, + _sub->mapX + kPlayAreaWidth - 1, _sub->mapY + kPlayAreaHeight - 1, kPlayAreaX, kPlayAreaY); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kPlayAreaX, kPlayAreaY, + kPlayAreaX + kPlayAreaWidth - 1, kPlayAreaY + kPlayAreaHeight - 1); + } // Draw the current animation frames for (Common::List::iterator a = _anims.begin(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 488396ea32..0582b99e83 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -28,6 +28,8 @@ #include "gob/sound/sounddesc.h" +#include "gob/minigames/geisha/submarine.h" + namespace Gob { class GobEngine; @@ -77,6 +79,18 @@ private: ~ManagedMouth(); }; + struct ManagedSub : public Position { + Submarine *sub; + + uint16 mapX; + uint16 mapY; + + ManagedSub(uint16 pX, uint16 pY); + ~ManagedSub(); + + void setPosition(uint16 pX, uint16 pY); + }; + GobEngine *_vm; bool _hasAccessPass; @@ -87,8 +101,6 @@ private: CMPFile *_sprites; ANIFile *_objects; - ANIObject *_sub; - Common::List _anims; Common::List _mapAnims; @@ -100,11 +112,7 @@ private: Surface *_map; byte _mapTiles[kMapWidth * kMapHeight]; - uint16 _mapX; - uint16 _mapY; - - uint8 _subTileX; - uint8 _subTileY; + ManagedSub *_sub; Common::List _shields; Common::List _mouths; @@ -112,6 +120,7 @@ private: SoundDesc _soundShield; SoundDesc _soundBite; SoundDesc _soundKiss; + SoundDesc _soundShoot; void init(); @@ -126,7 +135,8 @@ private: int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); void handleSub(int16 key); - void moveSub(int x, int y, uint16 animation); + void subMove(int x, int y, Submarine::Direction direction); + void subShoot(); bool isWalkable(byte tile) const; @@ -135,6 +145,9 @@ private: void healthGain(int amount); void healthLose(int amount); + + bool isDead() const; + bool hasWon() const; }; } // End of namespace Geisha diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp new file mode 100644 index 0000000000..4a18c6e043 --- /dev/null +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -0,0 +1,233 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/minigames/geisha/submarine.h" + +namespace Gob { + +namespace Geisha { + +enum Animation { + kAnimationDriveS = 4, + kAnimationDriveE = 5, + kAnimationDriveN = 6, + kAnimationDriveW = 7, + kAnimationDriveSE = 8, + kAnimationDriveNE = 9, + kAnimationDriveSW = 10, + kAnimationDriveNW = 11, + kAnimationShootS = 12, + kAnimationShootN = 13, + kAnimationShootW = 14, + kAnimationShootE = 15, + kAnimationShootNE = 16, + kAnimationShootSE = 17, + kAnimationShootSW = 18, + kAnimationShootNW = 19, + kAnimationExplodeN = 28, + kAnimationExplodeS = 29, + kAnimationExplodeW = 30, + kAnimationExplodeE = 31, + kAnimationExit = 32 +}; + + +Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateNone) { + turn(kDirectionN); +} + +Submarine::~Submarine() { +} + +void Submarine::turn(Direction to) { + // Nothing to do + if ((_state == kStateMove) && (_direction == to)) + return; + + _state = kStateMove; + _direction = to; + + setAnimation(directionToMove(_direction)); + setMode(kModeContinuous); + setPause(false); + setVisible(true); +} + +void Submarine::shoot() { + _state = kStateShoot; + + setAnimation(directionToShoot(_direction)); + setMode(kModeOnce); + setPause(false); + setVisible(true); +} + +void Submarine::die() { + _state = kStateDie; + + setAnimation(directionToExplode(_direction)); + setMode(kModeOnce); + setPause(false); + setVisible(true); +} + +void Submarine::leave() { + _state = kStateExit; + + setAnimation(kAnimationExit); + setMode(kModeOnce); + setPause(false); + setVisible(true); +} + +void Submarine::advance() { + ANIObject::advance(); + + switch (_state) { + case kStateShoot: + if (isPaused()) + turn(_direction); + break; + + case kStateExit: + if (isPaused()) { + _state = kStateExited; + + setVisible(true); + } + + break; + + case kStateDie: + if (isPaused()) + _state = kStateDead; + break; + + default: + break; + } +} + +bool Submarine::canMove() const { + return (_state == kStateMove) || (_state == kStateShoot); +} + +bool Submarine::isDead() const { + return _state == kStateDead; +} + +uint16 Submarine::directionToMove(Direction direction) const { + switch (direction) { + case kDirectionN: + return kAnimationDriveN; + + case kDirectionNE: + return kAnimationDriveNE; + + case kDirectionE: + return kAnimationDriveE; + + case kDirectionSE: + return kAnimationDriveSE; + + case kDirectionS: + return kAnimationDriveS; + + case kDirectionSW: + return kAnimationDriveSW; + + case kDirectionW: + return kAnimationDriveW; + + case kDirectionNW: + return kAnimationDriveNW; + + default: + break; + } + + return 0; +} + +uint16 Submarine::directionToShoot(Direction direction) const { + switch (direction) { + case kDirectionN: + return kAnimationShootN; + + case kDirectionNE: + return kAnimationShootNE; + + case kDirectionE: + return kAnimationShootE; + + case kDirectionSE: + return kAnimationShootSE; + + case kDirectionS: + return kAnimationShootS; + + case kDirectionSW: + return kAnimationShootSW; + + case kDirectionW: + return kAnimationShootW; + + case kDirectionNW: + return kAnimationShootNW; + + default: + break; + } + + return 0; +} + +uint16 Submarine::directionToExplode(Direction direction) const { + // Only 4 exploding animations (spinning clockwise) + + switch (direction) { + case kDirectionNW: + case kDirectionN: + return kAnimationExplodeN; + + case kDirectionNE: + case kDirectionE: + return kAnimationExplodeE; + + case kDirectionSE: + case kDirectionS: + return kAnimationExplodeS; + + case kDirectionSW: + case kDirectionW: + return kAnimationExplodeW; + + default: + break; + } + + return 0; +} + +} // End of namespace Geisha + +} // End of namespace Gob diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h new file mode 100644 index 0000000000..e8ae72d996 --- /dev/null +++ b/engines/gob/minigames/geisha/submarine.h @@ -0,0 +1,96 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_MINIGAMES_GEISHA_SUBMARINE_H +#define GOB_MINIGAMES_GEISHA_SUBMARINE_H + +#include "gob/aniobject.h" + +namespace Gob { + +namespace Geisha { + +/** The submarine Geisha's "Penetration" minigame. */ +class Submarine : public ANIObject { +public: + enum Direction { + kDirectionN, + kDirectionNE, + kDirectionE, + kDirectionSE, + kDirectionS, + kDirectionSW, + kDirectionW, + kDirectionNW + }; + + Submarine(const ANIFile &ani); + ~Submarine(); + + /** Turn to the specified direction. */ + void turn(Direction to); + + /** Play the shoot animation. */ + void shoot(); + + /** Play the exploding animation. */ + void die(); + + /** Play the exiting animation. */ + void leave(); + + /** Advance the animation to the next frame. */ + void advance(); + + /** Can the submarine move at the moment? */ + bool canMove() const; + + /** Is the submarine dead? */ + bool isDead() const; + +private: + enum State { + kStateNone = 0, + kStateMove, + kStateShoot, + kStateExit, + kStateExited, + kStateDie, + kStateDead + }; + + State _state; + Direction _direction; + + /** Map the directions to move animation indices. */ + uint16 directionToMove(Direction direction) const; + /** Map the directions to shoot animation indices. */ + uint16 directionToShoot(Direction direction) const; + /** Map the directions to explode animation indices. */ + uint16 directionToExplode(Direction direction) const; +}; + +} // End of namespace Geisha + +} // End of namespace Gob + +#endif // GOB_MINIGAMES_GEISHA_SUBMARINE_H diff --git a/engines/gob/module.mk b/engines/gob/module.mk index c5ae947a1c..b9680fad6b 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -81,6 +81,7 @@ MODULE_OBJS := \ minigames/geisha/meter.o \ minigames/geisha/diving.o \ minigames/geisha/mouth.o \ + minigames/geisha/submarine.o \ minigames/geisha/penetration.o \ save/savefile.o \ save/savehandler.o \ -- cgit v1.2.3 From 1782012f9f9ec368689fb2e232543a5aea3c1073 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 03:12:12 +0200 Subject: GOB: Clean up the Penetration map handling a bit --- engines/gob/minigames/geisha/penetration.cpp | 92 ++++++++++++++-------------- engines/gob/minigames/geisha/penetration.h | 6 +- 2 files changed, 49 insertions(+), 49 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 2c1a4918b9..22cb06fed8 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -309,84 +309,88 @@ void Penetration::deinit() { _soundKiss.free(); _soundShoot.free(); + clearMap(); + + delete _objects; + delete _sprites; + + _objects = 0; + _sprites = 0; +} + +void Penetration::clearMap() { _mapAnims.clear(); _anims.clear(); + _exits.clear(); _shields.clear(); - _mouths.clear(); delete _sub; - delete _objects; - delete _sprites; - - _objects = 0; - _sprites = 0; - _sub = 0; + + _map->fill(kColorBlack); } void Penetration::createMap() { if (_floor >= kFloorCount) error("Geisha: Invalid floor %d in minigame penetration", _floor); - // Copy the correct map - memcpy(_mapTiles, kMaps[_testMode ? 1 : 0][_floor], kMapWidth * kMapHeight); - - delete _sub; - _sub = 0; + clearMap(); - _shields.clear(); - _mouths.clear(); + const byte *mapTiles = kMaps[_testMode ? 1 : 0][_floor]; - _map->fill(kColorBlack); + bool exitWorks; // Draw the map tiles for (int y = 0; y < kMapHeight; y++) { for (int x = 0; x < kMapWidth; x++) { - byte *mapTile = _mapTiles + (y * kMapWidth + x); + const byte mapTile = mapTiles[y * kMapWidth + x]; + + bool *walkMap = _walkMap + (y * kMapWidth + x); const int posX = kPlayAreaBorderWidth + x * kMapTileWidth; const int posY = kPlayAreaBorderHeight + y * kMapTileHeight; - switch (*mapTile) { + *walkMap = true; + + switch (mapTile) { case 0: // Floor _sprites->draw(*_map, kSpriteFloor, posX, posY); break; case 49: // Emergency exit (needs access pass) - if (_hasAccessPass) { + exitWorks = _hasAccessPass; + if (exitWorks) { + _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); - *mapTile = 51; // Now works like a normal exit - } else + } else { _sprites->draw(*_map, kSpriteWall, posX, posY); + *walkMap = false; + } break; case 50: // Wall _sprites->draw(*_map, kSpriteWall, posX, posY); + *walkMap = false; break; case 51: // Regular exit - if (!_testMode) { - // When we're not in test mode, the last exit only works with an access pass - - if (_floor == 2) { - if (!_hasAccessPass) { - _sprites->draw(*_map, kSpriteWall, posX, posY); - *mapTile = 50; // It's now a wall - } else - _sprites->draw(*_map, kSpriteExit, posX, posY); - - } else - _sprites->draw(*_map, kSpriteExit, posX, posY); + // A regular exit works always in test mode. + // But if we're in real mode, and on the last floor, it needs an access pass + exitWorks = _testMode || (_floor < 2) || _hasAccessPass; - } else - // Always works in test mode + if (exitWorks) { + _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); + } else { + _sprites->draw(*_map, kSpriteWall, posX, posY); + *walkMap = false; + } break; @@ -400,7 +404,6 @@ void Penetration::createMap() { break; case 53: // Right side of biting mouth - *mapTile = 0; // Works like a floor break; case 54: // Left side of kissing mouth @@ -413,7 +416,6 @@ void Penetration::createMap() { break; case 55: // Right side of kissing mouth - *mapTile = 0; // Works like a floor break; case 56: // Shield lying on the floor @@ -429,8 +431,6 @@ void Penetration::createMap() { case 57: // Start position _sprites->draw(*_map, kSpriteFloor, posX, posY); - *mapTile = 0; - delete _sub; _sub = new ManagedSub(x, y); @@ -472,13 +472,11 @@ int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseB return _vm->_util->checkKey(); } -bool Penetration::isWalkable(byte tile) const { - // Only walls are nonwalkable - - if (tile == 50) +bool Penetration::isWalkable(int16 x, int16 y) const { + if ((x < 0) || (x >= kMapWidth) || (y < 0) || (y >= kMapHeight)) return false; - return true; + return _walkMap[y * kMapWidth + x]; } void Penetration::handleSub(int16 key) { @@ -501,19 +499,19 @@ void Penetration::subMove(int x, int y, Submarine::Direction direction) { // Limit the movement to walkable tiles int16 minX = 0; - if ((_sub->x > 0) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x - 1)])) + if (!isWalkable(_sub->x - 1, _sub->y)) minX = _sub->x * kMapTileWidth; int16 maxX = kMapWidth * kMapTileWidth; - if ((_sub->x < (kMapWidth - 1)) && !isWalkable(_mapTiles[_sub->y * kMapWidth + (_sub->x + 1)])) + if (!isWalkable(_sub->x + 1, _sub->y)) maxX = _sub->x * kMapTileWidth; int16 minY = 0; - if ((_sub->y > 0) && !isWalkable(_mapTiles[(_sub->y - 1) * kMapWidth + _sub->x])) + if (!isWalkable(_sub->x, _sub->y - 1)) minY = _sub->y * kMapTileHeight; int16 maxY = kMapHeight * kMapTileHeight; - if ((_sub->y < (kMapHeight - 1)) && !isWalkable(_mapTiles[(_sub->y + 1) * kMapWidth + _sub->x])) + if (!isWalkable(_sub->x, _sub->y + 1)) maxY = _sub->y * kMapTileHeight; _sub->mapX = CLIP(_sub->mapX + x, minX, maxX); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 0582b99e83..a5740382c6 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -110,10 +110,11 @@ private: uint8 _floor; Surface *_map; - byte _mapTiles[kMapWidth * kMapHeight]; + bool _walkMap[kMapWidth * kMapHeight]; ManagedSub *_sub; + Common::List _exits; Common::List _shields; Common::List _mouths; @@ -126,6 +127,7 @@ private: void init(); void deinit(); + void clearMap(); void createMap(); void initScreen(); @@ -138,7 +140,7 @@ private: void subMove(int x, int y, Submarine::Direction direction); void subShoot(); - bool isWalkable(byte tile) const; + bool isWalkable(int16 x, int16 y) const; void checkShields(); void checkMouths(); -- cgit v1.2.3 From 04d0ec8d03d46f59f950929321fef43b52ea740a Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 03:27:40 +0200 Subject: GOB: Implement exiting floors --- engines/gob/minigames/geisha/penetration.cpp | 47 +++++++++++++++++++++++----- engines/gob/minigames/geisha/penetration.h | 4 +++ engines/gob/minigames/geisha/submarine.cpp | 9 +++--- engines/gob/minigames/geisha/submarine.h | 3 ++ 4 files changed, 52 insertions(+), 11 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 22cb06fed8..856c063edf 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -263,6 +263,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Handle the sub movement handleSub(key); + + checkExited(); } deinit(); @@ -276,6 +278,7 @@ void Penetration::init() { _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); + _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); _background->clear(); @@ -296,11 +299,6 @@ void Penetration::init() { _floor = 0; createMap(); - - for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) - _mapAnims.push_back(m->mouth); - - _anims.push_back(_sub->sub); } void Penetration::deinit() { @@ -308,6 +306,7 @@ void Penetration::deinit() { _soundBite.free(); _soundKiss.free(); _soundShoot.free(); + _soundExit.free(); clearMap(); @@ -443,7 +442,12 @@ void Penetration::createMap() { } if (!_sub) - error("Geisha: No starting position in floor %d (testmode: %d", _floor, _testMode); + error("Geisha: No starting position in floor %d (testmode: %d)", _floor, _testMode); + + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) + _mapAnims.push_back(m->mouth); + + _anims.push_back(_sub->sub); } void Penetration::initScreen() { @@ -525,6 +529,7 @@ void Penetration::subMove(int x, int y, Submarine::Direction direction) { checkShields(); checkMouths(); + checkExits(); } void Penetration::subShoot() { @@ -578,6 +583,23 @@ void Penetration::checkMouths() { } } +void Penetration::checkExits() { + if (!_sub->sub->canMove()) + return; + + for (Common::List::iterator e = _exits.begin(); e != _exits.end(); ++e) { + if ((e->x == _sub->x) && (e->y == _sub->y)) { + _sub->mapX = e->x * kMapTileWidth; + _sub->mapY = e->y * kMapTileHeight; + + _sub->sub->leave(); + + _vm->_sound->blasterPlay(&_soundExit, 1, 0); + break; + } + } +} + void Penetration::healthGain(int amount) { if (_shieldMeter->getValue() > 0) _healthMeter->increase(_shieldMeter->increase(amount)); @@ -592,12 +614,23 @@ void Penetration::healthLose(int amount) { _sub->sub->die(); } +void Penetration::checkExited() { + if (_sub->sub->hasExited()) { + _floor++; + + if (_floor >= kFloorCount) + return; + + createMap(); + } +} + bool Penetration::isDead() const { return _sub && _sub->sub->isDead(); } bool Penetration::hasWon() const { - return _floor > kFloorCount; + return _floor >= kFloorCount; } void Penetration::updateAnims() { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index a5740382c6..f717e7219b 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -122,6 +122,7 @@ private: SoundDesc _soundBite; SoundDesc _soundKiss; SoundDesc _soundShoot; + SoundDesc _soundExit; void init(); @@ -142,12 +143,15 @@ private: bool isWalkable(int16 x, int16 y) const; + void checkExits(); void checkShields(); void checkMouths(); void healthGain(int amount); void healthLose(int amount); + void checkExited(); + bool isDead() const; bool hasWon() const; }; diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index 4a18c6e043..0f3f936ea6 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -109,12 +109,9 @@ void Submarine::advance() { break; case kStateExit: - if (isPaused()) { + if (isPaused()) _state = kStateExited; - setVisible(true); - } - break; case kStateDie: @@ -135,6 +132,10 @@ bool Submarine::isDead() const { return _state == kStateDead; } +bool Submarine::hasExited() const { + return _state == kStateExited; +} + uint16 Submarine::directionToMove(Direction direction) const { switch (direction) { case kDirectionN: diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index e8ae72d996..d14e4e953b 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -67,6 +67,9 @@ public: /** Is the submarine dead? */ bool isDead() const; + /** Has the submarine finished exiting the level? */ + bool hasExited() const; + private: enum State { kStateNone = 0, -- cgit v1.2.3 From 78c9c72691957ea8c6ed823b76b67a1c0e1d9a93 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 16:50:22 +0200 Subject: GOB: Set Penetration floor palettes and fade in/out --- engines/gob/minigames/geisha/penetration.cpp | 106 +++++++++++++++++++++------ engines/gob/minigames/geisha/penetration.h | 8 ++ 2 files changed, 90 insertions(+), 24 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 856c063edf..6d18a230a8 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -22,6 +22,7 @@ #include "gob/global.h" #include "gob/util.h" +#include "gob/palanim.h" #include "gob/draw.h" #include "gob/video.h" #include "gob/decfile.h" @@ -39,25 +40,6 @@ namespace Gob { namespace Geisha { -static const byte kPalette[48] = { - 0x16, 0x16, 0x16, - 0x12, 0x14, 0x16, - 0x34, 0x00, 0x25, - 0x1D, 0x1F, 0x22, - 0x24, 0x27, 0x2A, - 0x2C, 0x0D, 0x22, - 0x2B, 0x2E, 0x32, - 0x12, 0x09, 0x20, - 0x3D, 0x3F, 0x00, - 0x3F, 0x3F, 0x3F, - 0x00, 0x00, 0x00, - 0x15, 0x15, 0x3F, - 0x25, 0x22, 0x2F, - 0x1A, 0x14, 0x28, - 0x3F, 0x00, 0x00, - 0x15, 0x3F, 0x15 -}; - static const int kColorShield = 11; static const int kColorHealth = 15; static const int kColorBlack = 10; @@ -88,6 +70,63 @@ static const int kPlayAreaHeight = 113; static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2; static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2; +const byte Penetration::kPalettes[kFloorCount][3 * kPaletteSize] = { + { + 0x16, 0x16, 0x16, + 0x12, 0x14, 0x16, + 0x34, 0x00, 0x25, + 0x1D, 0x1F, 0x22, + 0x24, 0x27, 0x2A, + 0x2C, 0x0D, 0x22, + 0x2B, 0x2E, 0x32, + 0x12, 0x09, 0x20, + 0x3D, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x25, 0x22, 0x2F, + 0x1A, 0x14, 0x28, + 0x3F, 0x00, 0x00, + 0x15, 0x3F, 0x15 + }, + { + 0x16, 0x16, 0x16, + 0x12, 0x14, 0x16, + 0x37, 0x00, 0x24, + 0x1D, 0x1F, 0x22, + 0x24, 0x27, 0x2A, + 0x30, 0x0E, 0x16, + 0x2B, 0x2E, 0x32, + 0x22, 0x0E, 0x26, + 0x3D, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x36, 0x28, 0x36, + 0x30, 0x1E, 0x2A, + 0x3F, 0x00, 0x00, + 0x15, 0x3F, 0x15 + }, + { + 0x16, 0x16, 0x16, + 0x12, 0x14, 0x16, + 0x3F, 0x14, 0x22, + 0x1D, 0x1F, 0x22, + 0x24, 0x27, 0x2A, + 0x30, 0x10, 0x10, + 0x2B, 0x2E, 0x32, + 0x2A, 0x12, 0x12, + 0x3D, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x3F, 0x23, 0x31, + 0x39, 0x20, 0x2A, + 0x3F, 0x00, 0x00, + 0x15, 0x3F, 0x15 + } +}; + const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = { { { // Real mode, floor 0 @@ -246,8 +285,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { while (!_vm->shouldQuit() && !isDead() && !hasWon()) { updateAnims(); - // Draw and wait for the end of the frame + // Draw, fade in if necessary and wait for the end of the frame _vm->_draw->blitInvalidated(); + fadeIn(); _vm->_util->waitEndFrame(); // Handle input @@ -450,13 +490,30 @@ void Penetration::createMap() { _anims.push_back(_sub->sub); } +void Penetration::fadeIn() { + if (!_needFadeIn) + return; + + // Fade to palette + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + _needFadeIn = false; +} + +void Penetration::setPalette() { + // Fade to black + _vm->_palAnim->fade(0, 0, 0); + + // Set palette + memcpy(_vm->_draw->_vgaPalette , kPalettes[_floor], 3 * kPaletteSize); + memcpy(_vm->_draw->_vgaSmallPalette, kPalettes[_floor], 3 * kPaletteSize); + + _needFadeIn = true; +} + void Penetration::initScreen() { _vm->_util->setFrameRate(15); - memcpy(_vm->_draw->_vgaPalette , kPalette, 48); - memcpy(_vm->_draw->_vgaSmallPalette, kPalette, 48); - - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + setPalette(); // Draw the shield meter _sprites->draw(*_background, 0, 0, 95, 6, 9, 117, 0); // Meter frame @@ -621,6 +678,7 @@ void Penetration::checkExited() { if (_floor >= kFloorCount) return; + setPalette(); createMap(); } } diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index f717e7219b..f19e186d82 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -57,6 +57,9 @@ private: static const int kMapWidth = 17; static const int kMapHeight = 13; + static const int kPaletteSize = 16; + + static const byte kPalettes[kFloorCount][3 * kPaletteSize]; static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; struct Position { @@ -97,6 +100,8 @@ private: bool _hasMaxEnergy; bool _testMode; + bool _needFadeIn; + Surface *_background; CMPFile *_sprites; ANIFile *_objects; @@ -133,6 +138,9 @@ private: void initScreen(); + void setPalette(); + void fadeIn(); + void updateAnims(); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); -- cgit v1.2.3 From 5913b9b839edc2a2bb6caecaee3336bd4de5a673 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 19:03:23 +0200 Subject: GOB: Draw info texts in Penetration The German strings have been changed from the original, to fix the horribly broken German. Someone should probably check the Italian and Spanish strings too. --- engines/gob/minigames/geisha/penetration.cpp | 219 ++++++++++++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 5 + 2 files changed, 220 insertions(+), 4 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 6d18a230a8..8fe75b083e 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -40,10 +40,12 @@ namespace Gob { namespace Geisha { -static const int kColorShield = 11; -static const int kColorHealth = 15; -static const int kColorBlack = 10; -static const int kColorFloor = 13; +static const int kColorShield = 11; +static const int kColorHealth = 15; +static const int kColorBlack = 10; +static const int kColorFloor = 13; +static const int kColorFloorText = 14; +static const int kColorExitText = 15; enum Sprite { kSpriteFloorShield = 25, @@ -70,6 +72,13 @@ static const int kPlayAreaHeight = 113; static const int kPlayAreaBorderWidth = kPlayAreaWidth / 2; static const int kPlayAreaBorderHeight = kPlayAreaHeight / 2; +static const int kTextAreaLeft = 9; +static const int kTextAreaTop = 7; +static const int kTextAreaRight = 104; +static const int kTextAreaBottom = 107; + +static const int kTextAreaBigBottom = 142; + const byte Penetration::kPalettes[kFloorCount][3 * kPaletteSize] = { { 0x16, 0x16, 0x16, @@ -224,6 +233,122 @@ const byte Penetration::kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight] = } }; +static const int kLanguageCount = 5; +static const int kFallbackLanguage = 2; // English + +enum String { + kString3rdBasement = 0, + kString2ndBasement, + kString1stBasement, + kStringNoExit, + kStringYouHave, + kString2Exits, + kString1Exit, + kStringToReach, + kStringUpperLevel1, + kStringUpperLevel2, + kStringLevel0, + kStringPenetration, + kStringSuccessful, + kStringDanger, + kStringGynoides, + kStringActivated, + kStringCount +}; + +static const char *kStrings[kLanguageCount][kStringCount] = { + { // French + "3EME SOUS-SOL", + "2EME SOUS-SOL", + "1ER SOUS-SOL", + "SORTIE REFUSEE", + "Vous disposez", + "de deux sorties", + "d\'une sortie", + "pour l\'acc\212s au", + "niveau", + "sup\202rieur", + "- NIVEAU 0 -", + "PENETRATION", + "REUSSIE", + "DANGER", + "GYNOIDES", + "ACTIVEES" + }, + { // German + // NOTE: The original had very broken German there. We provide proper(ish) German instead. + "3. UNTERGESCHOSS", + "2. UNTERGESCHOSS", + "1. UNTERGESCHOSS", + "AUSGANG GESPERRT", + "Sie haben", + "zwei Ausg\204nge", + "einen Ausgang", + "um das obere", + "Stockwerk zu", + "erreichen", + "- STOCKWERK 0 -", + "PENETRATION", + "ERFOLGREICH", + "GEFAHR", + "GYNOIDE", + "AKTIVIERT", + }, + { // English + "3RD BASEMENT", + "2ND BASEMENT", + "1ST BASEMENT", + "NO EXIT", + "You have", + "2 exits", + "1 exit", + "to reach upper", + "level", + "", + "- 0 LEVEL -", + "PENETRATION", + "SUCCESSFUL", + "DANGER", + "GYNOIDES", + "ACTIVATED", + }, + { // Spanish + "3ER. SUBSUELO", + "2D. SUBSUELO", + "1ER. SUBSUELO", + "SALIDA RECHAZADA", + "Dispones", + "de dos salidas", + "de una salida", + "para acceso al", + "nivel", + "superior", + "- NIVEL 0 -", + "PENETRACION", + "CONSEGUIDA", + "PELIGRO", + "GYNOIDAS", + "ACTIVADAS", + }, + { // Italian + "SOTTOSUOLO 3", + "SOTTOSUOLO 2", + "SOTTOSUOLO 1", + "NON USCITA", + "avete", + "due uscite", + "un\' uscita", + "per accedere al", + "livello", + "superiore", + "- LIVELLO 0 -", + "PENETRAZIONE", + "RIUSCITA", + "PERICOLO", + "GYNOIDI", + "ATTIVATE", + } +}; Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { } @@ -279,6 +404,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { init(); initScreen(); + drawFloorText(); + _vm->_draw->blitInvalidated(); _vm->_video->retrace(); @@ -308,6 +435,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { } deinit(); + drawEndText(); return hasWon(); } @@ -490,6 +618,81 @@ void Penetration::createMap() { _anims.push_back(_sub->sub); } +void Penetration::drawFloorText() { + _vm->_draw->_backSurface->fillRect(kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBottom, kColorBlack); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBottom); + + const Font *font = _vm->_draw->_fonts[2]; + if (!font) + return; + + const char **strings = kStrings[getLanguage()]; + + const char *floorString = 0; + if (_floor == 0) + floorString = strings[kString3rdBasement]; + else if (_floor == 1) + floorString = strings[kString2ndBasement]; + else if (_floor == 2) + floorString = strings[kString1stBasement]; + + if (floorString) + _vm->_draw->drawString(floorString, 10, 15, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + if (_exits.size() > 0) { + int exitCount = kString2Exits; + if (_exits.size() == 1) + exitCount = kString1Exit; + + _vm->_draw->drawString(strings[kStringYouHave] , 10, 38, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[exitCount] , 10, 53, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringToReach] , 10, 68, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringUpperLevel1], 10, 84, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringUpperLevel2], 10, 98, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + } else + _vm->_draw->drawString(strings[kStringNoExit], 10, 53, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); +} + +void Penetration::drawEndText() { + // Only draw the end text when we've won and this isn't a test run + if (!hasWon() || _testMode) + return; + + _vm->_draw->_backSurface->fillRect(kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBigBottom, kColorBlack); + + const Font *font = _vm->_draw->_fonts[2]; + if (!font) + return; + + const char **strings = kStrings[getLanguage()]; + + _vm->_draw->drawString(strings[kStringLevel0] , 11, 21, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringPenetration], 11, 42, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringSuccessful] , 11, 58, kColorExitText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + _vm->_draw->drawString(strings[kStringDanger] , 11, 82, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringGynoides] , 11, 98, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + _vm->_draw->drawString(strings[kStringActivated], 11, 113, kColorFloorText, kColorBlack, 1, + *_vm->_draw->_backSurface, *font); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBigBottom); + _vm->_draw->blitInvalidated(); + _vm->_video->retrace(); +} + void Penetration::fadeIn() { if (!_needFadeIn) return; @@ -680,6 +883,7 @@ void Penetration::checkExited() { setPalette(); createMap(); + drawFloorText(); } } @@ -691,6 +895,13 @@ bool Penetration::hasWon() const { return _floor >= kFloorCount; } +int Penetration::getLanguage() const { + if (_vm->_global->_language < kLanguageCount) + return _vm->_global->_language; + + return kFallbackLanguage; +} + void Penetration::updateAnims() { int16 left = 0, top = 0, right = 0, bottom = 0; diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index f19e186d82..3f03bfaf38 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -141,6 +141,9 @@ private: void setPalette(); void fadeIn(); + void drawFloorText(); + void drawEndText(); + void updateAnims(); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); @@ -162,6 +165,8 @@ private: bool isDead() const; bool hasWon() const; + + int getLanguage() const; }; } // End of namespace Geisha -- cgit v1.2.3 From 4288edd5236cb0c232dea0bd818779539e9bc6f2 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 6 Jun 2012 19:21:21 +0200 Subject: GOB: Add the original broken German as comments --- engines/gob/minigames/geisha/penetration.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 8fe75b083e..1bcc42a329 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -277,19 +277,20 @@ static const char *kStrings[kLanguageCount][kStringCount] = { }, { // German // NOTE: The original had very broken German there. We provide proper(ish) German instead. - "3. UNTERGESCHOSS", - "2. UNTERGESCHOSS", - "1. UNTERGESCHOSS", + // B0rken text in the comments after each line + "3. UNTERGESCHOSS", // "3. U.-GESCHOSS"" + "2. UNTERGESCHOSS", // "2. U.-GESCHOSS" + "1. UNTERGESCHOSS", // "1. U.-GESCHOSS" "AUSGANG GESPERRT", "Sie haben", - "zwei Ausg\204nge", - "einen Ausgang", - "um das obere", - "Stockwerk zu", - "erreichen", - "- STOCKWERK 0 -", - "PENETRATION", - "ERFOLGREICH", + "zwei Ausg\204nge", // "zwei Ausgang" + "einen Ausgang", // "Fortsetztung" + "um das obere", // "" + "Stockwerk zu", // "" + "erreichen", // "" + "- STOCKWERK 0 -", // "0 - HOHE" + "PENETRATION", // "DURCHDRIGEN" + "ERFOLGREICH", // "ERFOLG" "GEFAHR", "GYNOIDE", "AKTIVIERT", -- cgit v1.2.3 From 8c3d2fc7410ab3f55735f6a78dadbeec23c59b6c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 00:21:54 +0200 Subject: GOB: Add a way to reopen currently opened IMD/VMD videos This is a workaround for how Lost in Time behaves in combination with changes I made to the DataIO code for running Urban Runner on low-memory devices. Urban Runner's intro are far to big to have them copied into memory for these devices, so I made the DataIO code return a SafeSeekableSubReadStream into the opened archive stream instead. Unfortunately, Lost in Time might not close a video file when it closes the data file which it was originally in, especially when loading a saved game. Since the video player needs to be able to gaplessly continue a video and there does not, by itself, close the video if not requested by the scripts, this leads to reading out of an already closed stream in certain cases. So, to worka round this issues, the video player tries to reopen each currently opened video after a data archive was closed, to make sure that that video is still available. If not, the video is closed. --- engines/gob/inter_v1.cpp | 9 ++++++-- engines/gob/inter_v2.cpp | 4 ++++ engines/gob/videoplayer.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++ engines/gob/videoplayer.h | 7 +++++++ 4 files changed, 68 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 9aa190a456..4aa54f720b 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1744,10 +1744,15 @@ void Inter_v1::o1_writeData(OpFuncParams ¶ms) { void Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { Common::String file = _vm->_game->_script->evalString(); - if (!file.empty()) + if (!file.empty()) { _vm->_dataIO->openArchive(file, true); - else + } else { _vm->_dataIO->closeArchive(true); + + // NOTE: Lost in Time might close a data file without explicitely closing a video in it. + // So we make sure that all open videos are still available. + _vm->_vidPlayer->reopenAll(); + } } void Inter_v1::o1_setState(OpGobParams ¶ms) { diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 1e5b7bb24c..54f6a1acc1 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1002,6 +1002,10 @@ void Inter_v2::o2_openItk() { void Inter_v2::o2_closeItk() { _vm->_dataIO->closeArchive(false); + + // NOTE: Lost in Time might close a data file without explicitely closing a video in it. + // So we make sure that all open videos are still available. + _vm->_vidPlayer->reopenAll(); } void Inter_v2::o2_setImdFrontSurf() { diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 221f5ab3c9..a478492ccc 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -234,6 +234,23 @@ void VideoPlayer::closeAll() { closeVideo(i); } +bool VideoPlayer::reopenVideo(int slot) { + Video *video = getVideoBySlot(slot); + if (!video) + return true; + + return reopenVideo(*video); +} + +bool VideoPlayer::reopenAll() { + bool all = true; + for (int i = 0; i < kVideoSlotCount; i++) + if (!reopenVideo(i)) + all = false; + + return all; +} + void VideoPlayer::pauseVideo(int slot, bool pause) { Video *video = getVideoBySlot(slot); if (!video || !video->decoder) @@ -850,6 +867,39 @@ Common::String VideoPlayer::findFile(const Common::String &file, Properties &pro return video; } +bool VideoPlayer::reopenVideo(Video &video) { + if (video.isEmpty()) + return true; + + if (video.fileName.empty()) { + video.close(); + return false; + } + + Properties properties; + + properties.type = video.properties.type; + + Common::String fileName = findFile(video.fileName, properties); + if (fileName.empty()) { + video.close(); + return false; + } + + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); + if (!stream) { + video.close(); + return false; + } + + if (!video.decoder->reloadStream(stream)) { + delete stream; + return false; + } + + return true; +} + void VideoPlayer::copyPalette(const Video &video, int16 palStart, int16 palEnd) { if (!video.decoder->hasPalette() || !video.decoder->isPaletted()) return; diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index bc7cb48768..129ccef67a 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -110,6 +110,9 @@ public: void closeLiveSound(); void closeAll(); + bool reopenVideo(int slot = 0); + bool reopenAll(); + void pauseVideo(int slot, bool pause); void pauseAll(bool pause); @@ -163,6 +166,8 @@ private: bool isEmpty() const; void close(); + + void reopen(); }; static const int kVideoSlotCount = 32; @@ -188,6 +193,8 @@ private: ::Video::CoktelDecoder *openVideo(const Common::String &file, Properties &properties); + bool reopenVideo(Video &video); + bool playFrame(int slot, Properties &properties); void checkAbort(Video &video, Properties &properties); -- cgit v1.2.3 From 95454ab52c3e8f251b08aa62b18f071374de85b9 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 04:02:42 +0200 Subject: GOB: Better controls in Geisha's Penetration You can actually move diagonally now --- engines/gob/minigames/geisha/penetration.cpp | 103 ++++++++++++++++++++------- engines/gob/minigames/geisha/penetration.h | 18 ++++- engines/gob/minigames/geisha/submarine.cpp | 2 +- engines/gob/minigames/geisha/submarine.h | 1 + 4 files changed, 96 insertions(+), 28 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 1bcc42a329..72c53cb5c3 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -20,6 +20,8 @@ * */ +#include "common/events.h" + #include "gob/global.h" #include "gob/util.h" #include "gob/palanim.h" @@ -410,7 +412,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_draw->blitInvalidated(); _vm->_video->retrace(); - while (!_vm->shouldQuit() && !isDead() && !hasWon()) { + while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) { updateAnims(); // Draw, fade in if necessary and wait for the end of the frame @@ -418,19 +420,11 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { fadeIn(); _vm->_util->waitEndFrame(); - // Handle input - _vm->_util->processInput(); - - int16 mouseX, mouseY; - MouseButtons mouseButtons; - - int16 key = checkInput(mouseX, mouseY, mouseButtons); - // Aborting the game - if (key == kKeyEscape) - break; + // Handle the input + checkInput(); // Handle the sub movement - handleSub(key); + handleSub(); checkExited(); } @@ -449,6 +443,10 @@ void Penetration::init() { _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); + _quit = false; + for (int i = 0; i < kKeyCount; i++) + _keys[i] = false; + _background->clear(); _vm->_video->drawPackedSprite("hyprmef2.cmp", *_background); @@ -731,10 +729,44 @@ void Penetration::initScreen() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } -int16 Penetration::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) { - _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons); +void Penetration::checkInput() { + Common::Event event; + Common::EventManager *eventMan = g_system->getEventManager(); + + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + _quit = true; + else if (event.kbd.keycode == Common::KEYCODE_UP) + _keys[kKeyUp ] = true; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keys[kKeyDown ] = true; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keys[kKeyLeft ] = true; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keys[kKeyRight] = true; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keys[kKeySpace] = true; + break; + + case Common::EVENT_KEYUP: + if (event.kbd.keycode == Common::KEYCODE_UP) + _keys[kKeyUp ] = false; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keys[kKeyDown ] = false; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keys[kKeyLeft ] = false; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keys[kKeyRight] = false; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keys[kKeySpace] = false; + break; - return _vm->_util->checkKey(); + default: + break; + } + } } bool Penetration::isWalkable(int16 x, int16 y) const { @@ -744,16 +776,13 @@ bool Penetration::isWalkable(int16 x, int16 y) const { return _walkMap[y * kMapWidth + x]; } -void Penetration::handleSub(int16 key) { - if (key == kKeyLeft) - subMove(-5, 0, Submarine::kDirectionW); - else if (key == kKeyRight) - subMove( 5, 0, Submarine::kDirectionE); - else if (key == kKeyUp) - subMove( 0, -5, Submarine::kDirectionN); - else if (key == kKeyDown) - subMove( 0, 5, Submarine::kDirectionS); - else if (key == kKeySpace) +void Penetration::handleSub() { + int x, y; + Submarine::Direction direction = getDirection(x, y); + + subMove(x, y, direction); + + if (_keys[kKeySpace]) subShoot(); } @@ -802,6 +831,30 @@ void Penetration::subShoot() { _vm->_sound->blasterPlay(&_soundShoot, 1, 0); } +Submarine::Direction Penetration::getDirection(int &x, int &y) const { + x = _keys[kKeyRight] ? 3 : (_keys[kKeyLeft] ? -3 : 0); + y = _keys[kKeyDown ] ? 3 : (_keys[kKeyUp ] ? -3 : 0); + + if ((x > 0) && (y > 0)) + return Submarine::kDirectionSE; + if ((x > 0) && (y < 0)) + return Submarine::kDirectionNE; + if ((x < 0) && (y > 0)) + return Submarine::kDirectionSW; + if ((x < 0) && (y < 0)) + return Submarine::kDirectionNW; + if (x > 0) + return Submarine::kDirectionE; + if (x < 0) + return Submarine::kDirectionW; + if (y > 0) + return Submarine::kDirectionS; + if (y < 0) + return Submarine::kDirectionN; + + return Submarine::kDirectionNone; +} + void Penetration::checkShields() { for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { if ((pos->x == _sub->x) && (pos->y == _sub->y)) { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 3f03bfaf38..0f36453017 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -94,6 +94,15 @@ private: void setPosition(uint16 pX, uint16 pY); }; + enum Keys { + kKeyUp = 0, + kKeyDown, + kKeyLeft, + kKeyRight, + kKeySpace, + kKeyCount + }; + GobEngine *_vm; bool _hasAccessPass; @@ -102,6 +111,9 @@ private: bool _needFadeIn; + bool _quit; + bool _keys[kKeyCount]; + Surface *_background; CMPFile *_sprites; ANIFile *_objects; @@ -146,12 +158,14 @@ private: void updateAnims(); - int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + void checkInput(); - void handleSub(int16 key); + void handleSub(); void subMove(int x, int y, Submarine::Direction direction); void subShoot(); + Submarine::Direction getDirection(int &x, int &y) const; + bool isWalkable(int16 x, int16 y) const; void checkExits(); diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index 0f3f936ea6..c61f49f22b 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -60,7 +60,7 @@ Submarine::~Submarine() { void Submarine::turn(Direction to) { // Nothing to do - if ((_state == kStateMove) && (_direction == to)) + if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to))) return; _state = kStateMove; diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index d14e4e953b..2455ef95c1 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -33,6 +33,7 @@ namespace Geisha { class Submarine : public ANIObject { public: enum Direction { + kDirectionNone, kDirectionN, kDirectionNE, kDirectionE, -- cgit v1.2.3 From 3d537e763c85bb3f16825c8b47894335568278a0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 04:20:41 +0200 Subject: GOB: Handle Penetration shooting animations more cleverly Still no bullets, though :P --- engines/gob/aniobject.cpp | 4 ++++ engines/gob/aniobject.h | 3 +++ engines/gob/minigames/geisha/penetration.cpp | 2 +- engines/gob/minigames/geisha/submarine.cpp | 27 +++++++++++++++++++++------ engines/gob/minigames/geisha/submarine.h | 5 +++++ 5 files changed, 34 insertions(+), 7 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index 54534cd60b..8d739fb3a4 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -76,6 +76,10 @@ void ANIObject::rewind() { _frame = 0; } +void ANIObject::setFrame(uint16 frame) { + _frame = frame % _ani->getAnimationInfo(_animation).frameCount; +} + void ANIObject::setPosition() { // CMP "animations" have no default position if (_cmp) diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index 5ea1f75401..00f42b43ce 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -84,6 +84,9 @@ public: /** Rewind the current animation to the first frame. */ void rewind(); + /** Set the animation to a specific frame. */ + void setFrame(uint16 frame); + /** Return the current animation number. */ uint16 getAnimation() const; /** Return the current frame number. */ diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 72c53cb5c3..e260d3cae2 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -823,7 +823,7 @@ void Penetration::subMove(int x, int y, Submarine::Direction direction) { } void Penetration::subShoot() { - if (!_sub->sub->canMove()) + if (!_sub->sub->canMove() || _sub->sub->isShooting()) return; _sub->sub->shoot(); diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index c61f49f22b..9c12a56a85 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -51,7 +51,7 @@ enum Animation { }; -Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateNone) { +Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) { turn(kDirectionN); } @@ -63,13 +63,21 @@ void Submarine::turn(Direction to) { if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to))) return; - _state = kStateMove; _direction = to; - setAnimation(directionToMove(_direction)); - setMode(kModeContinuous); + move(); +} + +void Submarine::move() { + uint16 frame = getFrame(); + uint16 anim = (_state == kStateShoot) ? directionToShoot(_direction) : directionToMove(_direction); + + setAnimation(anim); + setFrame(frame); setPause(false); setVisible(true); + + setMode((_state == kStateShoot) ? kModeOnce : kModeContinuous); } void Submarine::shoot() { @@ -104,8 +112,11 @@ void Submarine::advance() { switch (_state) { case kStateShoot: - if (isPaused()) - turn(_direction); + if (isPaused()) { + _state = kStateMove; + + move(); + } break; case kStateExit: @@ -132,6 +143,10 @@ bool Submarine::isDead() const { return _state == kStateDead; } +bool Submarine::isShooting() const { + return _state == kStateShoot; +} + bool Submarine::hasExited() const { return _state == kStateExited; } diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index 2455ef95c1..8a6d679bdd 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -68,6 +68,9 @@ public: /** Is the submarine dead? */ bool isDead() const; + /** Is the submarine shooting? */ + bool isShooting() const; + /** Has the submarine finished exiting the level? */ bool hasExited() const; @@ -91,6 +94,8 @@ private: uint16 directionToShoot(Direction direction) const; /** Map the directions to explode animation indices. */ uint16 directionToExplode(Direction direction) const; + + void move(); }; } // End of namespace Geisha -- cgit v1.2.3 From c37577a950f7337889d5c705c9bc67d434ed3670 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 7 Jun 2012 04:29:10 +0200 Subject: GOB: Hook up the Penetration minigame in the cheater --- engines/gob/cheater.h | 6 ++++-- engines/gob/cheater_geisha.cpp | 11 +++++++++-- engines/gob/inter_geisha.cpp | 2 +- engines/gob/minigames/geisha/penetration.cpp | 18 +++++++++++++++++- engines/gob/minigames/geisha/penetration.h | 5 +++++ 5 files changed, 36 insertions(+), 6 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/cheater.h b/engines/gob/cheater.h index 334a5e88eb..bf6c1372fb 100644 --- a/engines/gob/cheater.h +++ b/engines/gob/cheater.h @@ -31,6 +31,7 @@ namespace Gob { namespace Geisha { class Diving; + class Penetration; } class GobEngine; @@ -48,13 +49,14 @@ protected: class Cheater_Geisha : public Cheater { public: - Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving); + Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving, Geisha::Penetration *penetration); ~Cheater_Geisha(); bool cheat(GUI::Debugger &console); private: - Geisha::Diving *_diving; + Geisha::Diving *_diving; + Geisha::Penetration *_penetration; }; } // End of namespace Gob diff --git a/engines/gob/cheater_geisha.cpp b/engines/gob/cheater_geisha.cpp index 3d8c56707d..567333c12f 100644 --- a/engines/gob/cheater_geisha.cpp +++ b/engines/gob/cheater_geisha.cpp @@ -27,11 +27,12 @@ #include "gob/inter.h" #include "gob/minigames/geisha/diving.h" +#include "gob/minigames/geisha/penetration.h" namespace Gob { -Cheater_Geisha::Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving) : - Cheater(vm), _diving(diving) { +Cheater_Geisha::Cheater_Geisha(GobEngine *vm, Geisha::Diving *diving, Geisha::Penetration *penetration) : + Cheater(vm), _diving(diving), _penetration(penetration) { } @@ -45,6 +46,12 @@ bool Cheater_Geisha::cheat(GUI::Debugger &console) { return false; } + // A cheat to get around the Penetration minigame + if (_penetration->isPlaying()) { + _penetration->cheatWin(); + return false; + } + // A cheat to get around the mastermind puzzle if (_vm->isCurrentTot("hard.tot") && _vm->_inter->_variables) { uint32 digit1 = READ_VARO_UINT32(0x768); diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 99f834d4d7..75204a3f55 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -55,7 +55,7 @@ Inter_Geisha::Inter_Geisha(GobEngine *vm) : Inter_v1(vm), _diving = new Geisha::Diving(vm); _penetration = new Geisha::Penetration(vm); - _cheater = new Cheater_Geisha(vm, _diving); + _cheater = new Cheater_Geisha(vm, _diving, _penetration); _vm->_console->registerCheater(_cheater); } diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index e260d3cae2..9791757984 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -377,7 +377,7 @@ Penetration::ManagedSub::~ManagedSub() { Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), - _shieldMeter(0), _healthMeter(0), _floor(0) { + _shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) { _background = new Surface(320, 200, 1); @@ -404,6 +404,8 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _hasMaxEnergy = hasMaxEnergy; _testMode = testMode; + _isPlaying = true; + init(); initScreen(); @@ -432,9 +434,19 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { deinit(); drawEndText(); + _isPlaying = false; + return hasWon(); } +bool Penetration::isPlaying() const { + return _isPlaying; +} + +void Penetration::cheatWin() { + _floor = 3; +} + void Penetration::init() { // Load sounds _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); @@ -748,6 +760,10 @@ void Penetration::checkInput() { _keys[kKeyRight] = true; else if (event.kbd.keycode == Common::KEYCODE_SPACE) _keys[kKeySpace] = true; + else if (event.kbd.keycode == Common::KEYCODE_d) { + _vm->getDebugger()->attach(); + _vm->getDebugger()->onFrame(); + } break; case Common::EVENT_KEYUP: diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 0f36453017..0336ef8dcb 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -50,6 +50,9 @@ public: bool play(bool hasAccessPass, bool hasMaxEnergy, bool testMode); + bool isPlaying() const; + void cheatWin(); + private: static const int kModeCount = 2; static const int kFloorCount = 3; @@ -141,6 +144,8 @@ private: SoundDesc _soundShoot; SoundDesc _soundExit; + bool _isPlaying; + void init(); void deinit(); -- cgit v1.2.3 From 421b93ce0574b76eeae0ffe0598f1f6858ddf1f1 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 8 Jun 2012 03:11:44 +0200 Subject: GOB: Rewrite "pathfinding" and implement moving enemies Since shooting does not yet work, we're just getting mauled by them... --- engines/gob/minigames/geisha/penetration.cpp | 362 ++++++++++++++++++++++----- engines/gob/minigames/geisha/penetration.h | 77 ++++-- engines/gob/minigames/geisha/submarine.cpp | 3 + 3 files changed, 358 insertions(+), 84 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 9791757984..656e90a45b 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -59,8 +59,12 @@ enum Sprite { }; enum Animation { - kAnimationMouthKiss = 33, - kAnimationMouthBite = 34 + kAnimationEnemyRound = 0, + kAnimationEnemyRoundExplode = 1, + kAnimationEnemySquare = 2, + kAnimationEnemySquareExplode = 3, + kAnimationMouthKiss = 33, + kAnimationMouthBite = 34 }; static const int kMapTileWidth = 24; @@ -353,12 +357,55 @@ static const char *kStrings[kLanguageCount][kStringCount] = { } }; -Penetration::Position::Position(uint16 pX, uint16 pY) : x(pX), y(pY) { + +Penetration::MapObject::MapObject(uint16 tX, uint16 tY, uint16 mX, uint16 mY, uint16 w, uint16 h) : + tileX(tX), tileY(tY), mapX(mX), mapY(mY), width(w), height(h) { + + isBlocking = true; +} + +Penetration::MapObject::MapObject(uint16 tX, uint16 tY, uint16 w, uint16 h) : + tileX(tX), tileY(tY), width(w), height(h) { + + isBlocking = true; + + setMapFromTilePosition(); } +void Penetration::MapObject::setTileFromMapPosition() { + tileX = (mapX + (width / 2)) / kMapTileWidth; + tileY = (mapY + (height / 2)) / kMapTileHeight; +} + +void Penetration::MapObject::setMapFromTilePosition() { + mapX = tileX * kMapTileWidth; + mapY = tileY * kMapTileHeight; +} + +bool Penetration::MapObject::isIn(uint16 mX, uint16 mY) const { + if ((mX < mapX) || (mY < mapY)) + return false; + if ((mX > (mapX + width - 1)) || (mY > (mapY + height - 1))) + return false; + + return true; +} + +bool Penetration::MapObject::isIn(uint16 mX, uint16 mY, uint16 w, uint16 h) const { + return isIn(mX , mY ) || + isIn(mX + w - 1, mY ) || + isIn(mX , mY + h - 1) || + isIn(mX + w - 1, mY + h - 1); +} + +bool Penetration::MapObject::isIn(const MapObject &obj) const { + return isIn(obj.mapX, obj.mapY, obj.width, obj.height); +} + + +Penetration::ManagedMouth::ManagedMouth(uint16 tX, uint16 tY, MouthType t) : + MapObject(tX, tY, 0, 0), mouth(0), type(t) { -Penetration::ManagedMouth::ManagedMouth(uint16 pX, uint16 pY, MouthType t) : - Position(pX, pY), mouth(0), type(t) { } Penetration::ManagedMouth::~ManagedMouth() { @@ -366,9 +413,9 @@ Penetration::ManagedMouth::~ManagedMouth() { } -Penetration::ManagedSub::ManagedSub(uint16 pX, uint16 pY) : Position(pX, pY), sub(0) { - mapX = x * kMapTileWidth; - mapY = y * kMapTileHeight; +Penetration::ManagedSub::ManagedSub(uint16 tX, uint16 tY) : + MapObject(tX, tY, kMapTileWidth, kMapTileHeight), sub(0) { + } Penetration::ManagedSub::~ManagedSub() { @@ -376,6 +423,20 @@ Penetration::ManagedSub::~ManagedSub() { } +Penetration::ManagedEnemy::ManagedEnemy() : MapObject(0, 0, 0, 0), enemy(0), dead(false) { +} + +Penetration::ManagedEnemy::~ManagedEnemy() { + delete enemy; +} + +void Penetration::ManagedEnemy::clear() { + delete enemy; + + enemy = 0; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) { @@ -415,6 +476,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { _vm->_video->retrace(); while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) { + enemiesCreate(); updateAnims(); // Draw, fade in if necessary and wait for the end of the frame @@ -428,6 +490,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Handle the sub movement handleSub(); + // Handle the enemies movement + enemiesMove(); + checkExited(); } @@ -449,11 +514,12 @@ void Penetration::cheatWin() { void Penetration::init() { // Load sounds - _vm->_sound->sampleLoad(&_soundShield, SOUND_SND, "boucl.snd"); - _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); - _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); - _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); - _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); + _vm->_sound->sampleLoad(&_soundShield , SOUND_SND, "boucl.snd"); + _vm->_sound->sampleLoad(&_soundBite , SOUND_SND, "pervet.snd"); + _vm->_sound->sampleLoad(&_soundKiss , SOUND_SND, "baise.snd"); + _vm->_sound->sampleLoad(&_soundShoot , SOUND_SND, "tirgim.snd"); + _vm->_sound->sampleLoad(&_soundExit , SOUND_SND, "trouve.snd"); + _vm->_sound->sampleLoad(&_soundExplode, SOUND_SND, "virmor.snd"); _quit = false; for (int i = 0; i < kKeyCount; i++) @@ -486,6 +552,7 @@ void Penetration::deinit() { _soundKiss.free(); _soundShoot.free(); _soundExit.free(); + _soundExplode.free(); clearMap(); @@ -500,10 +567,16 @@ void Penetration::clearMap() { _mapAnims.clear(); _anims.clear(); + _blockingObjects.clear(); + + _walls.clear(); _exits.clear(); _shields.clear(); _mouths.clear(); + for (int i = 0; i < kEnemyCount; i++) + _enemies[i].clear(); + delete _sub; _sub = 0; @@ -526,13 +599,9 @@ void Penetration::createMap() { for (int x = 0; x < kMapWidth; x++) { const byte mapTile = mapTiles[y * kMapWidth + x]; - bool *walkMap = _walkMap + (y * kMapWidth + x); - const int posX = kPlayAreaBorderWidth + x * kMapTileWidth; const int posY = kPlayAreaBorderHeight + y * kMapTileHeight; - *walkMap = true; - switch (mapTile) { case 0: // Floor _sprites->draw(*_map, kSpriteFloor, posX, posY); @@ -542,18 +611,18 @@ void Penetration::createMap() { exitWorks = _hasAccessPass; if (exitWorks) { - _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); + _exits.push_back(MapObject(x, y, 0, 0)); } else { _sprites->draw(*_map, kSpriteWall, posX, posY); - *walkMap = false; + _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight)); } break; case 50: // Wall _sprites->draw(*_map, kSpriteWall, posX, posY); - *walkMap = false; + _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight)); break; case 51: // Regular exit @@ -563,11 +632,11 @@ void Penetration::createMap() { exitWorks = _testMode || (_floor < 2) || _hasAccessPass; if (exitWorks) { - _exits.push_back(Position(x, y)); _sprites->draw(*_map, kSpriteExit, posX, posY); + _exits.push_back(MapObject(x, y, 0, 0)); } else { _sprites->draw(*_map, kSpriteWall, posX, posY); - *walkMap = false; + _walls.push_back(MapObject(x, y, kMapTileWidth, kMapTileHeight)); } break; @@ -603,7 +672,7 @@ void Penetration::createMap() { _map->fillRect(posX + 4, posY + 8, posX + 7, posY + 18, kColorFloor); // Area left to shield _map->fillRect(posX + 17, posY + 8, posX + 20, posY + 18, kColorFloor); // Area right to shield - _shields.push_back(Position(x, y)); + _shields.push_back(MapObject(x, y, 0, 0)); break; case 57: // Start position @@ -623,10 +692,30 @@ void Penetration::createMap() { if (!_sub) error("Geisha: No starting position in floor %d (testmode: %d)", _floor, _testMode); - for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); m++) + // Walls + for (Common::List::iterator w = _walls.begin(); w != _walls.end(); ++w) + _blockingObjects.push_back(&*w); + + // Mouths + for (Common::List::iterator m = _mouths.begin(); m != _mouths.end(); ++m) _mapAnims.push_back(m->mouth); + // Sub + _blockingObjects.push_back(_sub); _anims.push_back(_sub->sub); + + // Moving enemies + for (int i = 0; i < kEnemyCount; i++) { + _enemies[i].enemy = new ANIObject(*_objects); + + _enemies[i].enemy->setPause(true); + _enemies[i].enemy->setVisible(false); + + _enemies[i].isBlocking = false; + + _blockingObjects.push_back(&_enemies[i]); + _mapAnims.push_back(_enemies[i].enemy); + } } void Penetration::drawFloorText() { @@ -741,6 +830,104 @@ void Penetration::initScreen() { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); } +void Penetration::enemiesCreate() { + for (int i = 0; i < kEnemyCount; i++) { + ManagedEnemy &enemy = _enemies[i]; + + if (enemy.enemy->isVisible()) + continue; + + enemy.enemy->setAnimation((i & 1) ? kAnimationEnemySquare : kAnimationEnemyRound); + enemy.enemy->setMode(ANIObject::kModeContinuous); + enemy.enemy->setPause(false); + enemy.enemy->setVisible(true); + + int16 width, height; + enemy.enemy->getFrameSize(width, height); + + enemy.width = width; + enemy.height = height; + + do { + enemy.mapX = _vm->_util->getRandom(kMapWidth) * kMapTileWidth + 2; + enemy.mapY = _vm->_util->getRandom(kMapHeight) * kMapTileHeight + 4; + enemy.setTileFromMapPosition(); + } while (isBlocked(enemy, enemy.mapX, enemy.mapY)); + + const int posX = kPlayAreaBorderWidth + enemy.mapX; + const int posY = kPlayAreaBorderHeight + enemy.mapY; + + enemy.enemy->setPosition(posX, posY); + + enemy.isBlocking = true; + enemy.dead = false; + } +} + +void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) { + if ((x == 0) && (y == 0)) + return; + + bool touchedSub; + findPath(enemy, x, y, _sub, &touchedSub); + + enemy.setTileFromMapPosition(); + + const int posX = kPlayAreaBorderWidth + enemy.mapX; + const int posY = kPlayAreaBorderHeight + enemy.mapY; + + enemy.enemy->setPosition(posX, posY); + + if (touchedSub) + enemyAttack(enemy); +} + +void Penetration::enemiesMove() { + for (int i = 0; i < kEnemyCount; i++) { + ManagedEnemy &enemy = _enemies[i]; + + if (!enemy.enemy->isVisible() || enemy.dead) + continue; + + int x = 0, y = 0; + + if (enemy.mapX > _sub->mapX) + x = -8; + else if (enemy.mapX < _sub->mapX) + x = 8; + + if (enemy.mapY > _sub->mapY) + y = -8; + else if (enemy.mapY < _sub->mapY) + y = 8; + + enemyMove(enemy, x, y); + } +} + +void Penetration::enemyAttack(ManagedEnemy &enemy) { + // If we have shields, the enemy explodes at them, taking a huge chunk of energy with it. + // Otherwise, the enemy nibbles a small amount of health away. + + if (_shieldMeter->getValue() > 0) { + enemyExplode(enemy); + + healthLose(80); + } else + healthLose(5); +} + +void Penetration::enemyExplode(ManagedEnemy &enemy) { + enemy.dead = true; + + bool isSquare = enemy.enemy->getAnimation() == kAnimationEnemySquare; + + enemy.enemy->setAnimation(isSquare ? kAnimationEnemySquareExplode : kAnimationEnemyRoundExplode); + enemy.enemy->setMode(ANIObject::kModeOnce); + + _vm->_sound->blasterPlay(&_soundExplode, 1, 0); +} + void Penetration::checkInput() { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); @@ -785,13 +972,6 @@ void Penetration::checkInput() { } } -bool Penetration::isWalkable(int16 x, int16 y) const { - if ((x < 0) || (x >= kMapWidth) || (y < 0) || (y >= kMapHeight)) - return false; - - return _walkMap[y * kMapWidth + x]; -} - void Penetration::handleSub() { int x, y; Submarine::Direction direction = getDirection(x, y); @@ -802,34 +982,90 @@ void Penetration::handleSub() { subShoot(); } -void Penetration::subMove(int x, int y, Submarine::Direction direction) { - if (!_sub->sub->canMove()) - return; +bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, + const MapObject *checkBlockedBy, bool *blockedBy) const { - // Limit the movement to walkable tiles + if ((x < 0) || (y < 0)) + return true; + if (((x + self.width - 1) >= (kMapWidth * kMapTileWidth)) || + ((y + self.height - 1) >= (kMapHeight * kMapTileHeight))) + return true; - int16 minX = 0; - if (!isWalkable(_sub->x - 1, _sub->y)) - minX = _sub->x * kMapTileWidth; + MapObject checkSelf(0, 0, self.width, self.height); - int16 maxX = kMapWidth * kMapTileWidth; - if (!isWalkable(_sub->x + 1, _sub->y)) - maxX = _sub->x * kMapTileWidth; + checkSelf.mapX = x; + checkSelf.mapY = y; - int16 minY = 0; - if (!isWalkable(_sub->x, _sub->y - 1)) - minY = _sub->y * kMapTileHeight; + bool blocked = false; + for (Common::List::const_iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) { + const MapObject &obj = **o; - int16 maxY = kMapHeight * kMapTileHeight; - if (!isWalkable(_sub->x, _sub->y + 1)) - maxY = _sub->y * kMapTileHeight; + if (&obj == &self) + continue; - _sub->mapX = CLIP(_sub->mapX + x, minX, maxX); - _sub->mapY = CLIP(_sub->mapY + y, minY, maxY); + if (!obj.isBlocking) + continue; + + if (obj.isIn(checkSelf) || checkSelf.isIn(obj)) { + blocked = true; + + if (checkBlockedBy && blockedBy && (&obj == checkBlockedBy)) + *blockedBy = true; + } + } + + return blocked; +} + +void Penetration::findPath(MapObject &obj, int x, int y, + const MapObject *checkBlockedBy, bool *blockedBy) const { + + if (blockedBy) + *blockedBy = false; + + while ((x != 0) || (y != 0)) { + uint16 oldX = obj.mapX; + uint16 oldY = obj.mapY; + + uint16 newX = obj.mapX; + if (x > 0) { + newX++; + x--; + } else if (x < 0) { + newX--; + x++; + } + + if (!isBlocked(obj, newX, obj.mapY, checkBlockedBy, blockedBy)) + obj.mapX = newX; + + uint16 newY = obj.mapY; + if (y > 0) { + newY++; + y--; + } else if (y < 0) { + newY--; + y++; + } + + if (!isBlocked(obj, obj.mapX, newY, checkBlockedBy, blockedBy)) + obj.mapY = newY; + + if ((obj.mapX == oldX) && (obj.mapY == oldY)) + break; + } +} + +void Penetration::subMove(int x, int y, Submarine::Direction direction) { + if (!_sub->sub->canMove()) + return; - // The tile the sub is on is where its mid-point is - _sub->x = (_sub->mapX + (kMapTileWidth / 2)) / kMapTileWidth; - _sub->y = (_sub->mapY + (kMapTileHeight / 2)) / kMapTileHeight; + if ((x == 0) && (y == 0)) + return; + + findPath(*_sub, x, y); + + _sub->setTileFromMapPosition(); _sub->sub->turn(direction); @@ -872,8 +1108,8 @@ Submarine::Direction Penetration::getDirection(int &x, int &y) const { } void Penetration::checkShields() { - for (Common::List::iterator pos = _shields.begin(); pos != _shields.end(); ++pos) { - if ((pos->x == _sub->x) && (pos->y == _sub->y)) { + for (Common::List::iterator s = _shields.begin(); s != _shields.end(); ++s) { + if ((s->tileX == _sub->tileX) && (s->tileY == _sub->tileY)) { // Charge shields _shieldMeter->setMaxValue(); @@ -881,11 +1117,8 @@ void Penetration::checkShields() { _vm->_sound->blasterPlay(&_soundShield, 1, 0); // Erase the shield from the map - const int mapX = kPlayAreaBorderWidth + pos->x * kMapTileWidth; - const int mapY = kPlayAreaBorderHeight + pos->y * kMapTileHeight; - _sprites->draw(*_map, 30, mapX, mapY); - - _shields.erase(pos); + _sprites->draw(*_map, 30, s->mapX + kPlayAreaBorderWidth, s->mapY + kPlayAreaBorderHeight); + _shields.erase(s); break; } } @@ -896,8 +1129,8 @@ void Penetration::checkMouths() { if (!m->mouth->isDeactivated()) continue; - if ((( m->x == _sub->x) && (m->y == _sub->y)) || - (((m->x + 1) == _sub->x) && (m->y == _sub->y))) { + if ((( m->tileX == _sub->tileX) && (m->tileY == _sub->tileY)) || + (((m->tileX + 1) == _sub->tileX) && (m->tileY == _sub->tileY))) { m->mouth->activate(); @@ -917,10 +1150,9 @@ void Penetration::checkExits() { if (!_sub->sub->canMove()) return; - for (Common::List::iterator e = _exits.begin(); e != _exits.end(); ++e) { - if ((e->x == _sub->x) && (e->y == _sub->y)) { - _sub->mapX = e->x * kMapTileWidth; - _sub->mapY = e->y * kMapTileHeight; + for (Common::List::iterator e = _exits.begin(); e != _exits.end(); ++e) { + if ((e->tileX == _sub->tileX) && (e->tileY == _sub->tileY)) { + _sub->setMapFromTilePosition(); _sub->sub->leave(); diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 0336ef8dcb..9abae258b2 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -65,11 +65,29 @@ private: static const byte kPalettes[kFloorCount][3 * kPaletteSize]; static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; - struct Position { - uint16 x; - uint16 y; + static const int kEnemyCount = 9; - Position(uint16 pX, uint16 pY); + struct MapObject { + uint16 tileX; + uint16 tileY; + + uint16 mapX; + uint16 mapY; + + uint16 width; + uint16 height; + + bool isBlocking; + + MapObject(uint16 tX, uint16 tY, uint16 mX, uint16 mY, uint16 w, uint16 h); + MapObject(uint16 tX, uint16 tY, uint16 w, uint16 h); + + void setTileFromMapPosition(); + void setMapFromTilePosition(); + + bool isIn(uint16 mX, uint16 mY) const; + bool isIn(uint16 mX, uint16 mY, uint16 w, uint16 h) const; + bool isIn(const MapObject &obj) const; }; enum MouthType { @@ -77,24 +95,31 @@ private: kMouthTypeKiss }; - struct ManagedMouth : public Position { + struct ManagedMouth : public MapObject { Mouth *mouth; + MouthType type; - ManagedMouth(uint16 pX, uint16 pY, MouthType t); + ManagedMouth(uint16 tX, uint16 tY, MouthType t); ~ManagedMouth(); }; - struct ManagedSub : public Position { + struct ManagedSub : public MapObject { Submarine *sub; - uint16 mapX; - uint16 mapY; - - ManagedSub(uint16 pX, uint16 pY); + ManagedSub(uint16 tX, uint16 tY); ~ManagedSub(); + }; - void setPosition(uint16 pX, uint16 pY); + struct ManagedEnemy : public MapObject { + ANIObject *enemy; + + bool dead; + + ManagedEnemy(); + ~ManagedEnemy(); + + void clear(); }; enum Keys { @@ -130,19 +155,24 @@ private: uint8 _floor; Surface *_map; - bool _walkMap[kMapWidth * kMapHeight]; ManagedSub *_sub; - Common::List _exits; - Common::List _shields; + Common::List _walls; + Common::List _exits; + Common::List _shields; Common::List _mouths; + ManagedEnemy _enemies[kEnemyCount]; + + Common::List _blockingObjects; + SoundDesc _soundShield; SoundDesc _soundBite; SoundDesc _soundKiss; SoundDesc _soundShoot; SoundDesc _soundExit; + SoundDesc _soundExplode; bool _isPlaying; @@ -161,18 +191,21 @@ private: void drawFloorText(); void drawEndText(); + bool isBlocked(const MapObject &self, int16 x, int16 y, + const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; + void findPath(MapObject &obj, int x, int y, + const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; + void updateAnims(); void checkInput(); + Submarine::Direction getDirection(int &x, int &y) const; + void handleSub(); void subMove(int x, int y, Submarine::Direction direction); void subShoot(); - Submarine::Direction getDirection(int &x, int &y) const; - - bool isWalkable(int16 x, int16 y) const; - void checkExits(); void checkShields(); void checkMouths(); @@ -182,6 +215,12 @@ private: void checkExited(); + void enemiesCreate(); + void enemiesMove(); + void enemyMove(ManagedEnemy &enemy, int x, int y); + void enemyAttack(ManagedEnemy &enemy); + void enemyExplode(ManagedEnemy &enemy); + bool isDead() const; bool hasWon() const; diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index 9c12a56a85..cbe5f21eff 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -90,6 +90,9 @@ void Submarine::shoot() { } void Submarine::die() { + if (!canMove()) + return; + _state = kStateDie; setAnimation(directionToExplode(_direction)); -- cgit v1.2.3 From c414baa35d4cc4b11929d9c4995a1027d16f59e6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 8 Jun 2012 05:16:01 +0200 Subject: GOB: Implement shooting in Penetration Geisha's Penetration minigame should be complete now. This also means that Geisha is now basically complete. The only thing missing is the MDYPlayer, but since the music is only played once during the title screen, and it has a PCM-based fallback (which is currently played), this is low priority. --- engines/gob/minigames/geisha/penetration.cpp | 257 ++++++++++++++++++++++++--- engines/gob/minigames/geisha/penetration.h | 34 +++- engines/gob/minigames/geisha/submarine.cpp | 4 + engines/gob/minigames/geisha/submarine.h | 2 + 4 files changed, 270 insertions(+), 27 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 656e90a45b..3be9f1f651 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -55,7 +55,15 @@ enum Sprite { kSpriteFloor = 30, kSpriteWall = 31, kSpriteMouthBite = 32, - kSpriteMouthKiss = 33 + kSpriteMouthKiss = 33, + kSpriteBulletN = 65, + kSpriteBulletS = 66, + kSpriteBulletW = 67, + kSpriteBulletE = 68, + kSpriteBulletSW = 85, + kSpriteBulletSE = 86, + kSpriteBulletNW = 87, + kSpriteBulletNE = 88 }; enum Animation { @@ -437,6 +445,20 @@ void Penetration::ManagedEnemy::clear() { } +Penetration::ManagedBullet::ManagedBullet() : MapObject(0, 0, 0, 0), bullet(0) { +} + +Penetration::ManagedBullet::~ManagedBullet() { + delete bullet; +} + +void Penetration::ManagedBullet::clear() { + delete bullet; + + bullet = 0; +} + + Penetration::Penetration(GobEngine *vm) : _vm(vm), _background(0), _sprites(0), _objects(0), _sub(0), _shieldMeter(0), _healthMeter(0), _floor(0), _isPlaying(false) { @@ -477,6 +499,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { while (!_vm->shouldQuit() && !_quit && !isDead() && !hasWon()) { enemiesCreate(); + bulletsMove(); updateAnims(); // Draw, fade in if necessary and wait for the end of the frame @@ -494,6 +517,9 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { enemiesMove(); checkExited(); + + if (_shotCoolDown > 0) + _shotCoolDown--; } deinit(); @@ -543,6 +569,8 @@ void Penetration::init() { _floor = 0; + _shotCoolDown = 0; + createMap(); } @@ -576,6 +604,8 @@ void Penetration::clearMap() { for (int i = 0; i < kEnemyCount; i++) _enemies[i].clear(); + for (int i = 0; i < kMaxBulletCount; i++) + _bullets[i].clear(); delete _sub; @@ -716,6 +746,18 @@ void Penetration::createMap() { _blockingObjects.push_back(&_enemies[i]); _mapAnims.push_back(_enemies[i].enemy); } + + // Bullets + for (int i = 0; i < kMaxBulletCount; i++) { + _bullets[i].bullet = new ANIObject(*_sprites); + + _bullets[i].bullet->setPause(true); + _bullets[i].bullet->setVisible(false); + + _bullets[i].isBlocking = false; + + _mapAnims.push_back(_bullets[i].bullet); + } } void Penetration::drawFloorText() { @@ -868,8 +910,8 @@ void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) { if ((x == 0) && (y == 0)) return; - bool touchedSub; - findPath(enemy, x, y, _sub, &touchedSub); + MapObject *blockedBy; + findPath(enemy, x, y, &blockedBy); enemy.setTileFromMapPosition(); @@ -878,7 +920,7 @@ void Penetration::enemyMove(ManagedEnemy &enemy, int x, int y) { enemy.enemy->setPosition(posX, posY); - if (touchedSub) + if (blockedBy == _sub) enemyAttack(enemy); } @@ -918,7 +960,8 @@ void Penetration::enemyAttack(ManagedEnemy &enemy) { } void Penetration::enemyExplode(ManagedEnemy &enemy) { - enemy.dead = true; + enemy.dead = true; + enemy.isBlocking = false; bool isSquare = enemy.enemy->getAnimation() == kAnimationEnemySquare; @@ -982,8 +1025,7 @@ void Penetration::handleSub() { subShoot(); } -bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, - const MapObject *checkBlockedBy, bool *blockedBy) const { +bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, MapObject **blockedBy) { if ((x < 0) || (y < 0)) return true; @@ -996,9 +1038,8 @@ bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, checkSelf.mapX = x; checkSelf.mapY = y; - bool blocked = false; - for (Common::List::const_iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) { - const MapObject &obj = **o; + for (Common::List::iterator o = _blockingObjects.begin(); o != _blockingObjects.end(); ++o) { + MapObject &obj = **o; if (&obj == &self) continue; @@ -1007,21 +1048,19 @@ bool Penetration::isBlocked(const MapObject &self, int16 x, int16 y, continue; if (obj.isIn(checkSelf) || checkSelf.isIn(obj)) { - blocked = true; + if (blockedBy && !*blockedBy) + *blockedBy = &obj; - if (checkBlockedBy && blockedBy && (&obj == checkBlockedBy)) - *blockedBy = true; + return true; } } - return blocked; + return false; } -void Penetration::findPath(MapObject &obj, int x, int y, - const MapObject *checkBlockedBy, bool *blockedBy) const { - +void Penetration::findPath(MapObject &obj, int x, int y, MapObject **blockedBy) { if (blockedBy) - *blockedBy = false; + *blockedBy = 0; while ((x != 0) || (y != 0)) { uint16 oldX = obj.mapX; @@ -1036,7 +1075,7 @@ void Penetration::findPath(MapObject &obj, int x, int y, x++; } - if (!isBlocked(obj, newX, obj.mapY, checkBlockedBy, blockedBy)) + if (!isBlocked(obj, newX, obj.mapY, blockedBy)) obj.mapX = newX; uint16 newY = obj.mapY; @@ -1048,7 +1087,7 @@ void Penetration::findPath(MapObject &obj, int x, int y, y++; } - if (!isBlocked(obj, obj.mapX, newY, checkBlockedBy, blockedBy)) + if (!isBlocked(obj, obj.mapX, newY, blockedBy)) obj.mapY = newY; if ((obj.mapX == oldX) && (obj.mapY == oldY)) @@ -1078,9 +1117,185 @@ void Penetration::subShoot() { if (!_sub->sub->canMove() || _sub->sub->isShooting()) return; - _sub->sub->shoot(); + if (_shotCoolDown > 0) + return; + + // Creating a bullet + int slot = findEmptyBulletSlot(); + if (slot < 0) + return; + + ManagedBullet &bullet = _bullets[slot]; + bullet.bullet->setAnimation(directionToBullet(_sub->sub->getDirection())); + + setBulletPosition(*_sub, bullet); + + const int posX = kPlayAreaBorderWidth + bullet.mapX; + const int posY = kPlayAreaBorderHeight + bullet.mapY; + + bullet.bullet->setPosition(posX, posY); + bullet.bullet->setVisible(true); + + // Shooting + _sub->sub->shoot(); _vm->_sound->blasterPlay(&_soundShoot, 1, 0); + + _shotCoolDown = 3; +} + +void Penetration::setBulletPosition(const ManagedSub &sub, ManagedBullet &bullet) const { + bullet.mapX = sub.mapX; + bullet.mapY= sub.mapY; + + int16 sWidth, sHeight; + sub.sub->getFrameSize(sWidth, sHeight); + + int16 bWidth, bHeight; + bullet.bullet->getFrameSize(bWidth, bHeight); + + switch (sub.sub->getDirection()) { + case Submarine::kDirectionN: + bullet.mapX += sWidth / 2; + bullet.mapY -= bHeight; + + bullet.deltaX = 0; + bullet.deltaY = -8; + break; + + case Submarine::kDirectionNE: + bullet.mapX += sWidth; + bullet.mapY -= bHeight * 2; + + bullet.deltaX = 8; + bullet.deltaY = -8; + break; + + case Submarine::kDirectionE: + bullet.mapX += sWidth; + bullet.mapY += sHeight / 2 - bHeight; + + bullet.deltaX = 8; + bullet.deltaY = 0; + break; + + case Submarine::kDirectionSE: + bullet.mapX += sWidth; + bullet.mapY += sHeight; + + bullet.deltaX = 8; + bullet.deltaY = 8; + break; + + case Submarine::kDirectionS: + bullet.mapX += sWidth / 2; + bullet.mapY += sHeight; + + bullet.deltaX = 0; + bullet.deltaY = 8; + break; + + case Submarine::kDirectionSW: + bullet.mapX -= bWidth; + bullet.mapY += sHeight; + + bullet.deltaX = -8; + bullet.deltaY = 8; + break; + + case Submarine::kDirectionW: + bullet.mapX -= bWidth; + bullet.mapY += sHeight / 2 - bHeight; + + bullet.deltaX = -8; + bullet.deltaY = 0; + break; + + case Submarine::kDirectionNW: + bullet.mapX -= bWidth; + bullet.mapY -= bHeight; + + bullet.deltaX = -8; + bullet.deltaY = -8; + break; + + default: + break; + } +} + +uint16 Penetration::directionToBullet(Submarine::Direction direction) const { + switch (direction) { + case Submarine::kDirectionN: + return kSpriteBulletN; + + case Submarine::kDirectionNE: + return kSpriteBulletNE; + + case Submarine::kDirectionE: + return kSpriteBulletE; + + case Submarine::kDirectionSE: + return kSpriteBulletSE; + + case Submarine::kDirectionS: + return kSpriteBulletS; + + case Submarine::kDirectionSW: + return kSpriteBulletSW; + + case Submarine::kDirectionW: + return kSpriteBulletW; + + case Submarine::kDirectionNW: + return kSpriteBulletNW; + + default: + break; + } + + return 0; +} + +int Penetration::findEmptyBulletSlot() const { + for (int i = 0; i < kMaxBulletCount; i++) + if (!_bullets[i].bullet->isVisible()) + return i; + + return -1; +} + +void Penetration::bulletsMove() { + for (int i = 0; i < kMaxBulletCount; i++) + if (_bullets[i].bullet->isVisible()) + bulletMove(_bullets[i]); +} + +void Penetration::bulletMove(ManagedBullet &bullet) { + MapObject *blockedBy; + findPath(bullet, bullet.deltaX, bullet.deltaY, &blockedBy); + + if (blockedBy) { + checkShotEnemy(*blockedBy); + bullet.bullet->setVisible(false); + return; + } + + const int posX = kPlayAreaBorderWidth + bullet.mapX; + const int posY = kPlayAreaBorderHeight + bullet.mapY; + + bullet.bullet->setPosition(posX, posY); +} + +void Penetration::checkShotEnemy(MapObject &shotObject) { + for (int i = 0; i < kEnemyCount; i++) { + ManagedEnemy &enemy = _enemies[i]; + + if ((&enemy == &shotObject) && !enemy.dead && enemy.enemy->isVisible()) { + enemyExplode(enemy); + return; + } + } } Submarine::Direction Penetration::getDirection(int &x, int &y) const { diff --git a/engines/gob/minigames/geisha/penetration.h b/engines/gob/minigames/geisha/penetration.h index 9abae258b2..50004eba8e 100644 --- a/engines/gob/minigames/geisha/penetration.h +++ b/engines/gob/minigames/geisha/penetration.h @@ -65,7 +65,8 @@ private: static const byte kPalettes[kFloorCount][3 * kPaletteSize]; static const byte kMaps[kModeCount][kFloorCount][kMapWidth * kMapHeight]; - static const int kEnemyCount = 9; + static const int kEnemyCount = 9; + static const int kMaxBulletCount = 10; struct MapObject { uint16 tileX; @@ -122,6 +123,18 @@ private: void clear(); }; + struct ManagedBullet : public MapObject { + ANIObject *bullet; + + int16 deltaX; + int16 deltaY; + + ManagedBullet(); + ~ManagedBullet(); + + void clear(); + }; + enum Keys { kKeyUp = 0, kKeyDown, @@ -163,10 +176,13 @@ private: Common::List _shields; Common::List _mouths; - ManagedEnemy _enemies[kEnemyCount]; + ManagedEnemy _enemies[kEnemyCount]; + ManagedBullet _bullets[kMaxBulletCount]; Common::List _blockingObjects; + uint8 _shotCoolDown; + SoundDesc _soundShield; SoundDesc _soundBite; SoundDesc _soundKiss; @@ -191,10 +207,8 @@ private: void drawFloorText(); void drawEndText(); - bool isBlocked(const MapObject &self, int16 x, int16 y, - const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; - void findPath(MapObject &obj, int x, int y, - const MapObject *checkBlockedBy = 0, bool *blockedBy = 0) const; + bool isBlocked(const MapObject &self, int16 x, int16 y, MapObject **blockedBy = 0); + void findPath(MapObject &obj, int x, int y, MapObject **blockedBy = 0); void updateAnims(); @@ -206,6 +220,14 @@ private: void subMove(int x, int y, Submarine::Direction direction); void subShoot(); + int findEmptyBulletSlot() const; + uint16 directionToBullet(Submarine::Direction direction) const; + void setBulletPosition(const ManagedSub &sub, ManagedBullet &bullet) const; + + void bulletsMove(); + void bulletMove(ManagedBullet &bullet); + void checkShotEnemy(MapObject &shotObject); + void checkExits(); void checkShields(); void checkMouths(); diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index cbe5f21eff..d16761cb7c 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -58,6 +58,10 @@ Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) { Submarine::~Submarine() { } +Submarine::Direction Submarine::getDirection() const { + return _direction; +} + void Submarine::turn(Direction to) { // Nothing to do if ((to == kDirectionNone) || ((_state == kStateMove) && (_direction == to))) diff --git a/engines/gob/minigames/geisha/submarine.h b/engines/gob/minigames/geisha/submarine.h index 8a6d679bdd..a6eae57095 100644 --- a/engines/gob/minigames/geisha/submarine.h +++ b/engines/gob/minigames/geisha/submarine.h @@ -47,6 +47,8 @@ public: Submarine(const ANIFile &ani); ~Submarine(); + Direction getDirection() const; + /** Turn to the specified direction. */ void turn(Direction to); -- cgit v1.2.3 From 03ef6689c015742c192d5d92d936e60d638caa1c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 9 Jun 2012 10:38:55 +0200 Subject: GOB: Rewrite the AdLib players This is a complete rewrite of the AdLib players for ADL and MDY/TBR files in the Gob engine. Major changes 1) The AdLib base class is now completely separated from all file format code and can theoretically be used by any OPL2-based format (within reason) 2) The new code is far better documented and more readable 3) The MDY player now actually works. The MDY/TBR format is in reality the MUS/SND format created by AdLib as a simpler alternative to the ROL format 4) Since the MAME emulator is quite buggy and leads to noticable wrong percussion in the Gobliins 2 title music, the new AdLib player will try to create a DOSBox OPL. If it's not compiled in, or if the user configured opl_driver to "mame", it will print out appropriate warnings. --- engines/gob/module.mk | 2 + engines/gob/sound/adlib.cpp | 1038 +++++++++++++++++---------------------- engines/gob/sound/adlib.h | 317 ++++++++---- engines/gob/sound/adlplayer.cpp | 257 ++++++++++ engines/gob/sound/adlplayer.h | 85 ++++ engines/gob/sound/musplayer.cpp | 391 +++++++++++++++ engines/gob/sound/musplayer.h | 109 ++++ engines/gob/sound/sound.cpp | 41 +- engines/gob/sound/sound.h | 17 +- 9 files changed, 1545 insertions(+), 712 deletions(-) create mode 100644 engines/gob/sound/adlplayer.cpp create mode 100644 engines/gob/sound/adlplayer.h create mode 100644 engines/gob/sound/musplayer.cpp create mode 100644 engines/gob/sound/musplayer.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index b9680fad6b..7c5d7de158 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -103,6 +103,8 @@ MODULE_OBJS := \ sound/sounddesc.o \ sound/pcspeaker.o \ sound/adlib.o \ + sound/musplayer.o \ + sound/adlplayer.o \ sound/infogrames.o \ sound/protracker.o \ sound/soundmixer.o \ diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index f1ab2a2d79..3f46f6cf4b 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -20,771 +20,615 @@ * */ -#include "common/debug.h" -#include "common/file.h" -#include "common/endian.h" +#include "common/util.h" #include "common/textconsole.h" +#include "common/debug.h" +#include "common/config-manager.h" + +#include "audio/fmopl.h" #include "gob/gob.h" #include "gob/sound/adlib.h" namespace Gob { -const unsigned char AdLib::_operators[] = {0, 1, 2, 8, 9, 10, 16, 17, 18}; -const unsigned char AdLib::_volRegNums[] = { - 3, 4, 5, - 11, 12, 13, - 19, 20, 21 +static const int kPitchTom = 24; +static const int kPitchTomToSnare = 7; +static const int kPitchSnareDrum = kPitchTom + kPitchTomToSnare; + + +// Is the operator a modulator (0) or a carrier (1)? +const uint8 AdLib::kOperatorType[kOperatorCount] = { + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 +}; + +// Operator number to register offset on the OPL +const uint8 AdLib::kOperatorOffset[kOperatorCount] = { + 0, 1, 2, 3, 4, 5, + 8, 9, 10, 11, 12, 13, + 16, 17, 18, 19, 20, 21 +}; + +// For each operator, the voice it belongs to +const uint8 AdLib::kOperatorVoice[kOperatorCount] = { + 0, 1, 2, + 0, 1, 2, + 3, 4, 5, + 3, 4, 5, + 6, 7, 8, + 6, 7, 8, +}; + +// Voice to operator set, for the 9 melodyvoices (only 6 useable in percussion mode) +const uint8 AdLib::kVoiceMelodyOperator[kOperatorsPerVoice][kMelodyVoiceCount] = { + {0, 1, 2, 6, 7, 8, 12, 13, 14}, + {3, 4, 5, 9, 10, 11, 15, 16, 17} }; -AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer) { - init(); +// Voice to operator set, for the 5 percussion voices (only useable in percussion mode) +const uint8 AdLib::kVoicePercussionOperator[kOperatorsPerVoice][kPercussionVoiceCount] = { + {12, 16, 14, 17, 13}, + {15, 0, 0, 0, 0} +}; + +// Mask bits to set each percussion instrument on/off +const byte AdLib::kPercussionMasks[kPercussionVoiceCount] = {0x10, 0x08, 0x04, 0x02, 0x01}; + +// Default instrument presets +const uint16 AdLib::kPianoParams [kOperatorsPerVoice][kParamCount] = { + { 1, 1, 3, 15, 5, 0, 1, 3, 15, 0, 0, 0, 1, 0}, + { 0, 1, 1, 15, 7, 0, 2, 4, 0, 0, 0, 1, 0, 0} }; +const uint16 AdLib::kBaseDrumParams[kOperatorsPerVoice][kParamCount] = { + { 0, 0, 0, 10, 4, 0, 8, 12, 11, 0, 0, 0, 1, 0 }, + { 0, 0, 0, 13, 4, 0, 6, 15, 0, 0, 0, 0, 1, 0 } }; +const uint16 AdLib::kSnareDrumParams[kParamCount] = { + 0, 12, 0, 15, 11, 0, 8, 5, 0, 0, 0, 0, 0, 0 }; +const uint16 AdLib::kTomParams [kParamCount] = { + 0, 4, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 }; +const uint16 AdLib::kCymbalParams [kParamCount] = { + 0, 1, 0, 15, 11, 0, 5, 5, 0, 0, 0, 0, 0, 0 }; +const uint16 AdLib::kHihatParams [kParamCount] = { + 0, 1, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 }; + + +AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0), + _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true) { + + _rate = _mixer->getOutputRate(); + + createOPL(); + initOPL(); + + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, + this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); } AdLib::~AdLib() { - Common::StackLock slock(_mutex); - _mixer->stopHandle(_handle); - OPLDestroy(_opl); - if (_data && _freeData) - delete[] _data; + + delete _opl; } -void AdLib::init() { - _index = -1; - _data = 0; - _playPos = 0; - _dataSize = 0; +// Creates the OPL. Try to use the DOSBox emulator, unless that one is not compiled in, +// or the user explicitly wants the MAME emulator. The MAME one is slightly buggy, leading +// to some wrong sounds, especially noticeable in the title music of Gobliins 2, so we +// really don't want to use it, if we can help it. +void AdLib::createOPL() { + Common::String oplDriver = ConfMan.get("opl_driver"); - _rate = _mixer->getOutputRate(); + if (oplDriver.empty() || (oplDriver == "auto") || (OPL::Config::parse(oplDriver) == -1)) { + // User has selected OPL driver auto detection or an invalid OPL driver. + // Set it to our preferred driver (DOSBox), if we can. - _opl = makeAdLibOPL(_rate); + if (OPL::Config::parse("db") <= 0) { + warning("The DOSBox AdLib emulator is not compiled in. Please keep in mind that the MAME one is buggy"); + } else + oplDriver = "db"; - _first = true; - _ended = false; - _playing = false; + } else if (oplDriver == "mame") { + // User has selected the MAME OPL driver. It is buggy, so warn the user about that. - _freeData = false; - - _repCount = -1; - _samplesTillPoll = 0; + warning("You have selected the MAME AdLib emulator. It is buggy; AdLib music might be slightly glitchy now"); + } - for (int i = 0; i < 16; i ++) - _pollNotes[i] = 0; - setFreqs(); + _opl = OPL::Config::create(OPL::Config::parse(oplDriver), OPL::Config::kOpl2); + if (!_opl || !_opl->init(_rate)) { + delete _opl; - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, - this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + error("Could not create an AdLib emulator"); + } } int AdLib::readBuffer(int16 *buffer, const int numSamples) { Common::StackLock slock(_mutex); - int samples; - int render; - if (!_playing || (numSamples < 0)) { - memset(buffer, 0, numSamples * sizeof(int16)); - return numSamples; - } - if (_first) { + // Nothing to do, fill with silence + if (!_playing) { memset(buffer, 0, numSamples * sizeof(int16)); - pollMusic(); return numSamples; } - samples = numSamples; + // Read samples from the OPL, polling in more music when necessary + uint32 samples = numSamples; while (samples && _playing) { - if (_samplesTillPoll) { - render = (samples > _samplesTillPoll) ? (_samplesTillPoll) : (samples); + if (_toPoll) { + const uint32 render = MIN(samples, _toPoll); + + _opl->readBuffer(buffer, render); + + buffer += render; samples -= render; - _samplesTillPoll -= render; - YM3812UpdateOne(_opl, buffer, render); - buffer += render; + _toPoll -= render; + } else { - pollMusic(); + // Song ended, fill the rest with silence if (_ended) { memset(buffer, 0, samples * sizeof(int16)); samples = 0; + break; } + + // Poll more music + _toPoll = pollMusic(_first); + _first = false; } } + // Song ended, loop if requested if (_ended) { - _first = true; - _ended = false; + _toPoll = 0; - rewind(); + // _repCount == 0: No looping (anymore); _repCount < 0: Infinite looping + if (_repCount != 0) { + if (_repCount > 0) + _repCount--; + + _first = true; + _ended = false; - _samplesTillPoll = 0; - if (_repCount == -1) { - reset(); - setVoices(); - } else if (_repCount > 0) { - _repCount--; reset(); - setVoices(); - } - else + rewind(); + } else _playing = false; } - return numSamples; -} - -void AdLib::writeOPL(byte reg, byte val) { - debugC(6, kDebugSound, "AdLib::writeOPL (%02X, %02X)", reg, val); - OPLWriteReg(_opl, reg, val); -} -void AdLib::setFreqs() { - byte lin; - byte col; - long val = 0; - - // Run through the 11 channels - for (lin = 0; lin < 11; lin ++) { - _notes[lin] = 0; - _notCol[lin] = 0; - _notLin[lin] = 0; - _notOn[lin] = false; - } - - // Run through the 25 lines - for (lin = 0; lin < 25; lin ++) { - // Run through the 12 columns - for (col = 0; col < 12; col ++) { - if (!col) - val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) * - 9 / 0x1B503; - _freqs[lin][col] = (short)((val + 4) >> 3); - val = val * 0x6A / 0x64; - } - } + return numSamples; } -void AdLib::reset() { - _first = true; - OPLResetChip(_opl); - _samplesTillPoll = 0; - - setFreqs(); - // Set frequencies and octave to 0; notes off - for (int i = 0; i < 9; i++) { - writeOPL(0xA0 | i, 0); - writeOPL(0xB0 | i, 0); - writeOPL(0xE0 | _operators[i] , 0); - writeOPL(0xE0 |(_operators[i] + 3), 0); - } - - // Authorize the control of the waveformes - writeOPL(0x01, 0x20); -} - -void AdLib::setKey(byte voice, byte note, bool on, bool spec) { - short freq = 0; - short octa = 0; - - // Instruction AX - if (spec) { - // 0x7F donne 0x16B; - // 7F - // << 7 = 3F80 - // + E000 = 11F80 - // & FFFF = 1F80 - // * 19 = 31380 - // / 2000 = 18 => Ligne 18h, colonne 0 => freq 16B - - // 0x3A donne 0x2AF; - // 3A - // << 7 = 1D00 - // + E000 = FD00 negatif - // * 19 = xB500 - // / 2000 = -2 => Ligne 17h, colonne -1 - - // 2E - // << 7 = 1700 - // + E000 = F700 negatif - // * 19 = x1F00 - // / 2000 = - short a; - short lin; - short col; - - a = (note << 7) + 0xE000; // Volontairement tronque - a = (short)((long)a * 25 / 0x2000); - if (a < 0) { - col = - ((24 - a) / 25); - lin = (-a % 25); - if (lin) - lin = 25 - lin; - } - else { - col = a / 25; - lin = a % 25; - } - - _notCol[voice] = col; - _notLin[voice] = lin; - note = _notes[voice]; - } - // Instructions 0X 9X 8X - else { - note -= 12; - _notOn[voice] = on; - } - - _notes[voice] = note; - note += _notCol[voice]; - note = MIN((byte) 0x5F, note); - octa = note / 12; - freq = _freqs[_notLin[voice]][note - octa * 12]; - - writeOPL(0xA0 + voice, freq & 0xFF); - writeOPL(0xB0 + voice, (freq >> 8) | (octa << 2) | (0x20 * (on ? 1 : 0))); - - if (!freq) - warning("AdLib::setKey Voice %d, note %02X unknown", voice, note); +bool AdLib::isStereo() const { + return _opl->isStereo(); } -void AdLib::setVolume(byte voice, byte volume) { - debugC(6, kDebugSound, "AdLib::setVolume(%d, %d)", voice, volume); - //assert(voice >= 0 && voice <= 9); - volume = 0x3F - ((volume * 0x7E) + 0x7F) / 0xFE; - writeOPL(0x40 + _volRegNums[voice], volume); +bool AdLib::endOfData() const { + return !_playing; } -void AdLib::pollMusic() { - if ((_playPos > (_data + _dataSize)) && (_dataSize != 0xFFFFFFFF)) { - _ended = true; - return; - } - - interpret(); +bool AdLib::endOfStream() const { + return false; } -void AdLib::unload() { - _playing = false; - _index = -1; - - if (_data && _freeData) - delete[] _data; - - _freeData = false; +int AdLib::getRate() const { + return _rate; } bool AdLib::isPlaying() const { return _playing; } -bool AdLib::getRepeating() const { - return _repCount != 0; +int32 AdLib::getRepeating() const { + Common::StackLock slock(_mutex); + + return _repCount; } void AdLib::setRepeating(int32 repCount) { + Common::StackLock slock(_mutex); + _repCount = repCount; } -int AdLib::getIndex() const { - return _index; +uint32 AdLib::getSamplesPerSecond() const { + return _rate * (isStereo() ? 2 : 1); } void AdLib::startPlay() { - if (_data) _playing = true; + Common::StackLock slock(_mutex); + + _playing = true; + _ended = false; + _first = true; + + reset(); + rewind(); } void AdLib::stopPlay() { Common::StackLock slock(_mutex); + + end(true); + _playing = false; } -ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer) { -} +void AdLib::writeOPL(byte reg, byte val) { + debugC(6, kDebugSound, "AdLib::writeOPL (%02X, %02X)", reg, val); -ADLPlayer::~ADLPlayer() { + _opl->writeReg(reg, val); } -bool ADLPlayer::load(const char *fileName) { - Common::File song; +void AdLib::reset() { + allOff(); + initOPL(); +} - unload(); - song.open(fileName); - if (!song.isOpen()) - return false; +void AdLib::allOff() { + // NOTE: Explicit casts are necessary, because of 5.16 paragraph 4 of the C++ standard + int numVoices = isPercussionMode() ? (int)kMaxVoiceCount : (int)kMelodyVoiceCount; - _freeData = true; - _dataSize = song.size(); - _data = new byte[_dataSize]; - song.read(_data, _dataSize); - song.close(); + for (int i = 0; i < numVoices; i++) + noteOff(i); +} +void AdLib::end(bool killRepeat) { reset(); - setVoices(); - _playPos = _data + 3 + (_data[1] + 1) * 0x38; - return true; + _ended = true; + + if (killRepeat) + _repCount = 0; } -bool ADLPlayer::load(byte *data, uint32 size, int index) { - unload(); - _repCount = 0; +void AdLib::initOPL() { + _tremoloDepth = false; + _vibratoDepth = false; + _keySplit = false; - _dataSize = size; - _data = data; - _index = index; + _enableWaveSelect = true; - reset(); - setVoices(); - _playPos = _data + 3 + (_data[1] + 1) * 0x38; + for (int i = 0; i < kMaxVoiceCount; i++) { + _voiceNote[i] = 0; + _voiceOn [i] = 0; + } + + _opl->reset(); + + initOperatorVolumes(); + initFreqs(); + + setPercussionMode(false); + + setTremoloDepth(false); + setVibratoDepth(false); + setKeySplit(false); - return true; + for(int i = 0; i < kMelodyVoiceCount; i++) + voiceOff(i); + + setPitchRange(1); + + enableWaveSelect(true); } -void ADLPlayer::unload() { - AdLib::unload(); +bool AdLib::isPercussionMode() const { + return _percussionMode; } -void ADLPlayer::interpret() { - unsigned char instr; - byte channel; - byte note; - byte volume; - uint16 tempo; +void AdLib::setPercussionMode(bool percussion) { + if (percussion) { + voiceOff(kVoiceBaseDrum); + voiceOff(kVoiceSnareDrum); + voiceOff(kVoiceTom); - // First tempo, we'll ignore it... - if (_first) { - tempo = *(_playPos++); - // Tempo on 2 bytes - if (tempo & 0x80) - tempo = ((tempo & 3) << 8) | *(_playPos++); - } - _first = false; - - // Instruction - instr = *(_playPos++); - channel = instr & 0x0F; - - switch (instr & 0xF0) { - // Note on + Volume - case 0x00: - note = *(_playPos++); - _pollNotes[channel] = note; - setVolume(channel, *(_playPos++)); - setKey(channel, note, true, false); - break; - // Note on - case 0x90: - note = *(_playPos++); - _pollNotes[channel] = note; - setKey(channel, note, true, false); - break; - // Last note off - case 0x80: - note = _pollNotes[channel]; - setKey(channel, note, false, false); - break; - // Frequency on/off - case 0xA0: - note = *(_playPos++); - setKey(channel, note, _notOn[channel], true); - break; - // Volume - case 0xB0: - volume = *(_playPos++); - setVolume(channel, volume); - break; - // Program change - case 0xC0: - setVoice(channel, *(_playPos++), false); - break; - // Special - case 0xF0: - switch (instr & 0x0F) { - case 0xF: // End instruction - _ended = true; - _samplesTillPoll = 0; - return; - default: - warning("ADLPlayer: Unknown special command %X, stopping playback", - instr & 0x0F); - _repCount = 0; - _ended = true; - break; - } - break; - default: - warning("ADLPlayer: Unknown command %X, stopping playback", - instr & 0xF0); - _repCount = 0; - _ended = true; - break; + /* set the frequency for the last 4 percussion voices: */ + setFreq(kVoiceTom, kPitchTom, 0); + setFreq(kVoiceSnareDrum, kPitchSnareDrum, 0); } - // Temporization - tempo = *(_playPos++); - // End tempo - if (tempo == 0xFF) { - _ended = true; - return; - } - // Tempo on 2 bytes - if (tempo & 0x80) - tempo = ((tempo & 3) << 8) | *(_playPos++); - if (!tempo) - tempo ++; + _percussionMode = percussion; + _percussionBits = 0; - _samplesTillPoll = tempo * (_rate / 1000); + initOperatorParams(); + writeTremoloVibratoDepthPercMode(); } -void ADLPlayer::reset() { - AdLib::reset(); +void AdLib::enableWaveSelect(bool enable) { + _enableWaveSelect = enable; + + for (int i = 0; i < kOperatorCount; i++) + writeOPL(0xE0 + kOperatorOffset[i], 0); + + writeOPL(0x011, _enableWaveSelect ? 0x20 : 0); } -void ADLPlayer::rewind() { - _playPos = _data + 3 + (_data[1] + 1) * 0x38; +void AdLib::setPitchRange(uint8 range) { + _pitchRange = CLIP(range, 0, 12); + _pitchRangeStep = _pitchRange * kPitchStepCount; } -void ADLPlayer::setVoices() { - // Definitions of the 9 instruments - for (int i = 0; i < 9; i++) - setVoice(i, i, true); +void AdLib::setTremoloDepth(bool tremoloDepth) { + _tremoloDepth = tremoloDepth; + + writeTremoloVibratoDepthPercMode(); } -void ADLPlayer::setVoice(byte voice, byte instr, bool set) { - uint16 strct[27]; - byte channel; - byte *dataPtr; +void AdLib::setVibratoDepth(bool vibratoDepth) { + _vibratoDepth = vibratoDepth; - // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 - // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 - for (int i = 0; i < 2; i++) { - dataPtr = _data + 3 + instr * 0x38 + i * 0x1A; - for (int j = 0; j < 27; j++) { - strct[j] = READ_LE_UINT16(dataPtr); - dataPtr += 2; - } - channel = _operators[voice] + i * 3; - writeOPL(0xBD, 0x00); - writeOPL(0x08, 0x00); - writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); - if (!i) - writeOPL(0xC0 | voice, - ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); - writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); - writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); - writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | - ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | - ((strct[11] & 1) << 4) | (strct[1] & 0xF)); - if (!i) - writeOPL(0xE0 | channel, (strct[26] & 3)); - else - writeOPL(0xE0 | channel, (strct[14] & 3)); - if (i && set) - writeOPL(0x40 | channel, 0); + writeTremoloVibratoDepthPercMode(); +} + +void AdLib::setKeySplit(bool keySplit) { + _keySplit = keySplit; + + writeKeySplit(); +} + +void AdLib::setVoiceTimbre(uint8 voice, const uint16 *params) { + const uint16 *params0 = params; + const uint16 *params1 = params + kParamCount - 1; + const uint16 *waves = params + 2 * (kParamCount - 1); + + const int voicePerc = voice - kVoiceBaseDrum; + + if (!isPercussionMode() || (voice < kVoiceBaseDrum)) { + setOperatorParams(kVoiceMelodyOperator[0][voice], params0, waves[0]); + setOperatorParams(kVoiceMelodyOperator[1][voice], params1, waves[1]); + } else if (voice == kVoiceBaseDrum) { + setOperatorParams(kVoicePercussionOperator[0][voicePerc], params0, waves[0]); + setOperatorParams(kVoicePercussionOperator[1][voicePerc], params1, waves[1]); + } else { + setOperatorParams(kVoicePercussionOperator[0][voicePerc], params0, waves[0]); } } +void AdLib::setVoiceVolume(uint8 voice, uint8 volume) { + int oper; + + const int voicePerc = voice - kVoiceBaseDrum; + + if (!isPercussionMode() || (voice < kVoiceBaseDrum)) + oper = kVoiceMelodyOperator[1][ voice]; + else + oper = kVoicePercussionOperator[voice == kVoiceBaseDrum ? 1 : 0][voicePerc]; -MDYPlayer::MDYPlayer(Audio::Mixer &mixer) : AdLib(mixer) { - init(); + _operatorVolume[oper] = MIN(volume, kMaxVolume); + writeKeyScaleLevelVolume(oper); } -MDYPlayer::~MDYPlayer() { +void AdLib::bendVoicePitch(uint8 voice, uint16 pitchBend) { + if (isPercussionMode() && (voice > kVoiceBaseDrum)) + return; + + changePitch(voice, MIN(pitchBend, kMaxPitch)); + setFreq(voice, _voiceNote[voice], _voiceOn[voice]); } -void MDYPlayer::init() { - _soundMode = 0; +void AdLib::noteOn(uint8 voice, uint8 note) { + note = MAX(0, note - (kStandardMidC - kOPLMidC)); + + if (isPercussionMode() && (voice >= kVoiceBaseDrum)) { + + if (voice == kVoiceBaseDrum) { + setFreq(kVoiceBaseDrum , note , false); + } else if (voice == kVoiceTom) { + setFreq(kVoiceTom , note , false); + setFreq(kVoiceSnareDrum, note + kPitchTomToSnare, false); + } + + _percussionBits |= kPercussionMasks[voice - kVoiceBaseDrum]; + writeTremoloVibratoDepthPercMode(); - _timbres = 0; - _tbrCount = 0; - _tbrStart = 0; - _timbresSize = 0; + } else + setFreq(voice, note, true); } -bool MDYPlayer::loadMDY(Common::SeekableReadStream &stream) { - unloadMDY(); +void AdLib::noteOff(uint8 voice) { + if (isPercussionMode() && (voice >= kVoiceBaseDrum)) { + _percussionBits &= ~kPercussionMasks[voice - kVoiceBaseDrum]; + writeTremoloVibratoDepthPercMode(); + } else + setFreq(voice, _voiceNote[voice], false); +} - _freeData = true; +void AdLib::writeKeyScaleLevelVolume(uint8 oper) { + uint16 volume = 0; - byte mdyHeader[70]; - stream.read(mdyHeader, 70); + volume = (63 - (_operatorParams[oper][kParamLevel] & 0x3F)) * _operatorVolume[oper]; + volume = 63 - ((2 * volume + kMaxVolume) / (2 * kMaxVolume)); - _tickBeat = mdyHeader[36]; - _beatMeasure = mdyHeader[37]; - _totalTick = mdyHeader[38] + (mdyHeader[39] << 8) + (mdyHeader[40] << 16) + (mdyHeader[41] << 24); - _dataSize = mdyHeader[42] + (mdyHeader[43] << 8) + (mdyHeader[44] << 16) + (mdyHeader[45] << 24); - _nrCommand = mdyHeader[46] + (mdyHeader[47] << 8) + (mdyHeader[48] << 16) + (mdyHeader[49] << 24); -// _soundMode is either 0 (melodic) or 1 (percussive) - _soundMode = mdyHeader[58]; - assert((_soundMode == 0) || (_soundMode == 1)); + uint8 keyScale = _operatorParams[oper][kParamKeyScaleLevel] << 6; - _pitchBendRangeStep = 25*mdyHeader[59]; - _basicTempo = mdyHeader[60] + (mdyHeader[61] << 8); + writeOPL(0x40 + kOperatorOffset[oper], volume | keyScale); +} - if (_pitchBendRangeStep < 25) - _pitchBendRangeStep = 25; - else if (_pitchBendRangeStep > 300) - _pitchBendRangeStep = 300; +void AdLib::writeKeySplit() { + writeOPL(0x08, _keySplit ? 0x40 : 0); +} - _data = new byte[_dataSize]; - stream.read(_data, _dataSize); +void AdLib::writeFeedbackFM(uint8 oper) { + if (kOperatorType[oper] == 1) + return; - reset(); - _playPos = _data; + uint8 value = 0; + + value |= _operatorParams[oper][kParamFeedback] << 1; + value |= _operatorParams[oper][kParamFM] ? 0 : 1; - return true; + writeOPL(0xC0 + kOperatorVoice[oper], value); } -bool MDYPlayer::loadMDY(const char *fileName) { - Common::File song; +void AdLib::writeAttackDecay(uint8 oper) { + uint8 value = 0; - song.open(fileName); - if (!song.isOpen()) - return false; + value |= _operatorParams[oper][kParamAttack] << 4; + value |= _operatorParams[oper][kParamDecay] & 0x0F; - bool loaded = loadMDY(song); + writeOPL(0x60 + kOperatorOffset[oper], value); +} - song.close(); +void AdLib::writeSustainRelease(uint8 oper) { + uint8 value = 0; - return loaded; + value |= _operatorParams[oper][kParamSustain] << 4; + value |= _operatorParams[oper][kParamRelease] & 0x0F; + + writeOPL(0x80 + kOperatorOffset[oper], value); } -bool MDYPlayer::loadTBR(Common::SeekableReadStream &stream) { - unloadTBR(); +void AdLib::writeTremoloVibratoSustainingKeyScaleRateFreqMulti(uint8 oper) { + uint8 value = 0; + + value |= _operatorParams[oper][kParamAM] ? 0x80 : 0; + value |= _operatorParams[oper][kParamVib] ? 0x40 : 0; + value |= _operatorParams[oper][kParamSustaining] ? 0x20 : 0; + value |= _operatorParams[oper][kParamKeyScaleRate] ? 0x10 : 0; + value |= _operatorParams[oper][kParamFreqMulti] & 0x0F; - _timbresSize = stream.size(); + writeOPL(0x20 + kOperatorOffset[oper], value); +} - _timbres = new byte[_timbresSize]; - stream.read(_timbres, _timbresSize); +void AdLib::writeTremoloVibratoDepthPercMode() { + uint8 value = 0; - reset(); - setVoices(); + value |= _tremoloDepth ? 0x80 : 0; + value |= _vibratoDepth ? 0x40 : 0; + value |= isPercussionMode() ? 0x20 : 0; + value |= _percussionBits; - return true; + writeOPL(0xBD, value); } -bool MDYPlayer::loadTBR(const char *fileName) { - Common::File timbres; +void AdLib::writeWaveSelect(uint8 oper) { + uint8 wave = 0; + if (_enableWaveSelect) + wave = _operatorParams[oper][kParamWaveSelect] & 0x03; - timbres.open(fileName); - if (!timbres.isOpen()) - return false; + writeOPL(0xE0 + kOperatorOffset[ oper], wave); +} + +void AdLib::writeAllParams(uint8 oper) { + writeTremoloVibratoDepthPercMode(); + writeKeySplit(); + writeKeyScaleLevelVolume(oper); + writeFeedbackFM(oper); + writeAttackDecay(oper); + writeSustainRelease(oper); + writeTremoloVibratoSustainingKeyScaleRateFreqMulti(oper); + writeWaveSelect(oper); +} - bool loaded = loadTBR(timbres); +void AdLib::initOperatorParams() { + for (int i = 0; i < kOperatorCount; i++) + setOperatorParams(i, kPianoParams[kOperatorType[i]], kPianoParams[kOperatorType[i]][kParamCount - 1]); - timbres.close(); + if (isPercussionMode()) { + setOperatorParams(12, kBaseDrumParams [0], kBaseDrumParams [0][kParamCount - 1]); + setOperatorParams(15, kBaseDrumParams [1], kBaseDrumParams [1][kParamCount - 1]); + setOperatorParams(16, kSnareDrumParams , kSnareDrumParams [kParamCount - 1]); + setOperatorParams(14, kTomParams , kTomParams [kParamCount - 1]); + setOperatorParams(17, kCymbalParams , kCymbalParams [kParamCount - 1]); + setOperatorParams(13, kHihatParams , kHihatParams [kParamCount - 1]); + } +} - return loaded; +void AdLib::initOperatorVolumes() { + for(int i = 0; i < kOperatorCount; i++) + _operatorVolume[i] = kMaxVolume; } -void MDYPlayer::unload() { - unloadTBR(); - unloadMDY(); +void AdLib::setOperatorParams(uint8 oper, const uint16 *params, uint8 wave) { + byte *operParams = _operatorParams[oper]; + + for (int i = 0; i < (kParamCount - 1); i++) + operParams[i] = params[i]; + + operParams[kParamCount - 1] = wave & 0x03; + + writeAllParams(oper); } -void MDYPlayer::unloadMDY() { - AdLib::unload(); +void AdLib::voiceOff(uint8 voice) { + writeOPL(0xA0 + voice, 0); + writeOPL(0xB0 + voice, 0); } -void MDYPlayer::unloadTBR() { - delete[] _timbres; +int32 AdLib::calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom) { + int32 freq = 0; - _timbres = 0; - _timbresSize = 0; + freq = ((deltaDemiToneDenom * 100) + 6 * deltaDemiToneNum) * 52088; + freq /= deltaDemiToneDenom * 2500; + + return (freq * 147456) / 111875; } -void MDYPlayer::interpret() { - unsigned char instr; - byte channel; - byte note; - byte volume; - uint8 tempoMult, tempoFrac; - uint8 ctrlByte1, ctrlByte2; - uint8 timbre; +void AdLib::setFreqs(uint16 *freqs, int32 num, int32 denom) { + int32 val = calcFreq(num, denom); -// TODO : Verify the loop for percussive mode (11 ?) - if (_first) { - for (int i = 0; i < 9; i ++) - setVolume(i, 0); + *freqs++ = (4 + val) >> 3; -// TODO : Set pitch range + for (int i = 1; i < kHalfToneCount; i++) { + val = (val * 106) / 100; - _tempo = _basicTempo; - _wait = *(_playPos++); - _first = false; + *freqs++ = (4 + val) >> 3; } - do { - instr = *_playPos; - debugC(6, kDebugSound, "MDYPlayer::interpret instr 0x%X", instr); - switch (instr) { - case 0xF8: - _wait = *(_playPos++); - break; - case 0xFC: - _ended = true; - _samplesTillPoll = 0; - return; - case 0xF0: - _playPos++; - ctrlByte1 = *(_playPos++); - ctrlByte2 = *(_playPos++); - debugC(6, kDebugSound, "MDYPlayer::interpret ctrlBytes 0x%X 0x%X", ctrlByte1, ctrlByte2); - if (ctrlByte1 != 0x7F || ctrlByte2 != 0) { - _playPos -= 2; - while (*(_playPos++) != 0xF7) - ; - } else { - tempoMult = *(_playPos++); - tempoFrac = *(_playPos++); - _tempo = _basicTempo * tempoMult + (unsigned)(((long)_basicTempo * tempoFrac) >> 7); - _playPos++; - } - _wait = *(_playPos++); - break; - default: - if (instr >= 0x80) { - _playPos++; - } - channel = (int)(instr & 0x0f); - - switch (instr & 0xf0) { - case 0x90: - note = *(_playPos++); - volume = *(_playPos++); - _pollNotes[channel] = note; - setVolume(channel, volume); - setKey(channel, note, true, false); - break; - case 0x80: - _playPos += 2; - note = _pollNotes[channel]; - setKey(channel, note, false, false); - break; - case 0xA0: - setVolume(channel, *(_playPos++)); - break; - case 0xC0: - timbre = *(_playPos++); - setVoice(channel, timbre, false); - break; - case 0xE0: - warning("MDYPlayer: Pitch bend not yet implemented"); +} - note = *(_playPos)++; - note += (unsigned)(*(_playPos++)) << 7; +void AdLib::initFreqs() { + const int numStep = 100 / kPitchStepCount; - setKey(channel, note, _notOn[channel], true); + for (int i = 0; i < kPitchStepCount; i++) + setFreqs(_freqs[i], i * numStep, 100); - break; - case 0xB0: - _playPos += 2; - break; - case 0xD0: - _playPos++; - break; - default: - warning("MDYPlayer: Bad MIDI instr byte: 0%X", instr); - while ((*_playPos) < 0x80) - _playPos++; - if (*_playPos != 0xF8) - _playPos--; - break; - } //switch instr & 0xF0 - _wait = *(_playPos++); - break; - } //switch instr - } while (_wait == 0); - - if (_wait == 0xF8) { - _wait = 0xF0; - if (*_playPos != 0xF8) - _wait += *(_playPos++) & 0x0F; + for (int i = 0; i < kMaxVoiceCount; i++) { + _freqPtr [i] = _freqs[0]; + _halfToneOffset[i] = 0; } -// _playPos++; - _samplesTillPoll = _wait * (_rate / 1000); } -void MDYPlayer::reset() { - AdLib::reset(); +void AdLib::changePitch(uint8 voice, uint16 pitchBend) { + + int full = 0; + int frac = 0; + int amount = ((pitchBend - kMidPitch) * _pitchRangeStep) / kMidPitch; + + if (amount >= 0) { + // Bend up + + full = amount / kPitchStepCount; + frac = amount % kPitchStepCount; -// _soundMode 1 : Percussive mode. - if (_soundMode == 1) { - writeOPL(0xA6, 0); - writeOPL(0xB6, 0); - writeOPL(0xA7, 0); - writeOPL(0xB7, 0); - writeOPL(0xA8, 0); - writeOPL(0xB8, 0); + } else { + // Bend down + + amount = kPitchStepCount - 1 - amount; + + full = -(amount / kPitchStepCount); + frac = (amount - kPitchStepCount + 1) % kPitchStepCount; + if (frac) + frac = kPitchStepCount - frac; -// TODO set the correct frequency for the last 4 percussive voices } + + _halfToneOffset[voice] = full; + _freqPtr [voice] = _freqs[frac]; } -void MDYPlayer::rewind() { - _playPos = _data; -} - -void MDYPlayer::setVoices() { - byte *timbrePtr; - - timbrePtr = _timbres; - debugC(6, kDebugSound, "MDYPlayer::setVoices TBR version: %X.%X", timbrePtr[0], timbrePtr[1]); - timbrePtr += 2; - - _tbrCount = READ_LE_UINT16(timbrePtr); - debugC(6, kDebugSound, "MDYPlayer::setVoices Timbres counter: %d", _tbrCount); - timbrePtr += 2; - _tbrStart = READ_LE_UINT16(timbrePtr); - - timbrePtr += 2; - for (int i = 0; i < _tbrCount; i++) - setVoice(i, i, true); -} - -void MDYPlayer::setVoice(byte voice, byte instr, bool set) { -// uint16 strct[27]; - uint8 strct[27]; - byte channel; - byte *timbrePtr; - char timbreName[10]; - - timbreName[9] = '\0'; - for (int j = 0; j < 9; j++) - timbreName[j] = _timbres[6 + j + (instr * 9)]; - debugC(6, kDebugSound, "MDYPlayer::setVoice Loading timbre %s", timbreName); - - // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 - // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 - for (int i = 0; i < 2; i++) { - timbrePtr = _timbres + _tbrStart + instr * 0x38 + i * 0x1A; - for (int j = 0; j < 27; j++) { - if (timbrePtr >= (_timbres + _timbresSize)) { - warning("MDYPlayer: Instrument %d out of range (%d, %d)", instr, - (uint32) (timbrePtr - _timbres), _timbresSize); - strct[j] = 0; - } else - //strct[j] = READ_LE_UINT16(timbrePtr); - strct[j] = timbrePtr[0]; - //timbrePtr += 2; - timbrePtr++; - } - channel = _operators[voice] + i * 3; - writeOPL(0xBD, 0x00); - writeOPL(0x08, 0x00); - writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); - if (!i) - writeOPL(0xC0 | voice, - ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); - writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); - writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); - writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | - ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | - ((strct[11] & 1) << 4) | (strct[1] & 0xF)); - if (!i) - writeOPL(0xE0 | channel, (strct[26] & 3)); - else { - writeOPL(0xE0 | channel, (strct[14] & 3)); - writeOPL(0x40 | channel, 0); - } - } +void AdLib::setFreq(uint8 voice, uint16 note, bool on) { + _voiceOn [voice] = on; + _voiceNote[voice] = note; + + note = CLIP(note + _halfToneOffset[voice], 0, kNoteCount - 1); + + uint16 freq = _freqPtr[voice][note % kHalfToneCount]; + + uint8 value = 0; + value |= on ? 0x20 : 0; + value |= ((note / kHalfToneCount) << 2) | ((freq >> 8) & 0x03); + + writeOPL(0xA0 + voice, freq); + writeOPL(0xB0 + voice, value); } } // End of namespace Gob diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 934e9966eb..df1b77fd4d 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -20,154 +20,287 @@ * */ -#ifndef GOB_SOUND_ADLIB_H -#define GOB_SOUND_ADLIB_H +#ifndef GOB_SOUND_NEWADLIB_H +#define GOB_SOUND_NEWADLIB_H #include "common/mutex.h" + #include "audio/audiostream.h" #include "audio/mixer.h" -#include "audio/fmopl.h" -namespace Gob { +namespace OPL { + class OPL; +} -class GobEngine; +namespace Gob { +/** Base class for a player of an AdLib music format. */ class AdLib : public Audio::AudioStream { public: AdLib(Audio::Mixer &mixer); virtual ~AdLib(); - bool isPlaying() const; - int getIndex() const; - bool getRepeating() const; + bool isPlaying() const; ///< Are we currently playing? + int32 getRepeating() const; ///< Return number of times left to loop. + /** Set the loop counter. + * + * @param repCount Number of times to loop (i.e. number of additional + * paythroughs to the first one, not overall). + * A negative value means infinite looping. + */ void setRepeating(int32 repCount); void startPlay(); void stopPlay(); - virtual void unload(); - // AudioStream API int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return false; } - bool endOfData() const { return !_playing; } - bool endOfStream() const { return false; } - int getRate() const { return _rate; } + bool isStereo() const; + bool endOfData() const; + bool endOfStream() const; + int getRate() const; protected: - static const unsigned char _operators[]; - static const unsigned char _volRegNums []; + enum kVoice { + kVoiceMelody0 = 0, + kVoiceMelody1 = 1, + kVoiceMelody2 = 2, + kVoiceMelody3 = 3, + kVoiceMelody4 = 4, + kVoiceMelody5 = 5, + kVoiceMelody6 = 6, // Only available in melody mode. + kVoiceMelody7 = 7, // Only available in melody mode. + kVoiceMelody8 = 8, // Only available in melody mode. + kVoiceBaseDrum = 6, // Only available in percussion mode. + kVoiceSnareDrum = 7, // Only available in percussion mode. + kVoiceTom = 8, // Only available in percussion mode. + kVoiceCymbal = 9, // Only available in percussion mode. + kVoiceHihat = 10 // Only available in percussion mode. + }; + + /** Operator parameters. */ + enum kParam { + kParamKeyScaleLevel = 0, + kParamFreqMulti = 1, + kParamFeedback = 2, + kParamAttack = 3, + kParamSustain = 4, + kParamSustaining = 5, + kParamDecay = 6, + kParamRelease = 7, + kParamLevel = 8, + kParamAM = 9, + kParamVib = 10, + kParamKeyScaleRate = 11, + kParamFM = 12, + kParamWaveSelect = 13 + }; + + static const int kOperatorCount = 18; ///< Number of operators. + static const int kParamCount = 14; ///< Number of operator parameters. + static const int kPitchStepCount = 25; ///< Number of pitch bend steps in a half tone. + static const int kOctaveCount = 8; ///< Number of octaves we can play. + static const int kHalfToneCount = 12; ///< Number of half tones in an octave. + + static const int kOperatorsPerVoice = 2; ///< Number of operators per voice. + + static const int kMelodyVoiceCount = 9; ///< Number of melody voices. + static const int kPercussionVoiceCount = 5; ///< Number of percussion voices. + static const int kMaxVoiceCount = 11; ///< Max number of voices. + + /** Number of notes we can play. */ + static const int kNoteCount = kHalfToneCount * kOctaveCount; + + static const int kMaxVolume = 0x007F; + static const int kMaxPitch = 0x3FFF; + static const int kMidPitch = 0x2000; + + static const int kStandardMidC = 60; ///< A mid C in standard MIDI. + static const int kOPLMidC = 48; ///< A mid C for the OPL. + + + /** Return the number of samples per second. */ + uint32 getSamplesPerSecond() const; + + /** Write a value into an OPL register. */ + void writeOPL(byte reg, byte val); + + /** Signal that the playback ended. + * + * @param killRepeat Explicitly request that the song is not to be looped. + */ + void end(bool killRepeat = false); + + /** The callback function that's called for polling more AdLib commands. + * + * @param first Is this the first poll since the start of the song? + * @return The number of samples until the next poll. + */ + virtual uint32 pollMusic(bool first) = 0; + + /** Rewind the song. */ + virtual void rewind() = 0; + + /** Return whether we're in percussion mode. */ + bool isPercussionMode() const; + + /** Set percussion or melody mode. */ + void setPercussionMode(bool percussion); + + /** Enable/Disable the wave select operator parameters. + * + * When disabled, all operators use the sine wave, regardless of the parameter. + */ + void enableWaveSelect(bool enable); + + /** Change the pitch bend range. + * + * @param range The range in half tones from 1 to 12 inclusive. + * See bendVoicePitch() for how this works in practice. + */ + void setPitchRange(uint8 range); + + /** Set the tremolo (amplitude vibrato) depth. + * + * @param tremoloDepth false: 1.0dB, true: 4.8dB. + */ + void setTremoloDepth(bool tremoloDepth); + + /** Set the frequency vibrato depth. + * + * @param vibratoDepth false: 7 cent, true: 14 cent. 1 cent = 1/100 half tone. + */ + void setVibratoDepth(bool vibratoDepth); + + /** Set the keyboard split point. */ + void setKeySplit(bool keySplit); + + /** Set the timbre of a voice. + * + * Layout of the operator parameters is as follows: + * - First 13 parameter for the first operator + * - First 13 parameter for the second operator + * - 14th parameter (wave select) for the first operator + * - 14th parameter (wave select) for the second operator + */ + void setVoiceTimbre(uint8 voice, const uint16 *params); + + /** Set a voice's volume. */ + void setVoiceVolume(uint8 voice, uint8 volume); + + /** Bend a voice's pitch. + * + * The pitchBend parameter is a value between 0 (full down) and kMaxPitch (full up). + * The actual frequency depends on the pitch range set previously by setPitchRange(), + * with full down being -range half tones and full up range half tones. + */ + void bendVoicePitch(uint8 voice, uint16 pitchBend); + + /** Switch a voice on. + * + * Plays one of the kNoteCount notes. However, the valid range of a note is between + * 0 and 127, of which only 12 to 107 are audible. + */ + void noteOn(uint8 voice, uint8 note); + + /** Switch a voice off. */ + void noteOff(uint8 voice); + +private: + static const uint8 kOperatorType [kOperatorCount]; + static const uint8 kOperatorOffset[kOperatorCount]; + static const uint8 kOperatorVoice [kOperatorCount]; + + static const uint8 kVoiceMelodyOperator [kOperatorsPerVoice][kMelodyVoiceCount]; + static const uint8 kVoicePercussionOperator[kOperatorsPerVoice][kPercussionVoiceCount]; + + static const byte kPercussionMasks[kPercussionVoiceCount]; + + static const uint16 kPianoParams [kOperatorsPerVoice][kParamCount]; + static const uint16 kBaseDrumParams [kOperatorsPerVoice][kParamCount]; + + static const uint16 kSnareDrumParams[kParamCount]; + static const uint16 kTomParams [kParamCount]; + static const uint16 kCymbalParams [kParamCount]; + static const uint16 kHihatParams [kParamCount]; + Audio::Mixer *_mixer; Audio::SoundHandle _handle; - FM_OPL *_opl; + OPL::OPL *_opl; Common::Mutex _mutex; uint32 _rate; - byte *_data; - byte *_playPos; - uint32 _dataSize; - - short _freqs[25][12]; - byte _notes[11]; - byte _notCol[11]; - byte _notLin[11]; - bool _notOn[11]; - byte _pollNotes[16]; + uint32 _toPoll; - int _samplesTillPoll; int32 _repCount; - bool _playing; bool _first; + bool _playing; bool _ended; - bool _freeData; + bool _tremoloDepth; + bool _vibratoDepth; + bool _keySplit; - int _index; + bool _enableWaveSelect; - unsigned char _wait; - uint8 _tickBeat; - uint8 _beatMeasure; - uint32 _totalTick; - uint32 _nrCommand; - uint16 _pitchBendRangeStep; - uint16 _basicTempo, _tempo; + bool _percussionMode; + byte _percussionBits; - void writeOPL(byte reg, byte val); - void setFreqs(); - void setKey(byte voice, byte note, bool on, bool spec); - void setVolume(byte voice, byte volume); - void pollMusic(); + uint8 _pitchRange; + uint16 _pitchRangeStep; - virtual void interpret() = 0; + uint8 _voiceNote[kMaxVoiceCount]; // Last note of each voice + uint8 _voiceOn [kMaxVoiceCount]; // Whether each voice is currently on - virtual void reset(); - virtual void rewind() = 0; - virtual void setVoices() = 0; + uint8 _operatorVolume[kOperatorCount]; // Volume of each operator -private: - void init(); -}; + byte _operatorParams[kOperatorCount][kParamCount]; // All operator parameters -class ADLPlayer : public AdLib { -public: - ADLPlayer(Audio::Mixer &mixer); - ~ADLPlayer(); + uint16 _freqs[kPitchStepCount][kHalfToneCount]; + uint16 *_freqPtr[kMaxVoiceCount]; - bool load(const char *fileName); - bool load(byte *data, uint32 size, int index = -1); + int _halfToneOffset[kMaxVoiceCount]; - void unload(); -protected: - void interpret(); + void createOPL(); + void initOPL(); void reset(); - void rewind(); + void allOff(); - void setVoices(); - void setVoice(byte voice, byte instr, bool set); -}; + // Write global parameters into the OPL + void writeTremoloVibratoDepthPercMode(); + void writeKeySplit(); -class MDYPlayer : public AdLib { -public: - MDYPlayer(Audio::Mixer &mixer); - ~MDYPlayer(); - - bool loadMDY(const char *fileName); - bool loadMDY(Common::SeekableReadStream &stream); - bool loadTBR(const char *fileName); - bool loadTBR(Common::SeekableReadStream &stream); - - void unload(); - -protected: - byte _soundMode; - - byte *_timbres; - uint16 _tbrCount; - uint16 _tbrStart; - uint32 _timbresSize; + // Write operator parameters into the OPL + void writeWaveSelect(uint8 oper); + void writeTremoloVibratoSustainingKeyScaleRateFreqMulti(uint8 oper); + void writeSustainRelease(uint8 oper); + void writeAttackDecay(uint8 oper); + void writeFeedbackFM(uint8 oper); + void writeKeyScaleLevelVolume(uint8 oper); + void writeAllParams(uint8 oper); - void interpret(); + void initOperatorParams(); + void initOperatorVolumes(); + void setOperatorParams(uint8 oper, const uint16 *params, uint8 wave); - void reset(); - void rewind(); + void voiceOff(uint8 voice); - void setVoices(); - void setVoice(byte voice, byte instr, bool set); + void initFreqs(); + void setFreqs(uint16 *freqs, int32 num, int32 denom); + int32 calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom); - void unloadTBR(); - void unloadMDY(); + void changePitch(uint8 voice, uint16 pitchBend); -private: - void init(); + void setFreq(uint8 voice, uint16 note, bool on); }; } // End of namespace Gob -#endif // GOB_SOUND_ADLIB_H +#endif // GOB_SOUND_NEWADLIB_H diff --git a/engines/gob/sound/adlplayer.cpp b/engines/gob/sound/adlplayer.cpp new file mode 100644 index 0000000000..ee23191c0d --- /dev/null +++ b/engines/gob/sound/adlplayer.cpp @@ -0,0 +1,257 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/stream.h" +#include "common/memstream.h" +#include "common/textconsole.h" + +#include "gob/sound/adlplayer.h" + +namespace Gob { + +ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer), + _songData(0), _songDataSize(0), _playPos(0) { + +} + +ADLPlayer::~ADLPlayer() { + unload(); +} + +void ADLPlayer::unload() { + stopPlay(); + + _timbres.clear(); + + delete[] _songData; + + _songData = 0; + _songDataSize = 0; + + _playPos = 0; +} + +uint32 ADLPlayer::pollMusic(bool first) { + if (_timbres.empty() || !_songData || !_playPos || (_playPos >= (_songData + _songDataSize))) { + end(); + return 0; + } + + // We'll ignore the first delay + if (first) + _playPos += (*_playPos & 0x80) ? 2 : 1; + + byte cmd = *_playPos++; + + // Song end marker + if (cmd == 0xFF) { + end(); + return 0; + } + + // Set the instrument that should be modified + if (cmd == 0xFE) + _modifyInstrument = *_playPos++; + + if (cmd >= 0xD0) { + // Modify an instrument + + if (_modifyInstrument == 0xFF) + warning("ADLPlayer: No instrument to modify"); + else if (_modifyInstrument >= _timbres.size()) + warning("ADLPlayer: Can't modify invalid instrument %d (%d)", _modifyInstrument, _timbres.size()); + else + _timbres[_modifyInstrument].params[_playPos[0]] = _playPos[1]; + + _playPos += 2; + + // If we currently have that instrument loaded, reload it + for (int i = 0; i < kMaxVoiceCount; i++) + if (_currentInstruments[i] == _modifyInstrument) + setInstrument(i, _modifyInstrument); + } else { + // Voice command + + uint8 voice = cmd & 0x0F; + uint8 note, volume; + + switch (cmd & 0xF0) { + case 0x00: // Note on with volume + note = *_playPos++; + volume = *_playPos++; + + setVoiceVolume(voice, volume); + noteOn(voice, note); + break; + + case 0xA0: // Pitch bend + bendVoicePitch(voice, ((uint16)*_playPos++) << 7); + break; + + case 0xB0: // Set volume + setVoiceVolume(voice, *_playPos++); + break; + + case 0xC0: // Set instrument + setInstrument(voice, *_playPos++); + break; + + case 0x90: // Note on + noteOn(voice, *_playPos++); + break; + + case 0x80: // Note off + noteOff(voice); + break; + + default: + warning("ADLPlayer: Unsupported command: 0x%02X. Stopping playback.", cmd); + end(true); + return 0; + } + } + + uint16 delay = *_playPos++; + + if (delay & 0x80) + delay = ((delay & 3) << 8) | *_playPos++; + + return getSampleDelay(delay); +} + +uint32 ADLPlayer::getSampleDelay(uint16 delay) const { + if (delay == 0) + return 0; + + return ((uint32)delay * getSamplesPerSecond()) / 1000; +} + +void ADLPlayer::rewind() { + // Reset song data + _playPos = _songData; + + // Set melody/percussion mode + setPercussionMode(_soundMode != 0); + + // Reset instruments + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) + memcpy(t->params, t->startParams, kOperatorsPerVoice * kParamCount * sizeof(uint16)); + + for (int i = 0; i < kMaxVoiceCount; i++) + _currentInstruments[i] = 0; + + // Reset voices + int numVoice = MIN(_timbres.size(), _soundMode ? (int)kMaxVoiceCount : (int)kMelodyVoiceCount); + for (int i = 0; i < numVoice; i++) { + setInstrument(i, _currentInstruments[i]); + setVoiceVolume(i, kMaxVolume); + } + + _modifyInstrument = 0xFF; +} + +bool ADLPlayer::load(Common::SeekableReadStream &adl) { + unload(); + + int timbreCount; + if (!readHeader(adl, timbreCount)) { + unload(); + return false; + } + + if (!readTimbres(adl, timbreCount) || !readSongData(adl) || adl.err()) { + unload(); + return false; + } + + rewind(); + + return true; +} + +bool ADLPlayer::readHeader(Common::SeekableReadStream &adl, int &timbreCount) { + // Sanity check + if (adl.size() < 60) { + warning("ADLPlayer::readHeader(): File too small (%d)", adl.size()); + return false; + } + + _soundMode = adl.readByte(); + timbreCount = adl.readByte() + 1; + + adl.skip(1); + + return true; +} + +bool ADLPlayer::readTimbres(Common::SeekableReadStream &adl, int timbreCount) { + _timbres.resize(timbreCount); + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) { + for (int i = 0; i < (kOperatorsPerVoice * kParamCount); i++) + t->startParams[i] = adl.readUint16LE(); + } + + if (adl.err()) { + warning("ADLPlayer::readTimbres(): Read failed"); + return false; + } + + return true; +} + +bool ADLPlayer::readSongData(Common::SeekableReadStream &adl) { + _songDataSize = adl.size() - adl.pos(); + _songData = new byte[_songDataSize]; + + if (adl.read(_songData, _songDataSize) != _songDataSize) { + warning("ADLPlayer::readSongData(): Read failed"); + return false; + } + + return true; +} + +bool ADLPlayer::load(const byte *data, uint32 dataSize, int index) { + unload(); + + Common::MemoryReadStream stream(data, dataSize); + if (!load(stream)) + return false; + + _index = index; + return true; +} + +void ADLPlayer::setInstrument(int voice, int instrument) { + if ((voice >= kMaxVoiceCount) || ((uint)instrument >= _timbres.size())) + return; + + _currentInstruments[voice] = instrument; + + setVoiceTimbre(voice, _timbres[instrument].params); +} + +int ADLPlayer::getIndex() const { + return _index; +} + +} // End of namespace Gob diff --git a/engines/gob/sound/adlplayer.h b/engines/gob/sound/adlplayer.h new file mode 100644 index 0000000000..9596447bbc --- /dev/null +++ b/engines/gob/sound/adlplayer.h @@ -0,0 +1,85 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_SOUND_ADLPLAYER_H +#define GOB_SOUND_ADLPLAYER_H + +#include "common/array.h" + +#include "gob/sound/adlib.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Gob { + +/** A player for Coktel Vision's ADL music format. */ +class ADLPlayer : public AdLib { +public: + ADLPlayer(Audio::Mixer &mixer); + ~ADLPlayer(); + + bool load(Common::SeekableReadStream &adl); + bool load(const byte *data, uint32 dataSize, int index = -1); + void unload(); + + int getIndex() const; + +protected: + // AdLib interface + uint32 pollMusic(bool first); + void rewind(); + +private: + struct Timbre { + uint16 startParams[kOperatorsPerVoice * kParamCount]; + uint16 params[kOperatorsPerVoice * kParamCount]; + }; + + uint8 _soundMode; + + Common::Array _timbres; + + byte *_songData; + uint32 _songDataSize; + + const byte *_playPos; + + int _index; + + uint8 _modifyInstrument; + uint16 _currentInstruments[kMaxVoiceCount]; + + + void setInstrument(int voice, int instrument); + + bool readHeader (Common::SeekableReadStream &adl, int &timbreCount); + bool readTimbres (Common::SeekableReadStream &adl, int timbreCount); + bool readSongData(Common::SeekableReadStream &adl); + + uint32 getSampleDelay(uint16 delay) const; +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_ADLPLAYER_H diff --git a/engines/gob/sound/musplayer.cpp b/engines/gob/sound/musplayer.cpp new file mode 100644 index 0000000000..3e41dc6ed1 --- /dev/null +++ b/engines/gob/sound/musplayer.cpp @@ -0,0 +1,391 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/stream.h" +#include "common/textconsole.h" + +#include "gob/sound/musplayer.h" + +namespace Gob { + +MUSPlayer::MUSPlayer(Audio::Mixer &mixer) : AdLib(mixer), + _songData(0), _songDataSize(0), _playPos(0), _songID(0) { + +} + +MUSPlayer::~MUSPlayer() { + unload(); +} + +void MUSPlayer::unload() { + stopPlay(); + + unloadSND(); + unloadMUS(); +} + +uint32 MUSPlayer::getSampleDelay(uint16 delay) const { + if (delay == 0) + return 0; + + uint32 freq = (_ticksPerBeat * _tempo) / 60; + + return ((uint32)delay * getSamplesPerSecond()) / freq; +} + +void MUSPlayer::skipToTiming() { + while (*_playPos < 0x80) + _playPos++; + + if (*_playPos != 0xF8) + _playPos--; +} + +uint32 MUSPlayer::pollMusic(bool first) { + if (_timbres.empty() || !_songData || !_playPos || (_playPos >= (_songData + _songDataSize))) { + end(); + return 0; + } + + if (first) + return getSampleDelay(*_playPos++); + + uint16 delay = 0; + while (delay == 0) { + byte cmd = *_playPos; + + // Delay overflow + if (cmd == 0xF8) { + _playPos++; + delay = 0xF8; + break; + } + + // Song end marker + if (cmd == 0xFC) { + end(); + return 0; + } + + // Global command + if (cmd == 0xF0) { + _playPos++; + + byte type1 = *_playPos++; + byte type2 = *_playPos++; + + if ((type1 == 0x7F) && (type2 == 0)) { + // Tempo change, as a fraction of the base tempo + + uint32 num = *_playPos++; + uint32 denom = *_playPos++; + + _tempo = _baseTempo * num + ((_baseTempo * denom) >> 7); + + _playPos++; + } else { + + // Unsupported global command, skip it + _playPos -= 2; + while(*_playPos++ != 0xF7) + ; + } + + delay = *_playPos++; + break; + } + + // Voice command + + if (cmd >= 0x80) { + _playPos++; + + _lastCommand = cmd; + } else + cmd = _lastCommand; + + uint8 voice = cmd & 0x0F; + uint8 note, volume; + uint16 pitch; + + switch (cmd & 0xF0) { + case 0x80: // Note off + _playPos += 2; + noteOff(voice); + break; + + case 0x90: // Note on + note = *_playPos++; + volume = *_playPos++; + + if (volume) { + setVoiceVolume(voice, volume); + noteOn(voice, note); + } else + noteOff(voice); + break; + + case 0xA0: // Set volume + setVoiceVolume(voice, *_playPos++); + break; + + case 0xB0: + _playPos += 2; + break; + + case 0xC0: // Set instrument + setInstrument(voice, *_playPos++); + break; + + case 0xD0: + _playPos++; + break; + + case 0xE0: // Pitch bend + pitch = *_playPos++; + pitch += *_playPos++ << 7; + bendVoicePitch(voice, pitch); + break; + + default: + warning("MUSPlayer: Unsupported command: 0x%02X", cmd); + skipToTiming(); + break; + } + + delay = *_playPos++; + } + + if (delay == 0xF8) { + delay = 240; + + if (*_playPos != 0xF8) + delay += *_playPos++; + } + + return getSampleDelay(delay); +} + +void MUSPlayer::rewind() { + _playPos = _songData; + _tempo = _baseTempo; + + _lastCommand = 0; + + setPercussionMode(_soundMode != 0); + setPitchRange(_pitchBendRange); +} + +bool MUSPlayer::loadSND(Common::SeekableReadStream &snd) { + unloadSND(); + + int timbreCount, timbrePos; + if (!readSNDHeader(snd, timbreCount, timbrePos)) + return false; + + if (!readSNDTimbres(snd, timbreCount, timbrePos) || snd.err()) { + unloadSND(); + return false; + } + + return true; +} + +bool MUSPlayer::readString(Common::SeekableReadStream &stream, Common::String &string, byte *buffer, uint size) { + if (stream.read(buffer, size) != size) + return false; + + buffer[size] = '\0'; + + string = (char *) buffer; + + return true; +} + +bool MUSPlayer::readSNDHeader(Common::SeekableReadStream &snd, int &timbreCount, int &timbrePos) { + // Sanity check + if (snd.size() <= 6) { + warning("MUSPlayer::readSNDHeader(): File too small (%d)", snd.size()); + return false; + } + + // Version + const uint8 versionMajor = snd.readByte(); + const uint8 versionMinor = snd.readByte(); + + if ((versionMajor != 1) && (versionMinor != 0)) { + warning("MUSPlayer::readSNDHeader(): Unsupported version %d.%d", versionMajor, versionMinor); + return false; + } + + // Number of timbres and where they start + timbreCount = snd.readUint16LE(); + timbrePos = snd.readUint16LE(); + + const uint16 minTimbrePos = 6 + timbreCount * 9; + + // Sanity check + if (timbrePos < minTimbrePos) { + warning("MUSPlayer::readSNDHeader(): Timbre offset too small: %d < %d", timbrePos, minTimbrePos); + return false; + } + + const uint32 timbreParametersSize = snd.size() - timbrePos; + const uint32 paramSize = kOperatorsPerVoice * kParamCount * sizeof(uint16); + + // Sanity check + if (timbreParametersSize != (timbreCount * paramSize)) { + warning("MUSPlayer::loadSND(): Timbre parameters size mismatch: %d != %d", + timbreParametersSize, timbreCount * paramSize); + return false; + } + + return true; +} + +bool MUSPlayer::readSNDTimbres(Common::SeekableReadStream &snd, int timbreCount, int timbrePos) { + _timbres.resize(timbreCount); + + // Read names + byte nameBuffer[10]; + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) { + if (!readString(snd, t->name, nameBuffer, 9)) { + warning("MUSPlayer::readMUSTimbres(): Failed to read timbre name"); + return false; + } + } + + if (!snd.seek(timbrePos)) { + warning("MUSPlayer::readMUSTimbres(): Failed to seek to timbres"); + return false; + } + + // Read parameters + for (Common::Array::iterator t = _timbres.begin(); t != _timbres.end(); ++t) { + for (int i = 0; i < (kOperatorsPerVoice * kParamCount); i++) + t->params[i] = snd.readUint16LE(); + } + + return true; +} + +bool MUSPlayer::loadMUS(Common::SeekableReadStream &mus) { + unloadMUS(); + + if (!readMUSHeader(mus) || !readMUSSong(mus) || mus.err()) { + unloadMUS(); + return false; + } + + rewind(); + + return true; +} + +bool MUSPlayer::readMUSHeader(Common::SeekableReadStream &mus) { + // Sanity check + if (mus.size() <= 6) + return false; + + // Version + const uint8 versionMajor = mus.readByte(); + const uint8 versionMinor = mus.readByte(); + + if ((versionMajor != 1) && (versionMinor != 0)) { + warning("MUSPlayer::readMUSHeader(): Unsupported version %d.%d", versionMajor, versionMinor); + return false; + } + + _songID = mus.readUint32LE(); + + byte nameBuffer[31]; + if (!readString(mus, _songName, nameBuffer, 30)) { + warning("MUSPlayer::readMUSHeader(): Failed to read the song name"); + return false; + } + + _ticksPerBeat = mus.readByte(); + _beatsPerMeasure = mus.readByte(); + + mus.skip(4); // Length of song in ticks + + _songDataSize = mus.readUint32LE(); + + mus.skip(4); // Number of commands + mus.skip(8); // Unused + + _soundMode = mus.readByte(); + _pitchBendRange = mus.readByte(); + _baseTempo = mus.readUint16LE(); + + mus.skip(8); // Unused + + return true; +} + +bool MUSPlayer::readMUSSong(Common::SeekableReadStream &mus) { + const uint32 realSongDataSize = mus.size() - mus.pos(); + + if (realSongDataSize < _songDataSize) { + warning("MUSPlayer::readMUSSong(): File too small for the song data: %d < %d", realSongDataSize, _songDataSize); + return false; + } + + _songData = new byte[_songDataSize]; + + if (mus.read(_songData, _songDataSize) != _songDataSize) { + warning("MUSPlayer::readMUSSong(): Read failed"); + return false; + } + + return true; +} + +void MUSPlayer::unloadSND() { + _timbres.clear(); +} + +void MUSPlayer::unloadMUS() { + delete[] _songData; + + _songData = 0; + _songDataSize = 0; + + _playPos = 0; +} + +uint32 MUSPlayer::getSongID() const { + return _songID; +} + +const Common::String &MUSPlayer::getSongName() const { + return _songName; +} + +void MUSPlayer::setInstrument(uint8 voice, uint8 instrument) { + if (instrument >= _timbres.size()) + return; + + setVoiceTimbre(voice, _timbres[instrument].params); +} + +} // End of namespace Gob diff --git a/engines/gob/sound/musplayer.h b/engines/gob/sound/musplayer.h new file mode 100644 index 0000000000..6cc2a2d2ca --- /dev/null +++ b/engines/gob/sound/musplayer.h @@ -0,0 +1,109 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_SOUND_MUSPLAYER_H +#define GOB_SOUND_MUSPLAYER_H + +#include "common/str.h" +#include "common/array.h" + +#include "gob/sound/adlib.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Gob { + +/** A player for the AdLib MUS format, with the instrument information in SND files. + * + * In the Gob engine, those files are usually named .MDY and .TBR instead. + */ +class MUSPlayer : public AdLib { +public: + MUSPlayer(Audio::Mixer &mixer); + ~MUSPlayer(); + + /** Load the instruments (.SND or .TBR) */ + bool loadSND(Common::SeekableReadStream &snd); + /** Load the melody (.MUS or .MDY) */ + bool loadMUS(Common::SeekableReadStream &mus); + + void unload(); + + uint32 getSongID() const; + const Common::String &getSongName() const; + +protected: + // AdLib interface + uint32 pollMusic(bool first); + void rewind(); + +private: + struct Timbre { + Common::String name; + + uint16 params[kOperatorsPerVoice * kParamCount]; + }; + + Common::Array _timbres; + + byte *_songData; + uint32 _songDataSize; + + const byte *_playPos; + + uint32 _songID; + Common::String _songName; + + uint8 _ticksPerBeat; + uint8 _beatsPerMeasure; + + uint8 _soundMode; + uint8 _pitchBendRange; + + uint16 _baseTempo; + + uint16 _tempo; + + byte _lastCommand; + + + void unloadSND(); + void unloadMUS(); + + bool readSNDHeader (Common::SeekableReadStream &snd, int &timbreCount, int &timbrePos); + bool readSNDTimbres(Common::SeekableReadStream &snd, int timbreCount, int timbrePos); + + bool readMUSHeader(Common::SeekableReadStream &mus); + bool readMUSSong (Common::SeekableReadStream &mus); + + uint32 getSampleDelay(uint16 delay) const; + void setInstrument(uint8 voice, uint8 instrument); + void skipToTiming(); + + static bool readString(Common::SeekableReadStream &stream, Common::String &string, byte *buffer, uint size); +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_MUSPLAYER_H diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index bfe0394390..f14e9b150a 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -30,7 +30,8 @@ #include "gob/sound/pcspeaker.h" #include "gob/sound/soundblaster.h" -#include "gob/sound/adlib.h" +#include "gob/sound/adlplayer.h" +#include "gob/sound/musplayer.h" #include "gob/sound/infogrames.h" #include "gob/sound/protracker.h" #include "gob/sound/cdrom.h" @@ -131,10 +132,7 @@ void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdLib, int index) { if (noteAdLib) { if (_adlPlayer) if ((index == -1) || (_adlPlayer->getIndex() == index)) - _adlPlayer->stopPlay(); - if (_mdyPlayer) - if ((index == -1) || (_mdyPlayer->getIndex() == index)) - _mdyPlayer->stopPlay(); + _adlPlayer->unload(); } } else { @@ -235,7 +233,17 @@ bool Sound::adlibLoadADL(const char *fileName) { debugC(1, kDebugSound, "AdLib: Loading ADL data (\"%s\")", fileName); - return _adlPlayer->load(fileName); + Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); + if (!stream) { + warning("Can't open ADL file \"%s\"", fileName); + return false; + } + + bool loaded = _adlPlayer->load(*stream); + + delete stream; + + return loaded; } bool Sound::adlibLoadADL(byte *data, uint32 size, int index) { @@ -267,7 +275,7 @@ bool Sound::adlibLoadMDY(const char *fileName) { return false; if (!_mdyPlayer) - _mdyPlayer = new MDYPlayer(*_vm->_mixer); + _mdyPlayer = new MUSPlayer(*_vm->_mixer); debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName); @@ -277,7 +285,7 @@ bool Sound::adlibLoadMDY(const char *fileName) { return false; } - bool loaded = _mdyPlayer->loadMDY(*stream); + bool loaded = _mdyPlayer->loadMUS(*stream); delete stream; @@ -289,7 +297,7 @@ bool Sound::adlibLoadTBR(const char *fileName) { return false; if (!_mdyPlayer) - _mdyPlayer = new MDYPlayer(*_vm->_mixer); + _mdyPlayer = new MUSPlayer(*_vm->_mixer); Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); if (!stream) { @@ -299,7 +307,7 @@ bool Sound::adlibLoadTBR(const char *fileName) { debugC(1, kDebugSound, "AdLib: Loading MDY instruments (\"%s\")", fileName); - bool loaded = _mdyPlayer->loadTBR(*stream); + bool loaded = _mdyPlayer->loadSND(*stream); delete stream; @@ -316,11 +324,8 @@ void Sound::adlibPlayTrack(const char *trackname) { if (_adlPlayer->isPlaying()) return; - debugC(1, kDebugSound, "AdLib: Playing ADL track \"%s\"", trackname); - - _adlPlayer->unload(); - _adlPlayer->load(trackname); - _adlPlayer->startPlay(); + if (adlibLoadADL(trackname)) + adlibPlay(); } void Sound::adlibPlayBgMusic() { @@ -331,7 +336,7 @@ void Sound::adlibPlayBgMusic() { _adlPlayer = new ADLPlayer(*_vm->_mixer); static const char *const tracksMac[] = { -// "musmac1.adl", // TODO: This track isn't played correctly at all yet +// "musmac1.adl", // This track seems to be missing instruments... "musmac2.adl", "musmac3.adl", "musmac4.adl", @@ -398,13 +403,11 @@ int Sound::adlibGetIndex() const { if (_adlPlayer) return _adlPlayer->getIndex(); - if (_mdyPlayer) - return _mdyPlayer->getIndex(); return -1; } -bool Sound::adlibGetRepeating() const { +int32 Sound::adlibGetRepeating() const { if (!_hasAdLib) return false; diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index 585cf36703..ea7d639ffe 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -32,7 +32,7 @@ class GobEngine; class PCSpeaker; class SoundBlaster; class ADLPlayer; -class MDYPlayer; +class MUSPlayer; class Infogrames; class Protracker; class CDROM; @@ -92,7 +92,7 @@ public: bool adlibIsPlaying() const; int adlibGetIndex() const; - bool adlibGetRepeating() const; + int32 adlibGetRepeating() const; void adlibSetRepeating(int32 repCount); @@ -145,14 +145,23 @@ private: SoundDesc _sounds[kSoundsCount]; + // Speaker PCSpeaker *_pcspeaker; + + // PCM based SoundBlaster *_blaster; + BackgroundAtmosphere *_bgatmos; + + // AdLib + MUSPlayer *_mdyPlayer; ADLPlayer *_adlPlayer; - MDYPlayer *_mdyPlayer; + + // Amiga Paula Infogrames *_infogrames; Protracker *_protracker; + + // Audio CD CDROM *_cdrom; - BackgroundAtmosphere *_bgatmos; }; } // End of namespace Gob -- cgit v1.2.3 From 8548dea13d56e1d69b2f4743361932cf14dd6eee Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 05:09:58 +0200 Subject: GOB: Hook up the MDY player in Fascination --- engines/gob/init_fascin.cpp | 6 +++--- engines/gob/inter_fascin.cpp | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/init_fascin.cpp b/engines/gob/init_fascin.cpp index b87d816406..e6d82faa68 100644 --- a/engines/gob/init_fascin.cpp +++ b/engines/gob/init_fascin.cpp @@ -44,10 +44,10 @@ void Init_Fascination::updateConfig() { } void Init_Fascination::initGame() { -// HACK - Suppress ADLIB_FLAG as the MDY/TBR player is not working. suppress -// the PC Speaker too, as the script checks in the intro for it's presence +// HACK - Suppress +// the PC Speaker, as the script checks in the intro for it's presence // to play or not some noices. - _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG; + _vm->_global->_soundFlags = MIDI_FLAG | BLASTER_FLAG | ADLIB_FLAG; Init::initGame(); } diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp index 081b48fbad..001ec06635 100644 --- a/engines/gob/inter_fascin.cpp +++ b/engines/gob/inter_fascin.cpp @@ -248,12 +248,11 @@ void Inter_Fascination::oFascin_playTira(OpGobParams ¶ms) { void Inter_Fascination::oFascin_loadExtasy(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("extasy.tbr"); _vm->_sound->adlibLoadMDY("extasy.mdy"); + _vm->_sound->adlibSetRepeating(-1); } void Inter_Fascination::oFascin_adlibPlay(OpGobParams ¶ms) { -#ifdef ENABLE_FASCIN_ADLIB _vm->_sound->adlibPlay(); -#endif } void Inter_Fascination::oFascin_adlibStop(OpGobParams ¶ms) { -- cgit v1.2.3 From a64e8a6d30fbef1de52684b75bb6f4536b28d988 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 05:10:24 +0200 Subject: GOB: Hook up the MDY player in Geisha --- engines/gob/init.h | 1 - engines/gob/init_geisha.cpp | 7 ------- engines/gob/inter_geisha.cpp | 5 ++--- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/init.h b/engines/gob/init.h index 946a3fa4f1..ac460fd654 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -62,7 +62,6 @@ public: ~Init_Geisha(); void initVideo(); - void initGame(); }; class Init_v2 : public Init_v1 { diff --git a/engines/gob/init_geisha.cpp b/engines/gob/init_geisha.cpp index b5bbcff400..01081a5af6 100644 --- a/engines/gob/init_geisha.cpp +++ b/engines/gob/init_geisha.cpp @@ -44,11 +44,4 @@ void Init_Geisha::initVideo() { _vm->_draw->_transparentCursor = 1; } -void Init_Geisha::initGame() { - // HACK - Since the MDY/TBR player is not working, claim we have no AdLib - _vm->_global->_soundFlags = 0; - - Init::initGame(); -} - } // End of namespace Gob diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 75204a3f55..8a4d4246b6 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -298,9 +298,8 @@ void Inter_Geisha::oGeisha_loadTitleMusic(OpGobParams ¶ms) { } void Inter_Geisha::oGeisha_playMusic(OpGobParams ¶ms) { - // TODO: The MDYPlayer is still broken! - warning("Geisha Stub: oGeisha_playMusic"); - // _vm->_sound->adlibPlay(); + _vm->_sound->adlibSetRepeating(-1); + _vm->_sound->adlibPlay(); } void Inter_Geisha::oGeisha_stopMusic(OpGobParams ¶ms) { -- cgit v1.2.3 From fe44939eba096bad083254b1c5152ef070ac4dc8 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 06:11:53 +0200 Subject: GOB: Play the music on the title screen of Gob1 EGA The EGA version of Gobliiins comes with an MDY track. While the original doesn't play it, we thought it might be a nice idea to play it nevertheless. --- engines/gob/detection_tables.h | 4 ++-- engines/gob/inter_v1.cpp | 34 +++++++++++++++++++++++++-- engines/gob/sound/adlib.h | 6 ++--- engines/gob/sound/sound.cpp | 53 ++++++++++++++++++++++++++++++------------ engines/gob/sound/sound.h | 4 ++++ 5 files changed, 79 insertions(+), 22 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index 7aa58b9b97..77b54a19cd 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -34,7 +34,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, kGameTypeGob1, - kFeaturesEGA, + kFeaturesEGA | kFeaturesAdLib, 0, 0, 0 }, { @@ -48,7 +48,7 @@ static const GOBGameDescription gameDescriptions[] = { GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, kGameTypeGob1, - kFeaturesEGA, + kFeaturesEGA | kFeaturesAdLib, 0, 0, 0 }, { // Supplied by Theruler76 in bug report #1201233 diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 4aa54f720b..6fc472a0ac 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -286,10 +286,40 @@ void Inter_v1::o1_loadMult() { } void Inter_v1::o1_playMult() { - int16 checkEscape; + // NOTE: The EGA version of Gobliiins has an MDY tune. + // While the original doesn't play it, we do. + bool isGob1EGAIntro = _vm->getGameType() == kGameTypeGob1 && + _vm->isEGA() && + _vm->_game->_script->pos() == 1010 && + _vm->isCurrentTot("intro.tot") && + VAR(57) != 0xFFFFFFFF && + _vm->_dataIO->hasFile("goblins.mdy") && + _vm->_dataIO->hasFile("goblins.tbr"); + + int16 checkEscape = _vm->_game->_script->readInt16(); + + if (isGob1EGAIntro) { + _vm->_sound->adlibLoadTBR("goblins.tbr"); + _vm->_sound->adlibLoadMDY("goblins.mdy"); + _vm->_sound->adlibSetRepeating(-1); + + _vm->_sound->adlibPlay(); + } - checkEscape = _vm->_game->_script->readInt16(); _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); + + if (isGob1EGAIntro) { + + // User didn't escape the intro mult, wait for an escape here + if (VAR(57) != 0xFFFFFFFF) { + while (_vm->_util->getKey() != kKeyEscape) { + _vm->_util->processInput(); + _vm->_util->longDelay(1); + } + } + + _vm->_sound->adlibUnload(); + } } void Inter_v1::o1_freeMultKeys() { diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index df1b77fd4d..17ab950752 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -20,8 +20,8 @@ * */ -#ifndef GOB_SOUND_NEWADLIB_H -#define GOB_SOUND_NEWADLIB_H +#ifndef GOB_SOUND_ADLIB_H +#define GOB_SOUND_ADLIB_H #include "common/mutex.h" @@ -303,4 +303,4 @@ private: } // End of namespace Gob -#endif // GOB_SOUND_NEWADLIB_H +#endif // GOB_SOUND_ADLIB_H diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index f14e9b150a..9f72d1a98f 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -51,6 +51,8 @@ Sound::Sound(GobEngine *vm) : _vm(vm) { _hasAdLib = (!_vm->_noMusic && _vm->hasAdLib()); + _hasAdLibBg = _hasAdLib; + if (!_vm->_noMusic && (_vm->getPlatform() == Common::kPlatformAmiga)) { _infogrames = new Infogrames(*_vm->_mixer); _protracker = new Protracker(*_vm->_mixer); @@ -274,8 +276,7 @@ bool Sound::adlibLoadMDY(const char *fileName) { if (!_hasAdLib) return false; - if (!_mdyPlayer) - _mdyPlayer = new MUSPlayer(*_vm->_mixer); + createMDYPlayer(); debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName); @@ -296,8 +297,7 @@ bool Sound::adlibLoadTBR(const char *fileName) { if (!_hasAdLib) return false; - if (!_mdyPlayer) - _mdyPlayer = new MUSPlayer(*_vm->_mixer); + createMDYPlayer(); Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName); if (!stream) { @@ -318,8 +318,7 @@ void Sound::adlibPlayTrack(const char *trackname) { if (!_hasAdLib) return; - if (!_adlPlayer) - _adlPlayer = new ADLPlayer(*_vm->_mixer); + createADLPlayer(); if (_adlPlayer->isPlaying()) return; @@ -329,11 +328,10 @@ void Sound::adlibPlayTrack(const char *trackname) { } void Sound::adlibPlayBgMusic() { - if (!_hasAdLib) + if (!_hasAdLib || _hasAdLibBg) return; - if (!_adlPlayer) - _adlPlayer = new ADLPlayer(*_vm->_mixer); + createADLPlayer(); static const char *const tracksMac[] = { // "musmac1.adl", // This track seems to be missing instruments... @@ -352,13 +350,18 @@ void Sound::adlibPlayBgMusic() { "musmac5.mid" }; - if (_vm->getPlatform() == Common::kPlatformWindows) { - int track = _vm->_util->getRandom(ARRAYSIZE(tracksWin)); - adlibPlayTrack(tracksWin[track]); - } else { - int track = _vm->_util->getRandom(ARRAYSIZE(tracksMac)); - adlibPlayTrack(tracksMac[track]); + const char *track = 0; + if (_vm->getPlatform() == Common::kPlatformWindows) + track = tracksWin[ARRAYSIZE(tracksWin)]; + else + track = tracksMac[_vm->_util->getRandom(ARRAYSIZE(tracksMac))]; + + if (!track || !_vm->_dataIO->hasFile(track)) { + _hasAdLibBg = false; + return; } + + adlibPlayTrack(track); } void Sound::adlibPlay() { @@ -722,4 +725,24 @@ void Sound::bgUnshade() { _bgatmos->unshade(); } +void Sound::createMDYPlayer() { + if (_mdyPlayer) + return; + + delete _adlPlayer; + _adlPlayer = 0; + + _mdyPlayer = new MUSPlayer(*_vm->_mixer); +} + +void Sound::createADLPlayer() { + if (_adlPlayer) + return; + + delete _mdyPlayer; + _mdyPlayer= 0; + + _adlPlayer = new ADLPlayer(*_vm->_mixer); +} + } // End of namespace Gob diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index ea7d639ffe..064a249253 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -142,6 +142,7 @@ private: GobEngine *_vm; bool _hasAdLib; + bool _hasAdLibBg; SoundDesc _sounds[kSoundsCount]; @@ -162,6 +163,9 @@ private: // Audio CD CDROM *_cdrom; + + void createMDYPlayer(); + void createADLPlayer(); }; } // End of namespace Gob -- cgit v1.2.3 From f538b7658684aad26a38b2e3685a322ecc14a720 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 14:59:12 +0200 Subject: GOB: Don't recalculate the AdLib frequencies table on every player reset --- engines/gob/sound/adlib.cpp | 8 +++++++- engines/gob/sound/adlib.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index 3f46f6cf4b..d9fc362547 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -98,6 +98,8 @@ AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0), _rate = _mixer->getOutputRate(); + initFreqs(); + createOPL(); initOPL(); @@ -295,7 +297,7 @@ void AdLib::initOPL() { _opl->reset(); initOperatorVolumes(); - initFreqs(); + resetFreqs(); setPercussionMode(false); @@ -581,6 +583,10 @@ void AdLib::initFreqs() { for (int i = 0; i < kPitchStepCount; i++) setFreqs(_freqs[i], i * numStep, 100); + resetFreqs(); +} + +void AdLib::resetFreqs() { for (int i = 0; i < kMaxVoiceCount; i++) { _freqPtr [i] = _freqs[0]; _halfToneOffset[i] = 0; diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 17ab950752..bd1778d2ed 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -295,6 +295,7 @@ private: void initFreqs(); void setFreqs(uint16 *freqs, int32 num, int32 denom); int32 calcFreq(int32 deltaDemiToneNum, int32 deltaDemiToneDenom); + void resetFreqs(); void changePitch(uint8 voice, uint16 pitchBend); -- cgit v1.2.3 From a3db17033f9b251760e76d4ba7c7e66003cc228d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 15:07:01 +0200 Subject: GOB: Update list of games in the comment --- engines/gob/gob.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/gob.h b/engines/gob/gob.h index ea2323807a..6277585015 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -50,6 +50,10 @@ class StaticTextWidget; * - Bargon Attack * - Lost in Time * - The Bizarre Adventures of Woodruff and the Schnibble + * - Fascination + * - Urban Runner + * - Bambou le sauveur de la jungle + * - Geisha */ namespace Gob { -- cgit v1.2.3 From f87e8b53f333c6799302d620a2c36668b92c77f0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 11 Jun 2012 15:09:48 +0200 Subject: GOB: Fix an AmigaOS compile error Should close bug #3534287. --- engines/gob/minigames/geisha/meter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/meter.cpp b/engines/gob/minigames/geisha/meter.cpp index 719ecf3d18..7ec3119866 100644 --- a/engines/gob/minigames/geisha/meter.cpp +++ b/engines/gob/minigames/geisha/meter.cpp @@ -67,7 +67,7 @@ int32 Meter::increase(int32 n) { if (n < 0) return decrease(-n); - int32 overflow = MAX(0, (_value + n) - _maxValue); + int32 overflow = MAX(0, (_value + n) - _maxValue); int32 value = CLIP(_value + n, 0, _maxValue); if (_value == value) @@ -83,7 +83,7 @@ int32 Meter::decrease(int32 n) { if (n < 0) return increase(-n); - int32 underflow = -MIN(0, _value - n); + int32 underflow = -MIN(0, _value - n); int32 value = CLIP(_value - n, 0, _maxValue); if (_value == value) -- cgit v1.2.3 From 198c116061d58c19e5a0bd97f47925bb7d585923 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 14:40:33 +0200 Subject: GOB: Fix stupid typo/bug I introduced in 2007 Luckily, it apparently didn't have any visible symptoms... --- engines/gob/mult.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index 06a7130cef..b3d7ea6263 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -366,10 +366,11 @@ void Mult::doPalAnim() { palPtr->blue, 0, 0x13); palPtr = _vm->_global->_pPaletteDesc->vgaPal; - for (_counter = 0; _counter < 16; _counter++, palPtr++) + for (_counter = 0; _counter < 16; _counter++, palPtr++) { _vm->_global->_redPalette[_counter] = palPtr->red; _vm->_global->_greenPalette[_counter] = palPtr->green; _vm->_global->_bluePalette[_counter] = palPtr->blue; + } } else _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -- cgit v1.2.3 From ccad083ab905b1e708bc9b7b3db501c9f1f028ab Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 15:24:49 +0200 Subject: GOB: Fix a "condition depends on uninitialised value" in Geisha --- engines/gob/palanim.cpp | 93 +++++++++++++------------------------------------ 1 file changed, 24 insertions(+), 69 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp index 8a5327c3f1..f90b141725 100644 --- a/engines/gob/palanim.cpp +++ b/engines/gob/palanim.cpp @@ -75,47 +75,28 @@ bool PalAnim::fadeStepColor(int color) { bool PalAnim::fadeStep(int16 oper) { bool stop = true; - byte newRed; - byte newGreen; - byte newBlue; if (oper == 0) { - if (_vm->_global->_setAllPalette) { - if (_vm->_global->_inVM != 0) - error("PalAnim::fadeStep(): _vm->_global->_inVM != 0 not supported"); - - for (int i = 0; i < 256; i++) { - newRed = fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]); - newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]); - newBlue = fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]); - - if ((_vm->_global->_redPalette[i] != newRed) || - (_vm->_global->_greenPalette[i] != newGreen) || - (_vm->_global->_bluePalette[i] != newBlue)) { - - _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13); - - _vm->_global->_redPalette[i] = newRed; - _vm->_global->_greenPalette[i] = newGreen; - _vm->_global->_bluePalette[i] = newBlue; - stop = false; - } - } - } else { - for (int i = 0; i < 16; i++) { - - _vm->_video->setPalElem(i, - fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]), - fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]), - fadeColor(_vm->_global->_bluePalette[i], _toFadeBlue[i]), - -1, _vm->_global->_videoMode); - - if ((_vm->_global->_redPalette[i] != _toFadeRed[i]) || - (_vm->_global->_greenPalette[i] != _toFadeGreen[i]) || - (_vm->_global->_bluePalette[i] != _toFadeBlue[i])) - stop = false; + int colorCount = _vm->_global->_setAllPalette ? _vm->_global->_colorCount : 256; + + for (int i = 0; i < colorCount; i++) { + byte newRed = fadeColor(_vm->_global->_redPalette [i], _toFadeRed [i]); + byte newGreen = fadeColor(_vm->_global->_greenPalette[i], _toFadeGreen[i]); + byte newBlue = fadeColor(_vm->_global->_bluePalette [i], _toFadeBlue [i]); + + if ((_vm->_global->_redPalette [i] != newRed ) || + (_vm->_global->_greenPalette[i] != newGreen) || + (_vm->_global->_bluePalette [i] != newBlue)) { + + _vm->_video->setPalElem(i, newRed, newGreen, newBlue, 0, 0x13); + + _vm->_global->_redPalette [i] = newRed; + _vm->_global->_greenPalette[i] = newGreen; + _vm->_global->_bluePalette [i] = newBlue; + stop = false; } } + } else if ((oper > 0) && (oper < 4)) stop = fadeStepColor(oper - 1); @@ -124,44 +105,18 @@ bool PalAnim::fadeStep(int16 oper) { void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { bool stop; - int16 i; if (_vm->shouldQuit()) return; _fadeValue = (fadeV < 0) ? -fadeV : 2; - if (!_vm->_global->_setAllPalette) { - if (!palDesc) { - for (i = 0; i < 16; i++) { - _toFadeRed[i] = 0; - _toFadeGreen[i] = 0; - _toFadeBlue[i] = 0; - } - } else { - for (i = 0; i < 16; i++) { - _toFadeRed[i] = palDesc->vgaPal[i].red; - _toFadeGreen[i] = palDesc->vgaPal[i].green; - _toFadeBlue[i] = palDesc->vgaPal[i].blue; - } - } - } else { - if (_vm->_global->_inVM != 0) - error("PalAnim::fade(): _vm->_global->_inVM != 0 is not supported"); - - if (!palDesc) { - for (i = 0; i < 256; i++) { - _toFadeRed[i] = 0; - _toFadeGreen[i] = 0; - _toFadeBlue[i] = 0; - } - } else { - for (i = 0; i < 256; i++) { - _toFadeRed[i] = palDesc->vgaPal[i].red; - _toFadeGreen[i] = palDesc->vgaPal[i].green; - _toFadeBlue[i] = palDesc->vgaPal[i].blue; - } - } + int colorCount = _vm->_global->_setAllPalette ? _vm->_global->_colorCount : 256; + + for (int i = 0; i < colorCount; i++) { + _toFadeRed [i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].red; + _toFadeGreen[i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].green; + _toFadeBlue [i] = (palDesc == 0) ? 0 : palDesc->vgaPal[i].blue; } if (allColors == 0) { -- cgit v1.2.3 From 0e6fb437799ba8f35776c59c02a02d59a99a71cf Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 15:27:37 +0200 Subject: GOB: Remove useless variable --- engines/gob/global.cpp | 1 - engines/gob/global.h | 1 - engines/gob/init_v1.cpp | 2 -- engines/gob/init_v2.cpp | 2 -- 4 files changed, 6 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index 1264c09860..87656a5fad 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -111,7 +111,6 @@ Global::Global(GobEngine *vm) : _vm(vm) { _dontSetPalette = false; _debugFlag = 0; - _inVM = 0; _inter_animDataSize = 10; diff --git a/engines/gob/global.h b/engines/gob/global.h index fa2f2c9637..175331dd83 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -127,7 +127,6 @@ public: SurfacePtr _primarySurfDesc; int16 _debugFlag; - int16 _inVM; int16 _inter_animDataSize; diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp index 25d521aca6..a8e8cbe2c3 100644 --- a/engines/gob/init_v1.cpp +++ b/engines/gob/init_v1.cpp @@ -41,8 +41,6 @@ void Init_v1::initVideo() { _vm->_global->_mousePresent = 1; - _vm->_global->_inVM = 0; - if ((_vm->_global->_videoMode == 0x13) && !_vm->isEGA()) _vm->_global->_colorCount = 256; diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp index 1289d561ea..c204b04a40 100644 --- a/engines/gob/init_v2.cpp +++ b/engines/gob/init_v2.cpp @@ -45,8 +45,6 @@ void Init_v2::initVideo() { _vm->_global->_mousePresent = 1; - _vm->_global->_inVM = 0; - _vm->_global->_colorCount = 16; if (!_vm->isEGA() && ((_vm->getPlatform() == Common::kPlatformPC) || -- cgit v1.2.3 From 5ae4ed09ea9b0ffd4ef00e55eb1f738103fdeeeb Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 15:33:30 +0200 Subject: GOB: Fix an uninitialised value in Geisha's Penetration --- engines/gob/minigames/geisha/submarine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/submarine.cpp b/engines/gob/minigames/geisha/submarine.cpp index d16761cb7c..bf15306e5a 100644 --- a/engines/gob/minigames/geisha/submarine.cpp +++ b/engines/gob/minigames/geisha/submarine.cpp @@ -51,7 +51,7 @@ enum Animation { }; -Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove) { +Submarine::Submarine(const ANIFile &ani) : ANIObject(ani), _state(kStateMove), _direction(kDirectionNone) { turn(kDirectionN); } -- cgit v1.2.3 From 3b8b3c4caffc8a19a7ad4c4fa55bad712f0e5fce Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 14 Jun 2012 23:39:33 +0200 Subject: GOB: Fix a failed assert in Litte Red Riding Hood --- engines/gob/inter_v1.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 6fc472a0ac..3652637e32 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1584,14 +1584,13 @@ void Inter_v1::o1_waitEndPlay(OpFuncParams ¶ms) { } void Inter_v1::o1_playComposition(OpFuncParams ¶ms) { - int16 composition[50]; - int16 dataVar; - int16 freqVal; + int16 dataVar = _vm->_game->_script->readVarIndex(); + int16 freqVal = _vm->_game->_script->readValExpr(); - dataVar = _vm->_game->_script->readVarIndex(); - freqVal = _vm->_game->_script->readValExpr(); + int16 composition[50]; + int maxEntries = MIN(50, (_variables->getSize() - dataVar) / 4); for (int i = 0; i < 50; i++) - composition[i] = (int16) VAR_OFFSET(dataVar + i * 4); + composition[i] = (i < maxEntries) ? ((int16) VAR_OFFSET(dataVar + i * 4)) : -1; _vm->_sound->blasterPlayComposition(composition, freqVal); } -- cgit v1.2.3 From 59b2a84552ae4f64e3e6ddc8b29ecda4f3dd524d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 00:51:03 +0200 Subject: GOB: Add a proper GameType for Little Red --- engines/gob/detection_tables.h | 32 ++++++++++++++++---------------- engines/gob/gob.cpp | 1 + engines/gob/gob.h | 3 ++- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index 77b54a19cd..bd35900473 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -1615,7 +1615,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1629,7 +1629,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1643,7 +1643,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1657,7 +1657,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1671,7 +1671,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1689,7 +1689,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesNone, 0, 0, 0 }, @@ -1703,7 +1703,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1717,7 +1717,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1731,7 +1731,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1745,7 +1745,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1759,7 +1759,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1773,7 +1773,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1787,7 +1787,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1801,7 +1801,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1815,7 +1815,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, @@ -1829,7 +1829,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeLittleRed, kFeaturesAdLib | kFeaturesEGA, 0, 0, 0 }, diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 4e7aa467b5..acd8fcb468 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -438,6 +438,7 @@ bool GobEngine::initGameParts() { break; case kGameTypeWeen: + case kGameTypeLittleRed: case kGameTypeGob2: _init = new Init_v2(this); _video = new Video_v2(this); diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 6277585015..165760e6d5 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -127,7 +127,8 @@ enum GameType { kGameTypeAdi2, kGameTypeAdi4, kGameTypeAdibou2, - kGameTypeAdibou1 + kGameTypeAdibou1, + kGameTypeLittleRed }; enum Features { -- cgit v1.2.3 From f16cc050e97de6339347a650b9a801153dc7ad91 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 00:56:55 +0200 Subject: GOB: Add class Inter_LittleRed This fixes the crash when selecting an animal in the "Languages" screen. Interestingly, the German names of the animals are partially wrong... And for "Das Schmetterling" (sic!), even the recorded speech sample is wrong. --- engines/gob/gob.cpp | 12 +++++++++- engines/gob/inter.h | 11 +++++++++ engines/gob/inter_littlered.cpp | 49 +++++++++++++++++++++++++++++++++++++++++ engines/gob/inter_v2.cpp | 6 ++--- engines/gob/module.mk | 1 + 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 engines/gob/inter_littlered.cpp (limited to 'engines/gob') diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index acd8fcb468..a13f6a372f 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -438,7 +438,6 @@ bool GobEngine::initGameParts() { break; case kGameTypeWeen: - case kGameTypeLittleRed: case kGameTypeGob2: _init = new Init_v2(this); _video = new Video_v2(this); @@ -463,6 +462,17 @@ bool GobEngine::initGameParts() { _saveLoad = new SaveLoad_v2(this, _targetName.c_str()); break; + case kGameTypeLittleRed: + _init = new Init_v2(this); + _video = new Video_v2(this); + _inter = new Inter_LittleRed(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); + break; + case kGameTypeGob3: _init = new Init_v3(this); _video = new Video_v2(this); diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 1e6f74db4e..907a275e50 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -513,6 +513,17 @@ protected: void oFascin_setWinFlags(); }; +class Inter_LittleRed : public Inter_v2 { +public: + Inter_LittleRed(GobEngine *vm); + virtual ~Inter_LittleRed() {} + +protected: + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); +}; + class Inter_v3 : public Inter_v2 { public: Inter_v3(GobEngine *vm); diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp new file mode 100644 index 0000000000..6a63998216 --- /dev/null +++ b/engines/gob/inter_littlered.cpp @@ -0,0 +1,49 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/gob.h" +#include "gob/inter.h" + +namespace Gob { + +#define OPCODEVER Inter_LittleRed +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) + +Inter_LittleRed::Inter_LittleRed(GobEngine *vm) : Inter_v2(vm) { +} + +void Inter_LittleRed::setupOpcodesDraw() { + Inter_v2::setupOpcodesDraw(); +} + +void Inter_LittleRed::setupOpcodesFunc() { + Inter_v2::setupOpcodesFunc(); +} + +void Inter_LittleRed::setupOpcodesGob() { + OPCODEGOB(500, o2_playProtracker); + OPCODEGOB(501, o2_stopProtracker); +} + +} // End of namespace Gob diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 54f6a1acc1..cb58fe86f7 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1248,7 +1248,7 @@ void Inter_v2::o2_checkData(OpFuncParams ¶ms) { file = "EMAP2011.TOT"; int32 size = -1; - SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file.c_str()); + SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(file.c_str()) : SaveLoad::kSaveModeNone; if (mode == SaveLoad::kSaveModeNone) { size = _vm->_dataIO->fileSize(file); @@ -1277,7 +1277,7 @@ void Inter_v2::o2_readData(OpFuncParams ¶ms) { debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)", file, dataVar, size, offset); - SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file); + SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(file) : SaveLoad::kSaveModeNone; if (mode == SaveLoad::kSaveModeSave) { WRITE_VAR(1, 1); @@ -1349,7 +1349,7 @@ void Inter_v2::o2_writeData(OpFuncParams ¶ms) { WRITE_VAR(1, 1); - SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file); + SaveLoad::SaveMode mode = _vm->_saveLoad ? _vm->_saveLoad->getSaveMode(file) : SaveLoad::kSaveModeNone; if (mode == SaveLoad::kSaveModeSave) { if (!_vm->_saveLoad->save(file, dataVar, size, offset)) { diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 7c5d7de158..20214ea940 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -44,6 +44,7 @@ MODULE_OBJS := \ inter_v2.o \ inter_bargon.o \ inter_fascin.o \ + inter_littlered.o \ inter_inca2.o \ inter_playtoons.o \ inter_v3.o \ -- cgit v1.2.3 From 7632246264102d88922fc963284af6250ea12f57 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 13:32:43 +0200 Subject: GOB: Implement Util::getKeyState() for Little Red This makes the bees level playable, removing the "lock-up". Collision detection between Little Red and the bees and butterflies doesn't work yet though, so they're just flying through her. Nevertheless, the game seems to be completable now. --- engines/gob/inter.cpp | 12 +++++++++ engines/gob/inter.h | 9 +++++-- engines/gob/inter_littlered.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ engines/gob/inter_v1.cpp | 16 +++--------- engines/gob/util.cpp | 40 +++++++++++++++++++++++++++- engines/gob/util.h | 8 ++++++ 6 files changed, 128 insertions(+), 15 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 9df3c06c74..843c0bff48 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -52,6 +52,7 @@ Inter::Inter(GobEngine *vm) : _vm(vm), _varStack(600) { _soundEndTimeKey = 0; _soundStopVal = 0; + _lastBusyWait = 0; _noBusyWait = false; _variables = 0; @@ -452,4 +453,15 @@ uint32 Inter::readValue(uint16 index, uint16 type) { return 0; } +void Inter::handleBusyWait() { + uint32 now = _vm->_util->getTimeKey(); + + if (!_noBusyWait) + if ((now - _lastBusyWait) <= 20) + _vm->_util->longDelay(1); + + _lastBusyWait = now; + _noBusyWait = false; +} + } // End of namespace Gob diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 907a275e50..0625646cdd 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -142,8 +142,9 @@ protected: VariableStack _varStack; - // The busy-wait detection in o1_keyFunc breaks fast scrolling in Ween - bool _noBusyWait; + // Busy-wait detection + bool _noBusyWait; + uint32 _lastBusyWait; GobEngine *_vm; @@ -172,6 +173,8 @@ protected: void storeString(const char *value); uint32 readValue(uint16 index, uint16 type); + + void handleBusyWait(); }; class Inter_v1 : public Inter { @@ -522,6 +525,8 @@ protected: virtual void setupOpcodesDraw(); virtual void setupOpcodesFunc(); virtual void setupOpcodesGob(); + + void oLittleRed_keyFunc(OpFuncParams ¶ms); }; class Inter_v3 : public Inter_v2 { diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 6a63998216..01d372aaeb 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -22,6 +22,13 @@ #include "gob/gob.h" #include "gob/inter.h" +#include "gob/global.h" +#include "gob/util.h" +#include "gob/draw.h" +#include "gob/game.h" +#include "gob/script.h" +#include "gob/hotspots.h" +#include "gob/sound/sound.h" namespace Gob { @@ -39,6 +46,8 @@ void Inter_LittleRed::setupOpcodesDraw() { void Inter_LittleRed::setupOpcodesFunc() { Inter_v2::setupOpcodesFunc(); + + OPCODEFUNC(0x14, oLittleRed_keyFunc); } void Inter_LittleRed::setupOpcodesGob() { @@ -46,4 +55,53 @@ void Inter_LittleRed::setupOpcodesGob() { OPCODEGOB(501, o2_stopProtracker); } +void Inter_LittleRed::oLittleRed_keyFunc(OpFuncParams ¶ms) { + animPalette(); + _vm->_draw->blitInvalidated(); + + handleBusyWait(); + + int16 cmd = _vm->_game->_script->readInt16(); + int16 key; + uint32 keyState; + + switch (cmd) { + case -1: + break; + + case 0: + _vm->_draw->_showCursor &= ~2; + _vm->_util->longDelay(1); + key = _vm->_game->_hotspots->check(0, 0); + storeKey(key); + + _vm->_util->clearKeyBuf(); + break; + + case 1: + _vm->_util->forceMouseUp(true); + key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); + storeKey(key); + break; + + case 2: + _vm->_util->processInput(true); + keyState = _vm->_util->getKeyState(); + + WRITE_VAR(0, keyState); + _vm->_util->clearKeyBuf(); + break; + + default: + _vm->_sound->speakerOnUpdate(cmd); + if (cmd < 20) { + _vm->_util->delay(cmd); + _noBusyWait = true; + } else + _vm->_util->longDelay(cmd); + break; + } +} + } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 3652637e32..dc533a210a 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1189,26 +1189,15 @@ void Inter_v1::o1_palLoad(OpFuncParams ¶ms) { } void Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { - static uint32 lastCalled = 0; - int16 cmd; - int16 key; - uint32 now; - if (!_vm->_vidPlayer->isPlayingLive()) { _vm->_draw->forceBlit(); _vm->_video->retrace(); } - cmd = _vm->_game->_script->readInt16(); animPalette(); _vm->_draw->blitInvalidated(); - now = _vm->_util->getTimeKey(); - if (!_noBusyWait) - if ((now - lastCalled) <= 20) - _vm->_util->longDelay(1); - lastCalled = now; - _noBusyWait = false; + handleBusyWait(); // WORKAROUND for bug #1726130: Ween busy-waits in the intro for a counter // to become 5000. We deliberately slow down busy-waiting, so we shorten @@ -1217,6 +1206,9 @@ void Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { (_vm->_game->_script->pos() == 729) && _vm->isCurrentTot("intro5.tot")) WRITE_VAR(59, 4000); + int16 cmd = _vm->_game->_script->readInt16(); + int16 key; + switch (cmd) { case -1: break; diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 7f9c6131fd..64dfcf9b12 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -21,7 +21,6 @@ */ #include "common/stream.h" -#include "common/events.h" #include "graphics/palette.h" @@ -45,6 +44,8 @@ Util::Util(GobEngine *vm) : _vm(vm) { _frameRate = 12; _frameWaitTime = 0; _startFrameTime = 0; + + _keyState = 0; } uint32 Util::getTimeKey() { @@ -116,6 +117,8 @@ void Util::processInput(bool scroll) { _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsRight)); break; case Common::EVENT_KEYDOWN: + keyDown(event); + if (event.kbd.hasFlags(Common::KBD_CTRL)) { if (event.kbd.keycode == Common::KEYCODE_f) _fastMode ^= 1; @@ -132,6 +135,7 @@ void Util::processInput(bool scroll) { addKeyToBuffer(event.kbd); break; case Common::EVENT_KEYUP: + keyUp(event); break; default: break; @@ -576,4 +580,38 @@ void Util::checkJoystick() { _vm->_global->_useJoystick = 0; } +uint32 Util::getKeyState() const { + return _keyState; +} + +void Util::keyDown(const Common::Event &event) { + if (event.kbd.keycode == Common::KEYCODE_UP) + _keyState |= 0x0001; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keyState |= 0x0002; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keyState |= 0x0004; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keyState |= 0x0008; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keyState |= 0x0020; + else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + _keyState |= 0x0040; +} + +void Util::keyUp(const Common::Event &event) { + if (event.kbd.keycode == Common::KEYCODE_UP) + _keyState &= ~0x0001; + else if (event.kbd.keycode == Common::KEYCODE_DOWN) + _keyState &= ~0x0002; + else if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _keyState &= ~0x0004; + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _keyState &= ~0x0008; + else if (event.kbd.keycode == Common::KEYCODE_SPACE) + _keyState &= ~0x0020; + else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) + _keyState &= ~0x0040; +} + } // End of namespace Gob diff --git a/engines/gob/util.h b/engines/gob/util.h index 4228dac768..b26a78ab2c 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -25,6 +25,7 @@ #include "common/str.h" #include "common/keyboard.h" +#include "common/events.h" namespace Common { class SeekableReadStream; @@ -110,6 +111,8 @@ public: bool checkKey(int16 &key); bool keyPressed(); + uint32 getKeyState() const; + void getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons); void setMousePos(int16 x, int16 y); void waitMouseUp(); @@ -155,6 +158,8 @@ protected: int16 _frameWaitTime; uint32 _startFrameTime; + uint32 _keyState; + GobEngine *_vm; bool keyBufferEmpty(); @@ -162,6 +167,9 @@ protected: bool getKeyFromBuffer(Common::KeyState &key); int16 translateKey(const Common::KeyState &key); void checkJoystick(); + + void keyDown(const Common::Event &event); + void keyUp(const Common::Event &event); }; } // End of namespace Gob -- cgit v1.2.3 From 5961609a56a910d81d38389c6ac61d06eca6f029 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Jun 2012 15:09:01 +0200 Subject: GOB: Add a resource size workaround for Little Red This fixes the missing resources in the screen where Little Red has to find the animals' homes for them. --- engines/gob/gob.cpp | 10 ++++++++++ engines/gob/gob.h | 4 ++++ engines/gob/resources.cpp | 12 ++++++++++-- engines/gob/resources.h | 6 +++--- 4 files changed, 27 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index a13f6a372f..f3480fed99 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -233,6 +233,10 @@ bool GobEngine::isDemo() const { return (isSCNDemo() || isBATDemo()); } +bool GobEngine::hasResourceSizeWorkaround() const { + return _resourceSizeWorkaround; +} + bool GobEngine::isCurrentTot(const Common::String &tot) const { return _game->_curTotFile.equalsIgnoreCase(tot); } @@ -389,6 +393,8 @@ void GobEngine::pauseGame() { } bool GobEngine::initGameParts() { + _resourceSizeWorkaround = false; + // just detect some devices some of which will be always there if the music is not disabled _noMusic = MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB)) == MT_NULL ? true : false; _saveLoad = 0; @@ -471,6 +477,10 @@ bool GobEngine::initGameParts() { _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); + + // WORKAROUND: Little Red Riding Hood has a small resource size glitch in the + // screen where Little Red needs to find the animals' homes. + _resourceSizeWorkaround = true; break; case kGameTypeGob3: diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 165760e6d5..19489e4924 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -200,6 +200,8 @@ public: GobConsole *_console; + bool _resourceSizeWorkaround; + Global *_global; Util *_util; DataIO *_dataIO; @@ -236,6 +238,8 @@ public: bool isTrueColor() const; bool isDemo() const; + bool hasResourceSizeWorkaround() const; + bool isCurrentTot(const Common::String &tot) const; void setTrueColor(bool trueColor); diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp index d5497c25be..a84f4ac4b8 100644 --- a/engines/gob/resources.cpp +++ b/engines/gob/resources.cpp @@ -716,7 +716,7 @@ byte *Resources::getIMData(TOTResourceItem &totItem) const { return _imData + offset; } -byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { +byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 &size) const { Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_extFile); if (!stream) return 0; @@ -726,6 +726,10 @@ byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { return 0; } + // If that workaround is active, limit the resource size instead of throwing an error + if (_vm->hasResourceSizeWorkaround()) + size = MIN(size, stream->size() - extItem.offset); + byte *data = new byte[extItem.packed ? (size + 2) : size]; if (stream->read(data, size) != size) { delete[] data; @@ -737,7 +741,7 @@ byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { return data; } -byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const { +byte *Resources::getEXData(EXTResourceItem &extItem, uint32 &size) const { Common::SeekableReadStream *stream = _vm->_dataIO->getFile(_exFile); if (!stream) return 0; @@ -747,6 +751,10 @@ byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const { return 0; } + // If that workaround is active, limit the resource size instead of throwing an error + if (_vm->hasResourceSizeWorkaround()) + size = MIN(size, stream->size() - extItem.offset); + byte *data = new byte[extItem.packed ? (size + 2) : size]; if (stream->read(data, size) != size) { delete[] data; diff --git a/engines/gob/resources.h b/engines/gob/resources.h index 39155c5176..04b3b9d31e 100644 --- a/engines/gob/resources.h +++ b/engines/gob/resources.h @@ -103,7 +103,7 @@ private: static const int kTOTTextItemSize = 2 + 2; enum ResourceType { - kResourceTOT, + kResourceTOT = 0, kResourceIM, kResourceEXT, kResourceEX @@ -201,8 +201,8 @@ private: byte *getTOTData(TOTResourceItem &totItem) const; byte *getIMData(TOTResourceItem &totItem) const; - byte *getEXTData(EXTResourceItem &extItem, uint32 size) const; - byte *getEXData(EXTResourceItem &extItem, uint32 size) const; + byte *getEXTData(EXTResourceItem &extItem, uint32 &size) const; + byte *getEXData(EXTResourceItem &extItem, uint32 &size) const; }; } // End of namespace Gob -- cgit v1.2.3 From 1666d9da824c7e217fba19bcd694cc878b3d65bb Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 01:39:14 +0200 Subject: GOB: Fix mult object collision detection I broke in 2007 This fixes the sidescroller levels (like the bees and butterflies) in Little Red. I really wonder if this breakage had other effects too... --- engines/gob/mult_v2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 6593565e6a..64b9d19e33 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -1082,7 +1082,7 @@ void Mult_v2::animate() { continue; for (int j = 0; j < numAnims; j++) { - Mult_Object &animObj2 = *_renderObjs[i]; + Mult_Object &animObj2 = *_renderObjs[j]; Mult_AnimData &animData2 = *(animObj2.pAnimData); if (i == j) -- cgit v1.2.3 From 54f7d9c557e1560170256e89ac9c20a1d6be8640 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 01:44:57 +0200 Subject: GOB: Use the full title for Little Red Riding Hood While the other parts in the series are mostly hard-coded, they are small, simple and monotone enough that I might just think about implementing them some day... --- engines/gob/detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 17a2ae3da8..861cc95d41 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -50,7 +50,7 @@ static const PlainGameDescriptor gobGames[] = { {"gob2cd", "Gobliins 2 CD"}, {"ween", "Ween: The Prophecy"}, {"bargon", "Bargon Attack"}, - {"littlered", "Little Red Riding Hood"}, + {"littlered", "Once Upon A Time: Little Red Riding Hood"}, {"ajworld", "A.J's World of Discovery"}, {"gob3", "Goblins Quest 3"}, {"gob3cd", "Goblins Quest 3 CD"}, -- cgit v1.2.3 From f917db972e0ae7e4e82a6430010a155cbb3a92c0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 01:50:31 +0200 Subject: GOB: Shut up Little Red's warning about gob func 1 and 2 Those set some DOS timer interrupt related to sound. Seems to be unnecessary for us. --- engines/gob/inter_littlered.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 01d372aaeb..3a4494598e 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -51,6 +51,9 @@ void Inter_LittleRed::setupOpcodesFunc() { } void Inter_LittleRed::setupOpcodesGob() { + OPCODEGOB(1, o_gobNOP); // Sets some sound timer interrupt + OPCODEGOB(2, o_gobNOP); // Sets some sound timer interrupt + OPCODEGOB(500, o2_playProtracker); OPCODEGOB(501, o2_stopProtracker); } -- cgit v1.2.3 From a24cb57c9d4d4292da582fafc52be70103a1e369 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 02:58:53 +0200 Subject: GOB: Loop the Little Red title music --- engines/gob/inter.h | 1 + engines/gob/inter_littlered.cpp | 8 ++++++++ engines/gob/sound/sound.cpp | 4 ++++ engines/gob/sound/sound.h | 1 + engines/gob/sound/soundblaster.cpp | 24 +++++++++++++++++++++--- engines/gob/sound/soundblaster.h | 4 ++++ 6 files changed, 39 insertions(+), 3 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 0625646cdd..63bf3eb1c6 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -527,6 +527,7 @@ protected: virtual void setupOpcodesGob(); void oLittleRed_keyFunc(OpFuncParams ¶ms); + void oLittleRed_playComposition(OpFuncParams ¶ms); }; class Inter_v3 : public Inter_v2 { diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 3a4494598e..729d9f5694 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -48,6 +48,8 @@ void Inter_LittleRed::setupOpcodesFunc() { Inter_v2::setupOpcodesFunc(); OPCODEFUNC(0x14, oLittleRed_keyFunc); + + OPCODEFUNC(0x3D, oLittleRed_playComposition); } void Inter_LittleRed::setupOpcodesGob() { @@ -107,4 +109,10 @@ void Inter_LittleRed::oLittleRed_keyFunc(OpFuncParams ¶ms) { } } +void Inter_LittleRed::oLittleRed_playComposition(OpFuncParams ¶ms) { + _vm->_sound->blasterRepeatComposition(-1); + + o1_playComposition(params); +} + } // End of namespace Gob diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 9f72d1a98f..170330f281 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -445,6 +445,10 @@ void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount, _blaster->playSample(*sndDesc, repCount, frequency, fadeLength); } +void Sound::blasterRepeatComposition(int32 repCount) { + _blaster->repeatComposition(repCount);; +} + void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) { if (!_blaster) return; diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index 064a249253..6ad0ec5483 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -63,6 +63,7 @@ public: void blasterPlayComposition(int16 *composition, int16 freqVal, SoundDesc *sndDescs = 0, int8 sndCount = kSoundsCount); void blasterStopComposition(); + void blasterRepeatComposition(int32 repCount); char blasterPlayingSound() const; diff --git a/engines/gob/sound/soundblaster.cpp b/engines/gob/sound/soundblaster.cpp index 4ff555b0e3..915d744494 100644 --- a/engines/gob/sound/soundblaster.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -31,6 +31,8 @@ SoundBlaster::SoundBlaster(Audio::Mixer &mixer) : SoundMixer(mixer, Audio::Mixer _compositionSamples = 0; _compositionSampleCount = 0; _compositionPos = -1; + + _compositionRepCount = 0; } SoundBlaster::~SoundBlaster() { @@ -79,6 +81,7 @@ void SoundBlaster::nextCompositionPos() { if (_compositionPos == 49) _compositionPos = -1; } + _compositionPos = -1; } @@ -98,6 +101,10 @@ void SoundBlaster::playComposition(int16 *composition, int16 freqVal, nextCompositionPos(); } +void SoundBlaster::repeatComposition(int32 repCount) { + _compositionRepCount = repCount; +} + void SoundBlaster::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { @@ -106,10 +113,21 @@ void SoundBlaster::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency } void SoundBlaster::checkEndSample() { - if (_compositionPos != -1) + if (_compositionPos != -1) { + nextCompositionPos(); + return; + } + + if (_compositionRepCount != 0) { + if (_compositionRepCount > 0) + _compositionRepCount--; + nextCompositionPos(); - else - SoundMixer::checkEndSample(); + if (_compositionPos != -1) + return; + } + + SoundMixer::checkEndSample(); } void SoundBlaster::endFade() { diff --git a/engines/gob/sound/soundblaster.h b/engines/gob/sound/soundblaster.h index c2704c5482..c740ba2269 100644 --- a/engines/gob/sound/soundblaster.h +++ b/engines/gob/sound/soundblaster.h @@ -46,6 +46,8 @@ public: void stopComposition(); void endComposition(); + void repeatComposition(int32 repCount); + protected: Common::Mutex _mutex; @@ -54,6 +56,8 @@ protected: int16 _composition[50]; int8 _compositionPos; + int32 _compositionRepCount; + SoundDesc *_curSoundDesc; void setSample(SoundDesc &sndDesc, int16 repCount, -- cgit v1.2.3 From 08c0fa91059113e6ed054cf4a84317a6ff8b4d08 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 03:04:35 +0200 Subject: GOB: Remove a superfluous semicolon --- engines/gob/sound/sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 170330f281..184e14a2e6 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -446,7 +446,7 @@ void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount, } void Sound::blasterRepeatComposition(int32 repCount) { - _blaster->repeatComposition(repCount);; + _blaster->repeatComposition(repCount); } void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) { -- cgit v1.2.3 From ba07c7678a3c1f03636f408c51bae121f0280c00 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 04:06:21 +0200 Subject: GOB: Add Little Red to the gob games list comment --- engines/gob/gob.h | 1 + 1 file changed, 1 insertion(+) (limited to 'engines/gob') diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 19489e4924..808c941546 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -54,6 +54,7 @@ class StaticTextWidget; * - Urban Runner * - Bambou le sauveur de la jungle * - Geisha + * - Once Upon A Time: Little Red Riding Hood */ namespace Gob { -- cgit v1.2.3 From 3d7c6a2710e7d8ba1dfc86afe09f94dbf874b99a Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 15:06:07 +0200 Subject: GOB: Correct the name of A.J.'s World of Discovery --- engines/gob/detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 861cc95d41..18baffa3fa 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -51,7 +51,7 @@ static const PlainGameDescriptor gobGames[] = { {"ween", "Ween: The Prophecy"}, {"bargon", "Bargon Attack"}, {"littlered", "Once Upon A Time: Little Red Riding Hood"}, - {"ajworld", "A.J's World of Discovery"}, + {"ajworld", "A.J.'s World of Discovery"}, {"gob3", "Goblins Quest 3"}, {"gob3cd", "Goblins Quest 3 CD"}, {"lit1", "Lost in Time Part 1"}, -- cgit v1.2.3 From 6d01b517550d161b45cbebba077bb9f7bbbc99f2 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 15:08:10 +0200 Subject: GOB: Add a proper GameType for AJ's World --- engines/gob/detection_tables.h | 2 +- engines/gob/gob.cpp | 11 +++++++++++ engines/gob/gob.h | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h index bd35900473..f3dc375fc3 100644 --- a/engines/gob/detection_tables.h +++ b/engines/gob/detection_tables.h @@ -4675,7 +4675,7 @@ static const GOBGameDescription gameDescriptions[] = { ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, - kGameTypeGob2, + kGameTypeAJWorld, kFeaturesAdLib, 0, 0, 0 }, diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index f3480fed99..3d3c43d91c 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -483,6 +483,17 @@ bool GobEngine::initGameParts() { _resourceSizeWorkaround = true; break; + case kGameTypeAJWorld: + _init = new Init_v2(this); + _video = new Video_v2(this); + _inter = new Inter_v2(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); + break; + case kGameTypeGob3: _init = new Init_v3(this); _video = new Video_v2(this); diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 808c941546..52f3ba8f2d 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -129,7 +129,8 @@ enum GameType { kGameTypeAdi4, kGameTypeAdibou2, kGameTypeAdibou1, - kGameTypeLittleRed + kGameTypeLittleRed, + kGameTypeAJWorld }; enum Features { -- cgit v1.2.3 From 026ef70b87f4b85476cb6a3d74ffb9170a170718 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 15:23:31 +0200 Subject: GOB: Add a SaveLoad class for AJ's World Only contains a temp sprite handler ("menu.inf") for now. This fixes the graphical glitch after clicking on the cloud. --- engines/gob/gob.cpp | 1 + engines/gob/module.mk | 1 + engines/gob/save/saveload.h | 27 ++++++++++ engines/gob/save/saveload_ajworld.cpp | 94 +++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 engines/gob/save/saveload_ajworld.cpp (limited to 'engines/gob') diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 3d3c43d91c..3d8a18ed38 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -492,6 +492,7 @@ bool GobEngine::initGameParts() { _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); + _saveLoad = new SaveLoad_AJWorld(this, _targetName.c_str()); break; case kGameTypeGob3: diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 20214ea940..2249f44852 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -94,6 +94,7 @@ MODULE_OBJS := \ save/saveload_v7.o \ save/saveload_geisha.o \ save/saveload_fascin.o \ + save/saveload_ajworld.o \ save/saveload_inca2.o \ save/saveload_playtoons.o \ save/saveconverter.o \ diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h index 66b3482bac..834484757b 100644 --- a/engines/gob/save/saveload.h +++ b/engines/gob/save/saveload.h @@ -257,6 +257,33 @@ protected: SaveFile *getSaveFile(const char *fileName); }; +/** Save/Load class for A.J.'s World of Discovery. */ +class SaveLoad_AJWorld : public SaveLoad { +public: + SaveLoad_AJWorld(GobEngine *vm, const char *targetName); + virtual ~SaveLoad_AJWorld(); + + SaveMode getSaveMode(const char *fileName) const; + +protected: + struct SaveFile { + const char *sourceName; + SaveMode mode; + SaveHandler *handler; + const char *description; + }; + + static SaveFile _saveFiles[]; + + TempSpriteHandler *_tempSpriteHandler; + + SaveHandler *getHandler(const char *fileName) const; + const char *getDescription(const char *fileName) const; + + const SaveFile *getSaveFile(const char *fileName) const; + SaveFile *getSaveFile(const char *fileName); +}; + /** Save/Load class for Goblins 3 and Lost in Time. */ class SaveLoad_v3 : public SaveLoad { public: diff --git a/engines/gob/save/saveload_ajworld.cpp b/engines/gob/save/saveload_ajworld.cpp new file mode 100644 index 0000000000..727d071b3e --- /dev/null +++ b/engines/gob/save/saveload_ajworld.cpp @@ -0,0 +1,94 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/save/saveload.h" +#include "gob/save/saveconverter.h" +#include "gob/inter.h" +#include "gob/variables.h" + +namespace Gob { + +SaveLoad_AJWorld::SaveFile SaveLoad_AJWorld::_saveFiles[] = { + { "menu.inf", kSaveModeSave, 0, "temporary sprite"} +}; + + +SaveLoad_AJWorld::SaveLoad_AJWorld(GobEngine *vm, const char *targetName) : + SaveLoad(vm) { + + _tempSpriteHandler = new TempSpriteHandler(vm); + + _saveFiles[0].handler = _tempSpriteHandler; +} + +SaveLoad_AJWorld::~SaveLoad_AJWorld() { + delete _tempSpriteHandler; +} + +const SaveLoad_AJWorld::SaveFile *SaveLoad_AJWorld::getSaveFile(const char *fileName) const { + fileName = stripPath(fileName); + + for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) + if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) + return &_saveFiles[i]; + + return 0; +} + +SaveLoad_AJWorld::SaveFile *SaveLoad_AJWorld::getSaveFile(const char *fileName) { + fileName = stripPath(fileName); + + for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) + if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) + return &_saveFiles[i]; + + return 0; +} + +SaveHandler *SaveLoad_AJWorld::getHandler(const char *fileName) const { + const SaveFile *saveFile = getSaveFile(fileName); + + if (saveFile) + return saveFile->handler; + + return 0; +} + +const char *SaveLoad_AJWorld::getDescription(const char *fileName) const { + const SaveFile *saveFile = getSaveFile(fileName); + + if (saveFile) + return saveFile->description; + + return 0; +} + +SaveLoad::SaveMode SaveLoad_AJWorld::getSaveMode(const char *fileName) const { + const SaveFile *saveFile = getSaveFile(fileName); + + if (saveFile) + return saveFile->mode; + + return kSaveModeNone; +} + +} // End of namespace Gob -- cgit v1.2.3 From b7ae6a93a983c7feaa7cf029967354bd176b8efc Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 16 Jun 2012 17:20:45 +0200 Subject: GOB: Fix a segfault when quitting AJ's World --- engines/gob/game.cpp | 11 +++++++++++ engines/gob/game.h | 4 ++++ engines/gob/inter.cpp | 3 +++ 3 files changed, 18 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 502a440005..0d1953322f 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -167,6 +167,13 @@ bool Environments::has(Resources *resources, uint8 startEnv, int16 except) const return false; } +void Environments::deleted(Variables *variables) { + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].variables == variables) + _environments[i].variables = 0; + } +} + bool Environments::clearMedia(uint8 env) { if (env >= kEnvironmentCount) return false; @@ -947,6 +954,10 @@ void Game::switchTotSub(int16 index, int16 function) { _environments.get(_curEnvironment); } +void Game::deletedVars(Variables *variables) { + _environments.deleted(variables); +} + void Game::clearUnusedEnvironment() { if (!_environments.has(_script)) { delete _script; diff --git a/engines/gob/game.h b/engines/gob/game.h index b3057ac262..995baa5629 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -52,6 +52,8 @@ public: bool has(Script *script , uint8 startEnv = 0, int16 except = -1) const; bool has(Resources *resources, uint8 startEnv = 0, int16 except = -1) const; + void deleted(Variables *variables); + void clear(); bool setMedia(uint8 env); @@ -169,6 +171,8 @@ public: void totSub(int8 flags, const Common::String &totFile); void switchTotSub(int16 index, int16 function); + void deletedVars(Variables *variables); + bool loadFunctions(const Common::String &tot, uint16 flags); bool callFunction(const Common::String &tot, const Common::String &function, int16 param); diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 843c0bff48..4460274561 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -359,6 +359,9 @@ void Inter::allocateVars(uint32 count) { } void Inter::delocateVars() { + if (_vm->_game) + _vm->_game->deletedVars(_variables); + delete _variables; _variables = 0; } -- cgit v1.2.3 From 892ca3a9c57a948254a2779821a24576f82a77d6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 18 Jun 2012 17:04:46 +0200 Subject: GOB: Don't loop /all/ sounds in Little Red Just the title music... *cough* --- engines/gob/inter_littlered.cpp | 4 ++-- engines/gob/sound/soundblaster.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter_littlered.cpp b/engines/gob/inter_littlered.cpp index 729d9f5694..01aa4c2158 100644 --- a/engines/gob/inter_littlered.cpp +++ b/engines/gob/inter_littlered.cpp @@ -110,9 +110,9 @@ void Inter_LittleRed::oLittleRed_keyFunc(OpFuncParams ¶ms) { } void Inter_LittleRed::oLittleRed_playComposition(OpFuncParams ¶ms) { - _vm->_sound->blasterRepeatComposition(-1); - o1_playComposition(params); + + _vm->_sound->blasterRepeatComposition(-1); } } // End of namespace Gob diff --git a/engines/gob/sound/soundblaster.cpp b/engines/gob/sound/soundblaster.cpp index 915d744494..19c2346448 100644 --- a/engines/gob/sound/soundblaster.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -49,6 +49,8 @@ void SoundBlaster::stopSound(int16 fadeLength, SoundDesc *sndDesc) { if (sndDesc && (sndDesc != _curSoundDesc)) return; + _compositionRepCount = 0; + if (fadeLength <= 0) _curSoundDesc = 0; @@ -64,6 +66,7 @@ void SoundBlaster::stopComposition() { void SoundBlaster::endComposition() { _compositionPos = -1; + _compositionRepCount = 0; } void SoundBlaster::nextCompositionPos() { -- cgit v1.2.3 From 2e16e7fc4c6983db99ae99be9a420ba4549be35e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 18 Jun 2012 17:44:04 +0200 Subject: GOB: Add a workaround for the wrong German animal names in Little Red The DOS, Amiga and Atari version of Little Red come with a small screen, accessible through the main menu, that lets children read and listen to animal names in 5 languages: French, German, English, Spanish and Italian. Unfortunately, the German names are partially wrong. This is especially tragic because this is a game for small children and they're supposed to learn something here. So I deem fixing this a very good idea. Just to be sure, someone should probably look over the French, Spanish and Italian words too. --- engines/gob/draw.h | 2 ++ engines/gob/draw_v2.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 24c5550ea5..1359df632f 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -258,6 +258,8 @@ public: private: uint8 _mayorWorkaroundStatus; + + void fixLittleRedStrings(); }; class Draw_Bargon: public Draw_v2 { diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index d9b7a12639..b637ecbd2b 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -805,6 +805,10 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_PRINTTEXT: + // WORKAROUND: There's mistakes in Little Red's animal names. + // See this function for details. + fixLittleRedStrings(); + len = strlen(_textToPrint); left = _destSpriteX; @@ -933,4 +937,39 @@ void Draw_v2::spriteOperation(int16 operation) { } } +/* WORKAROUND: Fix wrong German animal names in Once Upon A Time: Little Red Riding Hood. + * + * The DOS, Amiga and Atari version of Little Red come with a small screen, accessible + * through the main menu, that lets children read and listen to animal names in 5 + * languages: French, German, English, Spanish and Italian. + * Unfortunately, the German names are partially wrong. This is especially tragic + * because this is a game for small children and they're supposed to learn something + * here. We fix this. + * + * However, there's also problems with the recorded spoken German names: + * - "Der Rabe" has a far too short "a", sounding more like "Rabbe" + * - The wrong article for "Schmetterling" is very audible + * - In general, the words are way too overpronounced + * These are, of course, way harder to fix. + */ + +static const char *kLittleRedStrings[][2] = { + {"die Heule" , "die Eule"}, + {"das Schmetterling" , "der Schmetterling"}, + {"die Vespe" , "die Wespe"}, + {"das Eich\224rnchen" , "das Eichh\224rnchen"} +}; + +void Draw_v2::fixLittleRedStrings() { + if (!_textToPrint || (_vm->getGameType() != kGameTypeLittleRed)) + return; + + for (int i = 0; i < ARRAYSIZE(kLittleRedStrings); i++) { + if (!strcmp(_textToPrint, kLittleRedStrings[i][0])) { + _textToPrint = kLittleRedStrings[i][1]; + return; + } + } +} + } // End of namespace Gob -- cgit v1.2.3 From b1e50b4e304b267afda1c48a4edb77b21058ed45 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 21 Jun 2012 22:59:33 +0200 Subject: GOB: _renderFlags & 0x80 means "Do we have windows?" --- engines/gob/draw.h | 2 +- engines/gob/draw_fascin.cpp | 4 ++-- engines/gob/hotspots.cpp | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 1359df632f..0c7f768341 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -32,7 +32,7 @@ namespace Gob { #define RENDERFLAG_COLLISIONS 0x0004 #define RENDERFLAG_CAPTUREPOP 0x0008 #define RENDERFLAG_USEDELTAS 0x0010 -#define RENDERFLAG_UNKNOWN 0x0080 +#define RENDERFLAG_HASWINDOWS 0x0080 #define RENDERFLAG_NOBLITINVALIDATED 0x0200 #define RENDERFLAG_NOSUBTITLES 0x0400 #define RENDERFLAG_FROMSPLIT 0x0800 diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 69e04f74c9..54cd52b660 100644 --- a/engines/gob/draw_fascin.cpp +++ b/engines/gob/draw_fascin.cpp @@ -747,7 +747,7 @@ int16 Draw_Fascination::openWin(int16 id) { int16 Draw_Fascination::getWinFromCoord(int16 &dx, int16 &dy) { int16 bestMatch = -1; - if ((_renderFlags & 128) == 0) + if (!(_renderFlags & RENDERFLAG_HASWINDOWS)) return -1; for (int i = 0; i < 10; i++) { @@ -790,7 +790,7 @@ int16 Draw_Fascination::handleCurWin() { int8 matchNum = 0; int16 bestMatch = -1; - if ((_vm->_game->_mouseButtons != 1) || ((_renderFlags & 128) == 0)) + if ((_vm->_game->_mouseButtons != 1) || !(_renderFlags & RENDERFLAG_HASWINDOWS)) return 0; for (int i = 0; i < 10; i++) { diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index 9a89f11923..c0f256c7d4 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -533,8 +533,9 @@ void Hotspots::leave(uint16 index) { } int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { - if ((_vm->_draw->_renderFlags & 0x80)==0) - return(0); + if (!(_vm->_draw->_renderFlags & RENDERFLAG_HASWINDOWS)) + return 0; + for (int i = 0; i < 10; i++) { if (_vm->_draw->_fascinWin[i].id != -1) { if (_vm->_global->_inter_mouseX >= _vm->_draw->_fascinWin[i].left && -- cgit v1.2.3 From 62cf66395736e1cc368b31588472fe9d74221c87 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 21 Jun 2012 23:59:59 +0200 Subject: GOB: Add Surface::drawRect() --- engines/gob/surface.cpp | 28 ++++++++++++++++++++++++++++ engines/gob/surface.h | 1 + 2 files changed, 29 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index 3af19f891d..3eaf741be2 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -695,6 +695,34 @@ void Surface::drawLine(uint16 x0, uint16 y0, uint16 x1, uint16 y1, uint32 color) Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, this); } +void Surface::drawRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color) { + // Just in case those are swapped + if (left > right) + SWAP(left, right); + if (top > bottom) + SWAP(top, bottom); + + if ((left >= _width) || (top >= _height)) + // Nothing to do + return; + + // Area to actually draw + const uint16 width = CLIP(right - left + 1, 0, _width - left); + const uint16 height = CLIP(bottom - top + 1, 0, _height - top); + + if ((width == 0) || (height == 0)) + // Nothing to do + return; + + right = left + width - 1; + bottom = top + height - 1; + + drawLine(left , top , left , bottom, color); + drawLine(right, top , right, bottom, color); + drawLine(left , top , right, top , color); + drawLine(left , bottom, right, bottom, color); +} + /* * The original's version of the Bresenham Algorithm was a bit "unclean" * and produced strange edges at 45, 135, 225 and 315 degrees, so using the diff --git a/engines/gob/surface.h b/engines/gob/surface.h index 5376603801..09be8d1a49 100644 --- a/engines/gob/surface.h +++ b/engines/gob/surface.h @@ -158,6 +158,7 @@ public: void putPixel(uint16 x, uint16 y, uint32 color); void drawLine(uint16 x0, uint16 y0, uint16 x1, uint16 y1, uint32 color); + void drawRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color); void drawCircle(uint16 x0, uint16 y0, uint16 radius, uint32 color, int16 pattern = 0); void blitToScreen(uint16 left, uint16 top, uint16 right, uint16 bottom, uint16 x, uint16 y) const; -- cgit v1.2.3 From 76723f4f0fe89650eb64f6fc4e6475d3242d642d Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 22 Jun 2012 00:04:06 +0200 Subject: GOB: Clean up the Fascination window hotspot code a bit --- engines/gob/hotspots.cpp | 174 ++++++++++++++++++++++++++--------------------- engines/gob/hotspots.h | 4 +- 2 files changed, 100 insertions(+), 78 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index c0f256c7d4..140cf2901b 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -532,35 +532,46 @@ void Hotspots::leave(uint16 index) { call(spot.funcLeave); } -int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { +int16 Hotspots::windowCursor(int16 &dx, int16 &dy) const { if (!(_vm->_draw->_renderFlags & RENDERFLAG_HASWINDOWS)) return 0; for (int i = 0; i < 10; i++) { - if (_vm->_draw->_fascinWin[i].id != -1) { - if (_vm->_global->_inter_mouseX >= _vm->_draw->_fascinWin[i].left && - _vm->_global->_inter_mouseX < _vm->_draw->_fascinWin[i].left + _vm->_draw->_fascinWin[i].width && - _vm->_global->_inter_mouseY >= _vm->_draw->_fascinWin[i].top && - _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + _vm->_draw->_fascinWin[i].height) { - if (_vm->_draw->_fascinWin[i].id == _vm->_draw->_winCount-1) { - dx = _vm->_draw->_fascinWin[i].left; - dy = _vm->_draw->_fascinWin[i].top; - if (_vm->_global->_inter_mouseX < _vm->_draw->_fascinWin[i].left + 12 && - _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + 12 && - (VAR((_vm->_draw->_winVarArrayStatus / 4) + i) & 2)) - // Cursor on 'Close Window' - return(5); - if (_vm->_global->_inter_mouseX >= _vm->_draw->_fascinWin[i].left + _vm->_draw->_fascinWin[i].width - 12 && - _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + 12 && - (VAR((_vm->_draw->_winVarArrayStatus / 4) + i) & 4)) - // Cursor on 'Move Window' - return(6); - return(-i); - } - } - } + if (_vm->_draw->_fascinWin[i].id == -1) + // No such windows + continue; + + const int left = _vm->_draw->_fascinWin[i].left; + const int top = _vm->_draw->_fascinWin[i].top; + const int right = _vm->_draw->_fascinWin[i].left + _vm->_draw->_fascinWin[i].width - 1; + const int bottom = _vm->_draw->_fascinWin[i].top + _vm->_draw->_fascinWin[i].height - 1; + + if ((_vm->_global->_inter_mouseX < left) || (_vm->_global->_inter_mouseX > right) || + (_vm->_global->_inter_mouseY < top ) || (_vm->_global->_inter_mouseY > bottom)) + // We're not inside that window + continue; + + if (_vm->_draw->_fascinWin[i].id != (_vm->_draw->_winCount - 1)) + // Only consider the top-most window + continue; + + dx = _vm->_draw->_fascinWin[i].left; + dy = _vm->_draw->_fascinWin[i].top; + + if ((_vm->_global->_inter_mouseX < (left + 12)) && (_vm->_global->_inter_mouseY < (top + 12)) && + (VAR((_vm->_draw->_winVarArrayStatus / 4) + i) & 2)) + // Cursor on 'Close Window' + return 5; + + if ((_vm->_global->_inter_mouseX > (right - 12)) & (_vm->_global->_inter_mouseY < (top + 12)) && + (VAR((_vm->_draw->_winVarArrayStatus / 4) + i) & 4)) + // Cursor on 'Move Window' + return 6; + + return -1; } - return(0); + + return 0; } uint16 Hotspots::checkMouse(Type type, uint16 &id, uint16 &index) const { @@ -1227,13 +1238,13 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, ids[i] = 0; // Type and window - byte type = _vm->_game->_script->readByte(); + byte type = _vm->_game->_script->readByte(); byte windowNum = 0; if ((type & 0x40) != 0) { // Got a window ID - type -= 0x40; + type -= 0x40; windowNum = _vm->_game->_script->readByte(); } @@ -1255,31 +1266,31 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, width = _vm->_game->_script->readUint16(); height = _vm->_game->_script->readUint16(); } + type &= 0x7F; + + // Draw a border around the hotspot if (_vm->_draw->_renderFlags & 64) { - _vm->_draw->_invalidatedTops[0] = 0; - _vm->_draw->_invalidatedLefts[0] = 0; - _vm->_draw->_invalidatedRights[0] = 319; - _vm->_draw->_invalidatedBottoms[0] = 199; - _vm->_draw->_invalidatedCount = 1; + Surface &surface = *_vm->_draw->_spritesArray[_vm->_draw->_destSurface]; + + _vm->_video->dirtyRectsAll(); + if (windowNum == 0) { - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left + width - 1, top, left + width - 1, top + height - 1, 0); - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left, top + height - 1, 0); - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left + width - 1, top, 0); - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top + height - 1, left + width - 1, top + height - 1, 0); + // The hotspot is not inside a window, just draw border it + surface.drawRect(left, top, left + width - 1, top + height - 1, 0); + } else { - if ((_vm->_draw->_fascinWin[windowNum].id != -1) && (_vm->_draw->_fascinWin[windowNum].id == _vm->_draw->_winCount - 1)) { - left += _vm->_draw->_fascinWin[windowNum].left; - top += _vm->_draw->_fascinWin[windowNum].top; - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left + width - 1, top, left + width - 1, top + height - 1, 0); - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left, top + height - 1, 0); - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top, left + width - 1, top, 0); - _vm->_draw->_spritesArray[_vm->_draw->_destSurface]->drawLine(left, top + height - 1, left + width - 1, top + height - 1, 0); - left -= _vm->_draw->_fascinWin[windowNum].left; - top -= _vm->_draw->_fascinWin[windowNum].top; + // The hotspot is inside a window, only draw it if it's the topmost window + + if ((_vm->_draw->_fascinWin[windowNum].id != -1) && + (_vm->_draw->_fascinWin[windowNum].id == (_vm->_draw->_winCount - 1))) { + + const uint16 wLeft = left + _vm->_draw->_fascinWin[windowNum].left; + const uint16 wTop = top + _vm->_draw->_fascinWin[windowNum].top; + + surface.drawRect(wLeft, wTop, wLeft + width - 1, wTop + height - 1, 0); } } } - type &= 0x7F; // Apply global drawing offset if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) { @@ -1668,38 +1679,19 @@ int16 Hotspots::findCursor(uint16 x, uint16 y) const { int16 deltax = 0; int16 deltay = 0; - if (_vm->getGameType() == kGameTypeFascination) - cursor = curWindow(deltax, deltay); - - if (cursor == 0) { - for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) { - const Hotspot &spot = _hotspots[i]; - - if ((spot.getWindow() != 0) || spot.isDisabled()) - // Ignore disabled and non-main-windowed hotspots - continue; + // Fascination uses hard-coded windows + if (_vm->getGameType() == kGameTypeFascination) { + cursor = windowCursor(deltax, deltay); - if (!spot.isIn(x, y)) - // We're not in that hotspot, ignore it - continue; + // We're in a window and in an area that forces a specific cursor + if (cursor > 0) + return cursor; - if (spot.getCursor() == 0) { - // Hotspot doesn't itself specify a cursor... - if (spot.getType() >= kTypeInput1NoLeave) { - // ...but the type has a generic one - cursor = 3; - break; - } else if ((spot.getButton() != kMouseButtonsRight) && (cursor == 0)) - // ...but there's a generic "click" cursor - cursor = 1; - } else if (cursor == 0) - // Hotspot had an attached cursor index - cursor = spot.getCursor(); - } - } else { + // We're somewhere else inside a window if (cursor < 0) { - int16 curType = - cursor * 256; + int16 curType = -cursor * 256; cursor = 0; + for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) { const Hotspot &spot = _hotspots[i]; // this check is /really/ Fascination specific. @@ -1713,10 +1705,40 @@ int16 Hotspots::findCursor(uint16 x, uint16 y) const { break; } } + + if (_vm->_draw->_cursorAnimLow[cursor] == -1) + // If the cursor is invalid... there's a generic "click" cursor + cursor = 1; + + return cursor; } - if (_vm->_draw->_cursorAnimLow[cursor] == -1) - // If the cursor is invalid... there's a generic "click" cursor - cursor = 1; + + } + + // Normal, non-window cursor handling + for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) { + const Hotspot &spot = _hotspots[i]; + + if ((spot.getWindow() != 0) || spot.isDisabled()) + // Ignore disabled and non-main-windowed hotspots + continue; + + if (!spot.isIn(x, y)) + // We're not in that hotspot, ignore it + continue; + + if (spot.getCursor() == 0) { + // Hotspot doesn't itself specify a cursor... + if (spot.getType() >= kTypeInput1NoLeave) { + // ...but the type has a generic one + cursor = 3; + break; + } else if ((spot.getButton() != kMouseButtonsRight) && (cursor == 0)) + // ...but there's a generic "click" cursor + cursor = 1; + } else if (cursor == 0) + // Hotspot had an attached cursor index + cursor = spot.getCursor(); } return cursor; diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h index b348f9cd70..bd7b281c10 100644 --- a/engines/gob/hotspots.h +++ b/engines/gob/hotspots.h @@ -202,8 +202,8 @@ private: /** Handling hotspot leave events. */ void leave(uint16 index); - /** Which window is the mouse cursor currently in? (Fascination) */ - int16 curWindow(int16 &dx, int16 &dy) const; + /** Check whether a specific part of the window forces a certain cursor. */ + int16 windowCursor(int16 &dx, int16 &dy) const; /** Which hotspot is the mouse cursor currently at? */ uint16 checkMouse(Type type, uint16 &id, uint16 &index) const; -- cgit v1.2.3 From ac7fbc4bf2805ffc93cf1714eb4bd3508a57ec7c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 22 Jun 2012 00:05:20 +0200 Subject: GOB: _renderFlags & 0x40 means the we should draw borders around hotspots Probably a debug-only flag --- engines/gob/draw.h | 1 + engines/gob/hotspots.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 0c7f768341..e7af1f9af3 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -32,6 +32,7 @@ namespace Gob { #define RENDERFLAG_COLLISIONS 0x0004 #define RENDERFLAG_CAPTUREPOP 0x0008 #define RENDERFLAG_USEDELTAS 0x0010 +#define RENDERFLAG_BORDERHOTSPOTS 0x0040 #define RENDERFLAG_HASWINDOWS 0x0080 #define RENDERFLAG_NOBLITINVALIDATED 0x0200 #define RENDERFLAG_NOSUBTITLES 0x0400 diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index 140cf2901b..ecab9bb906 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -1269,7 +1269,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, type &= 0x7F; // Draw a border around the hotspot - if (_vm->_draw->_renderFlags & 64) { + if (_vm->_draw->_renderFlags & RENDERFLAG_BORDERHOTSPOTS) { Surface &surface = *_vm->_draw->_spritesArray[_vm->_draw->_destSurface]; _vm->_video->dirtyRectsAll(); -- cgit v1.2.3 From 07b17f7116cd8b068bd677d09684664e13626939 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 22 Jun 2012 17:40:01 +0200 Subject: GOB: Reorganize the detection tables The big table with it's 330 entries grew far too messy and unwieldy, so I'm splitting it into several files. One file for each game, with some exceptions: - The Playtoons series - The ADI / Addy 2 series - The ADI / Addy 4 series - The Adibou / Addy Junior series --- engines/gob/detection.cpp | 165 - engines/gob/detection/detection.cpp | 107 + engines/gob/detection/tables.h | 117 + engines/gob/detection/tables_adi2.h | 203 ++ engines/gob/detection/tables_adi4.h | 222 ++ engines/gob/detection/tables_adibou.h | 247 ++ engines/gob/detection/tables_ajworld.h | 46 + engines/gob/detection/tables_bargon.h | 135 + engines/gob/detection/tables_dynasty.h | 146 + engines/gob/detection/tables_fallback.h | 409 +++ engines/gob/detection/tables_fascin.h | 267 ++ engines/gob/detection/tables_geisha.h | 76 + engines/gob/detection/tables_gob1.h | 716 ++++ engines/gob/detection/tables_gob2.h | 641 ++++ engines/gob/detection/tables_gob3.h | 564 ++++ engines/gob/detection/tables_inca2.h | 249 ++ engines/gob/detection/tables_lit.h | 484 +++ engines/gob/detection/tables_littlered.h | 265 ++ engines/gob/detection/tables_playtoons.h | 517 +++ engines/gob/detection/tables_urban.h | 151 + engines/gob/detection/tables_ween.h | 349 ++ engines/gob/detection/tables_woodruff.h | 402 +++ engines/gob/detection_tables.h | 5276 ------------------------------ engines/gob/module.mk | 2 +- 24 files changed, 6314 insertions(+), 5442 deletions(-) delete mode 100644 engines/gob/detection.cpp create mode 100644 engines/gob/detection/detection.cpp create mode 100644 engines/gob/detection/tables.h create mode 100644 engines/gob/detection/tables_adi2.h create mode 100644 engines/gob/detection/tables_adi4.h create mode 100644 engines/gob/detection/tables_adibou.h create mode 100644 engines/gob/detection/tables_ajworld.h create mode 100644 engines/gob/detection/tables_bargon.h create mode 100644 engines/gob/detection/tables_dynasty.h create mode 100644 engines/gob/detection/tables_fallback.h create mode 100644 engines/gob/detection/tables_fascin.h create mode 100644 engines/gob/detection/tables_geisha.h create mode 100644 engines/gob/detection/tables_gob1.h create mode 100644 engines/gob/detection/tables_gob2.h create mode 100644 engines/gob/detection/tables_gob3.h create mode 100644 engines/gob/detection/tables_inca2.h create mode 100644 engines/gob/detection/tables_lit.h create mode 100644 engines/gob/detection/tables_littlered.h create mode 100644 engines/gob/detection/tables_playtoons.h create mode 100644 engines/gob/detection/tables_urban.h create mode 100644 engines/gob/detection/tables_ween.h create mode 100644 engines/gob/detection/tables_woodruff.h delete mode 100644 engines/gob/detection_tables.h (limited to 'engines/gob') diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp deleted file mode 100644 index 18baffa3fa..0000000000 --- a/engines/gob/detection.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "base/plugins.h" -#include "engines/advancedDetector.h" -#include "engines/obsolete.h" - -#include "gob/gob.h" - -namespace Gob { - -struct GOBGameDescription { - ADGameDescription desc; - - GameType gameType; - int32 features; - const char *startStkBase; - const char *startTotBase; - uint32 demoIndex; -}; - -} - -using namespace Common; - -static const PlainGameDescriptor gobGames[] = { - {"gob", "Gob engine game"}, - {"gob1", "Gobliiins"}, - {"gob1cd", "Gobliiins CD"}, - {"gob2", "Gobliins 2"}, - {"gob2cd", "Gobliins 2 CD"}, - {"ween", "Ween: The Prophecy"}, - {"bargon", "Bargon Attack"}, - {"littlered", "Once Upon A Time: Little Red Riding Hood"}, - {"ajworld", "A.J.'s World of Discovery"}, - {"gob3", "Goblins Quest 3"}, - {"gob3cd", "Goblins Quest 3 CD"}, - {"lit1", "Lost in Time Part 1"}, - {"lit2", "Lost in Time Part 2"}, - {"lit", "Lost in Time"}, - {"inca2", "Inca II: Wiracocha"}, - {"woodruff", "The Bizarre Adventures of Woodruff and the Schnibble"}, - {"dynasty", "The Last Dynasty"}, - {"urban", "Urban Runner"}, - {"playtoons1", "Playtoons 1 - Uncle Archibald"}, - {"playtoons2", "Playtoons 2 - The Case of the Counterfeit Collaborator"}, - {"playtoons3", "Playtoons 3 - The Secret of the Castle"}, - {"playtoons4", "Playtoons 4 - The Mandarine Prince"}, - {"playtoons5", "Playtoons 5 - The Stone of Wakan"}, - {"playtnck1", "Playtoons Construction Kit 1 - Monsters"}, - {"playtnck2", "Playtoons Construction Kit 2 - Knights"}, - {"playtnck3", "Playtoons Construction Kit 3 - Far West"}, - {"bambou", "Playtoons Limited Edition - Bambou le sauveur de la jungle"}, - {"fascination", "Fascination"}, - {"geisha", "Geisha"}, - {"adi2", "ADI 2"}, - {"adi4", "ADI 4"}, - {"adibou2", "Adibou 2"}, - {"adibou1", "Adibou 1"}, - {0, 0} -}; - -static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = { - {"gob1", "gob", kPlatformUnknown}, - {"gob2", "gob", kPlatformUnknown}, - {0, 0, kPlatformUnknown} -}; - -#include "gob/detection_tables.h" - -class GobMetaEngine : public AdvancedMetaEngine { -public: - GobMetaEngine() : AdvancedMetaEngine(Gob::gameDescriptions, sizeof(Gob::GOBGameDescription), gobGames) { - _singleid = "gob"; - _guioptions = GUIO1(GUIO_NOLAUNCHLOAD); - } - - virtual GameDescriptor findGame(const char *gameid) const { - return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable); - } - - virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { - return detectGameFilebased(allFiles, Gob::fileBased); - } - - virtual const char *getName() const { - return "Gob"; - } - - virtual const char *getOriginalCopyright() const { - return "Goblins Games (C) Coktel Vision"; - } - - virtual bool hasFeature(MetaEngineFeature f) const; - - virtual Common::Error createInstance(OSystem *syst, Engine **engine) const { - Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable); - return AdvancedMetaEngine::createInstance(syst, engine); - } - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; -}; - -bool GobMetaEngine::hasFeature(MetaEngineFeature f) const { - return false; -} - -bool Gob::GobEngine::hasFeature(EngineFeature f) const { - return - (f == kSupportsRTL); -} -bool GobMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { - const Gob::GOBGameDescription *gd = (const Gob::GOBGameDescription *)desc; - if (gd) { - *engine = new Gob::GobEngine(syst); - ((Gob::GobEngine *)*engine)->initGame(gd); - } - return gd != 0; -} - -#if PLUGIN_ENABLED_DYNAMIC(GOB) - REGISTER_PLUGIN_DYNAMIC(GOB, PLUGIN_TYPE_ENGINE, GobMetaEngine); -#else - REGISTER_PLUGIN_STATIC(GOB, PLUGIN_TYPE_ENGINE, GobMetaEngine); -#endif - -namespace Gob { - -void GobEngine::initGame(const GOBGameDescription *gd) { - if (gd->startTotBase == 0) - _startTot = "intro.tot"; - else - _startTot = gd->startTotBase; - - if (gd->startStkBase == 0) - _startStk = "intro.stk"; - else - _startStk = gd->startStkBase; - - _demoIndex = gd->demoIndex; - - _gameType = gd->gameType; - _features = gd->features; - _language = gd->desc.language; - _platform = gd->desc.platform; -} -} // End of namespace Gob diff --git a/engines/gob/detection/detection.cpp b/engines/gob/detection/detection.cpp new file mode 100644 index 0000000000..bcfd5dacfa --- /dev/null +++ b/engines/gob/detection/detection.cpp @@ -0,0 +1,107 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "base/plugins.h" +#include "engines/advancedDetector.h" +#include "engines/obsolete.h" + +#include "gob/gob.h" + +#include "gob/detection/tables.h" + +class GobMetaEngine : public AdvancedMetaEngine { +public: + GobMetaEngine() : AdvancedMetaEngine(Gob::gameDescriptions, sizeof(Gob::GOBGameDescription), gobGames) { + _singleid = "gob"; + _guioptions = GUIO1(GUIO_NOLAUNCHLOAD); + } + + virtual GameDescriptor findGame(const char *gameid) const { + return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable); + } + + virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { + return detectGameFilebased(allFiles, Gob::fileBased); + } + + virtual const char *getName() const { + return "Gob"; + } + + virtual const char *getOriginalCopyright() const { + return "Goblins Games (C) Coktel Vision"; + } + + virtual bool hasFeature(MetaEngineFeature f) const; + + virtual Common::Error createInstance(OSystem *syst, Engine **engine) const { + Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable); + return AdvancedMetaEngine::createInstance(syst, engine); + } + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; +}; + +bool GobMetaEngine::hasFeature(MetaEngineFeature f) const { + return false; +} + +bool Gob::GobEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsRTL); +} +bool GobMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const Gob::GOBGameDescription *gd = (const Gob::GOBGameDescription *)desc; + if (gd) { + *engine = new Gob::GobEngine(syst); + ((Gob::GobEngine *)*engine)->initGame(gd); + } + return gd != 0; +} + +#if PLUGIN_ENABLED_DYNAMIC(GOB) + REGISTER_PLUGIN_DYNAMIC(GOB, PLUGIN_TYPE_ENGINE, GobMetaEngine); +#else + REGISTER_PLUGIN_STATIC(GOB, PLUGIN_TYPE_ENGINE, GobMetaEngine); +#endif + +namespace Gob { + +void GobEngine::initGame(const GOBGameDescription *gd) { + if (gd->startTotBase == 0) + _startTot = "intro.tot"; + else + _startTot = gd->startTotBase; + + if (gd->startStkBase == 0) + _startStk = "intro.stk"; + else + _startStk = gd->startStkBase; + + _demoIndex = gd->demoIndex; + + _gameType = gd->gameType; + _features = gd->features; + _language = gd->desc.language; + _platform = gd->desc.platform; +} + +} // End of namespace Gob diff --git a/engines/gob/detection/tables.h b/engines/gob/detection/tables.h new file mode 100644 index 0000000000..5d211ac7d8 --- /dev/null +++ b/engines/gob/detection/tables.h @@ -0,0 +1,117 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_DETECTION_TABLES_H +#define GOB_DETECTION_TABLES_H + +namespace Gob { + +struct GOBGameDescription { + ADGameDescription desc; + + GameType gameType; + int32 features; + const char *startStkBase; + const char *startTotBase; + uint32 demoIndex; +}; + +} + +using namespace Common; + +// Game IDs and proper names +static const PlainGameDescriptor gobGames[] = { + {"gob", "Gob engine game"}, + {"gob1", "Gobliiins"}, + {"gob1cd", "Gobliiins CD"}, + {"gob2", "Gobliins 2"}, + {"gob2cd", "Gobliins 2 CD"}, + {"ween", "Ween: The Prophecy"}, + {"bargon", "Bargon Attack"}, + {"littlered", "Once Upon A Time: Little Red Riding Hood"}, + {"ajworld", "A.J.'s World of Discovery"}, + {"gob3", "Goblins Quest 3"}, + {"gob3cd", "Goblins Quest 3 CD"}, + {"lit1", "Lost in Time Part 1"}, + {"lit2", "Lost in Time Part 2"}, + {"lit", "Lost in Time"}, + {"inca2", "Inca II: Wiracocha"}, + {"woodruff", "The Bizarre Adventures of Woodruff and the Schnibble"}, + {"dynasty", "The Last Dynasty"}, + {"urban", "Urban Runner"}, + {"playtoons1", "Playtoons 1 - Uncle Archibald"}, + {"playtoons2", "Playtoons 2 - The Case of the Counterfeit Collaborator"}, + {"playtoons3", "Playtoons 3 - The Secret of the Castle"}, + {"playtoons4", "Playtoons 4 - The Mandarine Prince"}, + {"playtoons5", "Playtoons 5 - The Stone of Wakan"}, + {"playtnck1", "Playtoons Construction Kit 1 - Monsters"}, + {"playtnck2", "Playtoons Construction Kit 2 - Knights"}, + {"playtnck3", "Playtoons Construction Kit 3 - Far West"}, + {"bambou", "Playtoons Limited Edition - Bambou le sauveur de la jungle"}, + {"fascination", "Fascination"}, + {"geisha", "Geisha"}, + {"adi2", "ADI 2"}, + {"adi4", "ADI 4"}, + {"adibou2", "Adibou 2"}, + {"adibou1", "Adibou 1"}, + {0, 0} +}; + +// Obsolete IDs we don't want anymore +static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = { + {"gob1", "gob", kPlatformUnknown}, + {"gob2", "gob", kPlatformUnknown}, + {0, 0, kPlatformUnknown} +}; + +namespace Gob { + +// Detection tables +static const GOBGameDescription gameDescriptions[] = { + #include "gob/detection/tables_gob1.h" // Gobliiins + #include "gob/detection/tables_gob2.h" // Gobliins 2: The Prince Buffoon + #include "gob/detection/tables_gob3.h" // Goblins 3 / Goblins Quest 3 + #include "gob/detection/tables_ween.h" // Ween: The Prophecy + #include "gob/detection/tables_bargon.h" // Bargon Attack + #include "gob/detection/tables_littlered.h" // Once Upon A Time: Little Red Riding Hood + #include "gob/detection/tables_lit.h" // Lost in Time + #include "gob/detection/tables_fascin.h" // Fascination + #include "gob/detection/tables_geisha.h" // Geisha + #include "gob/detection/tables_inca2.h" // Inca II: Wiracocha + #include "gob/detection/tables_woodruff.h" // (The Bizarre Adventures of) Woodruff and the Schnibble (of Azimuth) + #include "gob/detection/tables_dynasty.h" // The Last Dynasty + #include "gob/detection/tables_urban.h" // Urban Runner + #include "gob/detection/tables_playtoons.h" // The Playtoons series + #include "gob/detection/tables_adi2.h" // The ADI / Addy 2 series + #include "gob/detection/tables_adi4.h" // The ADI / Addy 4 series + #include "gob/detection/tables_adibou.h" // The Adibou / Addy Junior series + #include "gob/detection/tables_ajworld.h" // A.J.'s World of Discovery / ADI Jr. + + { AD_TABLE_END_MARKER, kGameTypeNone, kFeaturesNone, 0, 0, 0} +}; + +// File-based fallback tables +#include "gob/detection/tables_fallback.h" +} + +#endif // GOB_DETECTION_TABLES_H diff --git a/engines/gob/detection/tables_adi2.h b/engines/gob/detection/tables_adi2.h new file mode 100644 index 0000000000..da05a31f40 --- /dev/null +++ b/engines/gob/detection/tables_adi2.h @@ -0,0 +1,203 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for the ADI / Addy 2 series. */ + +#ifndef GOB_DETECTION_TABLES_ADI2_H +#define GOB_DETECTION_TABLES_ADI2_H + +// -- French: Adi -- + +{ + { + "adi2", + "Adi 2.0 for Teachers", + AD_ENTRY1s("adi2.stk", "da6f1fb68bff32260c5eecdf9286a2f5", 1533168), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdi2, + kFeaturesNone, + "adi2.stk", "ediintro.tot", 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1. Exact version not specified. + { + "adi2", + "Adi 2", + AD_ENTRY1s("adi2.stk", "23f279615c736dc38320f1348e70c36e", 10817668), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, +{ // Found in french ADI 2 Francais-Maths CE2. Exact version not specified. + { + "adi2", + "Adi 2", + AD_ENTRY1s("adi2.stk", "d4162c4298f9423ecc1fb04965557e90", 11531214), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, +{ + { + "adi2", + "Adi 2.5", + AD_ENTRY1s("adi2.stk", "fcac60e6627f37aee219575b60859de9", 16944268), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, +{ + { + "adi2", + "Adi 2.5", + AD_ENTRY1s("adi2.stk", "072d5e2d7826a7c055865568ebf918bb", 16934596), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, +{ + { + "adi2", + "Adi 2.6", + AD_ENTRY1s("adi2.stk", "2fb940eb8105b12871f6b88c8c4d1615", 16780058), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, + +// -- German: Addy -- + +{ + { + "adi2", + "Adi 2.6", + AD_ENTRY1s("adi2.stk", "fde7d98a67dbf859423b6473796e932a", 18044780), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, +{ + { + "adi2", + "Adi 2.7.1", + AD_ENTRY1s("adi2.stk", "6fa5dffebf5c7243c6af6b8c188ee00a", 19278008), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, + +// -- Spanish: Adi -- + +{ + { + "adi2", + "Adi 2", + AD_ENTRY1s("adi2.stk", "2a40bb48ccbd4e6fb3f7f0fc2f069d80", 17720132), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", "ediintro.tot", 0 +}, + +// -- English: ADI (Amiga) -- + +{ + { + "adi2", + "Adi 2", + AD_ENTRY1s("adi2.stk", "29694c5a649298a42f87ae731d6d6f6d", 311132), + EN_ANY, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdi2, + kFeaturesNone, + "adi2.stk", "ediintro.tot", 0 +}, + +// -- Demos -- + +{ + { + "adi2", + "Non-Interactive Demo", + { + {"demo.scn", 0, "8b5ba359fd87d586ad39c1754bf6ea35", 168}, + {"demadi2t.vmd", 0, "08a1b18cfe2015d3b43270da35cc813d", 7250723}, + {"demarch.vmd", 0, "4c4a4616585d40ef3df209e3c3911062", 5622731}, + {"demobou.vmd", 0, "2208b9855775564d15c4a5a559da0aec", 3550511}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 1 +}, + +#endif // GOB_DETECTION_TABLES_ADI2_H diff --git a/engines/gob/detection/tables_adi4.h b/engines/gob/detection/tables_adi4.h new file mode 100644 index 0000000000..4b967d76d3 --- /dev/null +++ b/engines/gob/detection/tables_adi4.h @@ -0,0 +1,222 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for the ADI / Addy 4 series. */ + +#ifndef GOB_DETECTION_TABLES_ADI4_H +#define GOB_DETECTION_TABLES_ADI4_H + +// -- French: Adi -- + +{ + { + "adi4", + "Adi 4.0", + AD_ENTRY1s("intro.stk", "a3c35d19b2d28ea261d96321d208cb5a", 6021466), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "Adi 4.0", + AD_ENTRY1s("intro.stk", "44491d85648810bc6fcf84f9b3aa47d5", 5834944), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "Adi 4.0", + AD_ENTRY1s("intro.stk", "29374c0e3c10b17dd8463b06a55ad093", 6012072), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "Adi 4.0 Limited Edition", + AD_ENTRY1s("intro.stk", "ebbbc5e28a4adb695535ed989c1b8d66", 5929644), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "ADI 4.10", + AD_ENTRY1s("intro.stk", "6afc2590856433b9f5295b032f2b205d", 5923112), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adi4", + "ADI 4.11", + AD_ENTRY1s("intro.stk", "6296e4be4e0c270c24d1330881900c7f", 5921234), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adi4", + "ADI 4.21", + AD_ENTRY1s("intro.stk", "c5b9f6222c0b463f51dab47317c5b687", 5950490), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, + +// -- German: Addy -- + +{ + { + "adi4", + "Addy 4 Grundschule Basis CD", + AD_ENTRY1s("intro.stk", "d2f0fb8909e396328dc85c0e29131ba8", 5847588), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "Addy 4 Sekundarstufe Basis CD", + AD_ENTRY1s("intro.stk", "367340e59c461b4fa36651cd74e32c4e", 5847378), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "Addy 4.21", + AD_ENTRY1s("intro.stk", "534f0b674cd4830df94a9c32c4ea7225", 6878034), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, + +// -- English: ADI -- + +{ + { + "adi4", + "ADI 4.10", + AD_ENTRY1s("intro.stk", "3e3fa9656e37d802027635ace88c4cc5", 5359144), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "adi4", + "Adi 4.0 Interactive Demo", + AD_ENTRY1s("intro.stk", "89ace204dbaac001425c73f394334f6f", 2413102), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "adi4", + "Adi 4.0 / Adibou 2 Demo", + AD_ENTRY1s("intro.stk", "d41d8cd98f00b204e9800998ecf8427e", 0), + FR_FRA, + kPlatformPC, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_ADI4_H diff --git a/engines/gob/detection/tables_adibou.h b/engines/gob/detection/tables_adibou.h new file mode 100644 index 0000000000..0e652839bb --- /dev/null +++ b/engines/gob/detection/tables_adibou.h @@ -0,0 +1,247 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Adibou / Addy Junior series. */ + +#ifndef GOB_DETECTION_TABLES_ADIBOU_H +#define GOB_DETECTION_TABLES_ADIBOU_H + +// -- French: Adibou -- + +{ + { + "adibou1", + "ADIBOU 1 Environnement 4-7 ans", + AD_ENTRY1s("intro.stk", "6db110188fcb7c5208d9721b5282682a", 4805104), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAdibou1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOU 2", + AD_ENTRY1s("intro.stk", "94ae7004348dc8bf99c23a9a6ef81827", 956162), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "Le Jardin Magique d'Adibou", + AD_ENTRY1s("intro.stk", "a8ff86f3cc40dfe5898e0a741217ef27", 956328), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOU Version Decouverte", + AD_ENTRY1s("intro.stk", "558c14327b79ed39214b49d567a75e33", 8737856), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOU 2.10 Environnement", + AD_ENTRY1s("intro.stk", "f2b797819aeedee557e904b0b5ccd82e", 8736454), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOU 2.11 Environnement", + AD_ENTRY1s("intro.stk", "7b1f1f6f6477f54401e95d913f75e333", 8736904), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOU 2.12 Environnement", + AD_ENTRY1s("intro.stk", "1e49c39a4a3ce6032a84b712539c2d63", 8738134), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOU 2.13s Environnement", + AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "adibou2", + "ADIBOO 2.14 Environnement", + AD_ENTRY1s("intro.stk", "ff63637e3cb7f0a457edf79457b1c6b3", 9333874), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, + +// -- German: Addy Junior -- + +{ + { + "adibou2", + "ADIBOU 2", + AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Italian: Adibù -- +{ + { + "adibou2", + "ADIB\xD9 2", + AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO0() + }, + kGameTypeAdibou2, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "adibou2", + "Non-Interactive Demo", + { + {"demogb.scn", 0, "9291455a908ac0e6aaaca686e532609b", 105}, + {"demogb.vmd", 0, "bc9c1db97db7bec8f566332444fa0090", 14320840}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformPC, + ADGF_DEMO, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeAdibou2, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 9 +}, +{ + { + "adibou2", + "Non-Interactive Demo", + { + {"demoall.scn", 0, "c8fd308c037b829800006332b2c32674", 106}, + {"demoall.vmd", 0, "4672b2deacc6fca97484840424b1921b", 14263433}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformPC, + ADGF_DEMO, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeAdibou2, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 10 +}, +{ + { + "adibou2", + "Non-Interactive Demo", + { + {"demofra.scn", 0, "d1b2b1618af384ea1120def8b986c02b", 106}, + {"demofra.vmd", 0, "b494cdec1aac7e54c3f2480512d2880e", 14297100}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_DEMO, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeAdibou2, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 11 +}, + +#endif // GOB_DETECTION_TABLES_ADIBOU_H diff --git a/engines/gob/detection/tables_ajworld.h b/engines/gob/detection/tables_ajworld.h new file mode 100644 index 0000000000..c78d11a6ad --- /dev/null +++ b/engines/gob/detection/tables_ajworld.h @@ -0,0 +1,46 @@ + +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for A.J.'s World of Discovery / ADI Jr. */ + +#ifndef GOB_DETECTION_TABLES_AJWORLD_H +#define GOB_DETECTION_TABLES_AJWORLD_H + +// -- DOS VGA Floppy -- + +{ + { + "ajworld", + "", + AD_ENTRY1s("intro.stk", "e453bea7b28a67c930764d945f64d898", 3913628), + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAJWorld, + kFeaturesAdLib, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_AJWORLD_H diff --git a/engines/gob/detection/tables_bargon.h b/engines/gob/detection/tables_bargon.h new file mode 100644 index 0000000000..ac90355476 --- /dev/null +++ b/engines/gob/detection/tables_bargon.h @@ -0,0 +1,135 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Bargon Attack. */ + +#ifndef GOB_DETECTION_TABLES_BARGON_H +#define GOB_DETECTION_TABLES_BARGON_H + +// -- DOS VGA Floppy -- + +{ + { + "bargon", + "", + AD_ENTRY1("intro.stk", "da3c54be18ab73fbdb32db24624a9c23"), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by cesardark in bug #1681649 + { + "bargon", + "", + AD_ENTRY1s("intro.stk", "11103b304286c23945560b391fd37e7d", 3181890), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug #1692667 + { + "bargon", + "", + AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by kizkoool in bugreport #2089734 + { + "bargon", + "", + AD_ENTRY1s("intro.stk", "00f6b4e2ee26e5c40b488e2df5adcf03", 3975580), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by glorfindel in bugreport #1722142 + { + "bargon", + "Fanmade", + AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Amiga -- + +{ // Supplied by pwigren in bugreport #1764174 + { + "bargon", + "", + AD_ENTRY1s("intro.stk", "569d679fe41d49972d34c9fce5930dda", 269825), + EN_ANY, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Atari ST -- + +{ // Supplied by Trekky in the forums + { + "bargon", + "", + AD_ENTRY1s("intro.stk", "2f54b330d21f65b04b7c1f8cca76426c", 262109), + FR_FRA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_BARGON_H diff --git a/engines/gob/detection/tables_dynasty.h b/engines/gob/detection/tables_dynasty.h new file mode 100644 index 0000000000..147bf32075 --- /dev/null +++ b/engines/gob/detection/tables_dynasty.h @@ -0,0 +1,146 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for The Last Dynasty. */ + +#ifndef GOB_DETECTION_TABLES_DYNASTY_H +#define GOB_DETECTION_TABLES_DYNASTY_H + +// -- Windows -- + +{ + { + "dynasty", + "", + AD_ENTRY1s("intro.stk", "6190e32404b672f4bbbc39cf76f41fda", 2511470), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "dynasty", + "", + AD_ENTRY1s("intro.stk", "61e4069c16e27775a6cc6d20f529fb36", 2511300), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "dynasty", + "", + AD_ENTRY1s("intro.stk", "61e4069c16e27775a6cc6d20f529fb36", 2511300), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "dynasty", + "", + AD_ENTRY1s("intro.stk", "b3f8472484b7a1df94557b51e7b6fca0", 2322644), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "dynasty", + "", + AD_ENTRY1s("intro.stk", "bdbdac8919200a5e71ffb9fb0709f704", 2446652), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "dynasty", + "Demo", + AD_ENTRY1s("intro.stk", "464538a17ed39755d7f1ba9c751af1bd", 1847864), + EN_USA, + kPlatformPC, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "dynasty", + "Demo", + AD_ENTRY1s("lda1.stk", "0e56a899357cbc0bf503260fd2dd634e", 15032774), + UNK_LANG, + kPlatformWindows, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + "lda1.stk", 0, 0 +}, +{ + { + "dynasty", + "Demo", + AD_ENTRY1s("lda1.stk", "8669ea2e9a8239c070dc73958fbc8753", 15567724), + DE_DEU, + kPlatformWindows, + ADGF_DEMO, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeDynasty, + kFeatures640x480, + "lda1.stk", 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_DYNASTY_H diff --git a/engines/gob/detection/tables_fallback.h b/engines/gob/detection/tables_fallback.h new file mode 100644 index 0000000000..d8a5760080 --- /dev/null +++ b/engines/gob/detection/tables_fallback.h @@ -0,0 +1,409 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_DETECTION_TABLES_FALLBACK_H +#define GOB_DETECTION_TABLES_FALLBACK_H + +static const GOBGameDescription fallbackDescs[] = { + { //0 + { + "gob1", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 + }, + { //1 + { + "gob1cd", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 + }, + { //2 + { + "gob2", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 + }, + { //3 + { + "gob2mac", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 + }, + { //4 + { + "gob2cd", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, + { //5 + { + "bargon", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBargon, + kFeaturesNone, + 0, 0, 0 + }, + { //6 + { + "gob3", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 + }, + { //7 + { + "gob3cd", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 + }, + { //8 + { + "woodruff", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 + }, + { //9 + { + "lostintime", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 + }, + { //10 + { + "lostintime", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 + }, + { //11 + { + "lostintime", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 + }, + { //12 + { + "urban", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 + }, + { //13 + { + "playtoons1", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + 0, 0, 0 + }, + { //14 + { + "playtoons2", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + 0, 0, 0 + }, + { //15 + { + "playtoons3", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + 0, 0, 0 + }, + { //16 + { + "playtoons4", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + 0, 0, 0 + }, + { //17 + { + "playtoons5", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + 0, 0, 0 + }, + { //18 + { + "playtoons construction kit", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + 0, 0, 0 + }, + { //19 + { + "bambou", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeBambou, + kFeatures640x480, + 0, 0, 0 + }, + { //20 + { + "fascination", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesNone, + "disk0.stk", 0, 0 + }, + { //21 + { + "geisha", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA, + "disk1.stk", "intro.tot", 0 + }, + { //22 + { + "adi2", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeAdi2, + kFeatures640x480, + "adi2.stk", 0, 0 + }, + { //23 + { + "adi4", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeAdi4, + kFeatures640x480, + "adif41.stk", 0, 0 + }, + { //24 + { + "coktelplayer", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeaturesAdLib | kFeatures640x480 | kFeaturesSCNDemo, + "", "", 8 + } +}; + +static const ADFileBasedFallback fileBased[] = { + { &fallbackDescs[ 0].desc, { "intro.stk", "disk1.stk", "disk2.stk", "disk3.stk", "disk4.stk", 0 } }, + { &fallbackDescs[ 1].desc, { "intro.stk", "gob.lic", 0 } }, + { &fallbackDescs[ 2].desc, { "intro.stk", 0 } }, + { &fallbackDescs[ 2].desc, { "intro.stk", "disk2.stk", "disk3.stk", 0 } }, + { &fallbackDescs[ 3].desc, { "intro.stk", "disk2.stk", "disk3.stk", "musmac1.mid", 0 } }, + { &fallbackDescs[ 4].desc, { "intro.stk", "gobnew.lic", 0 } }, + { &fallbackDescs[ 5].desc, { "intro.stk", "scaa.imd", "scba.imd", "scbf.imd", 0 } }, + { &fallbackDescs[ 6].desc, { "intro.stk", "imd.itk", 0 } }, + { &fallbackDescs[ 7].desc, { "intro.stk", "mus_gob3.lic", 0 } }, + { &fallbackDescs[ 8].desc, { "intro.stk", "woodruff.itk", 0 } }, + { &fallbackDescs[ 9].desc, { "intro.stk", "commun1.itk", 0 } }, + { &fallbackDescs[10].desc, { "intro.stk", "commun1.itk", "musmac1.mid", 0 } }, + { &fallbackDescs[11].desc, { "intro.stk", "commun1.itk", "lost.lic", 0 } }, + { &fallbackDescs[12].desc, { "intro.stk", "cd1.itk", "objet1.itk", 0 } }, + { &fallbackDescs[13].desc, { "playtoon.stk", "archi.stk", 0 } }, + { &fallbackDescs[14].desc, { "playtoon.stk", "spirou.stk", 0 } }, + { &fallbackDescs[15].desc, { "playtoon.stk", "chato.stk", 0 } }, + { &fallbackDescs[16].desc, { "playtoon.stk", "manda.stk", 0 } }, + { &fallbackDescs[17].desc, { "playtoon.stk", "wakan.stk", 0 } }, + { &fallbackDescs[18].desc, { "playtoon.stk", "dan.itk" } }, + { &fallbackDescs[19].desc, { "intro.stk", "bambou.itk", 0 } }, + { &fallbackDescs[20].desc, { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, + { &fallbackDescs[21].desc, { "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, + { &fallbackDescs[22].desc, { "adi2.stk", 0 } }, + { &fallbackDescs[23].desc, { "adif41.stk", "adim41.stk", 0 } }, + { &fallbackDescs[24].desc, { "coktelplayer.scn", 0 } }, + { 0, { 0 } } +}; + +#endif // GOB_DETECTION_TABLES_FALLBACK_H diff --git a/engines/gob/detection/tables_fascin.h b/engines/gob/detection/tables_fascin.h new file mode 100644 index 0000000000..1c9cced303 --- /dev/null +++ b/engines/gob/detection/tables_fascin.h @@ -0,0 +1,267 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Fascination. */ + +#ifndef GOB_DETECTION_TABLES_FASCIN_H +#define GOB_DETECTION_TABLES_FASCIN_H + +// -- DOS VGA Floppy (1 disk) -- + +{ // Supplied by scoriae + { + "fascination", + "VGA", + AD_ENTRY1s("disk0.stk", "c14330d052fe4da5a441ac9d81bc5891", 1061955), + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesAdLib, + "disk0.stk", 0, 0 +}, +{ + { + "fascination", + "VGA", + AD_ENTRY1s("disk0.stk", "e8ab4f200a2304849f462dc901705599", 183337), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesAdLib, + "disk0.stk", 0, 0 +}, + +// -- DOS VGA Floppy (3 disks) -- + +{ // Supplied by alex86r in bug report #3297633 + { + "fascination", + "VGA 3 disks edition", + AD_ENTRY1s("disk0.stk", "ab3dfdce43917bc806812959d692fc8f", 1061929), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesAdLib, + "disk0.stk", 0, 0 +}, +{ + { + "fascination", + "VGA 3 disks edition", + AD_ENTRY1s("disk0.stk", "a50a8495e1b2d67699fb562cb98fc3e2", 1064387), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesAdLib, + "disk0.stk", 0, 0 +}, +{ + { + "fascination", + "Hebrew edition (censored)", + AD_ENTRY1s("intro.stk", "d6e45ce548598727e2b5587a99718eba", 1055909), + HE_ISR, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesAdLib, + "intro.stk", 0, 0 +}, +{ // Supplied by windlepoons in bug report #2809247 + { + "fascination", + "VGA 3 disks edition", + AD_ENTRY1s("disk0.stk", "3a24e60a035250189643c86a9ceafb97", 1062480), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesAdLib, + "disk0.stk", 0, 0 +}, + +// -- DOS VGA CD -- + +{ + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSUBTITLES) + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 +}, +{ + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSUBTITLES) + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 +}, +{ + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSUBTITLES) + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 +}, +{ + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSUBTITLES) + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 +}, +{ + { + "fascination", + "CD Version (Censored)", + AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOSUBTITLES) + }, + kGameTypeFascination, + kFeaturesCD, + "intro.stk", 0, 0 +}, + +// -- Amiga -- + +{ + { + "fascination", + "", + AD_ENTRY1s("disk0.stk", "68b1c01564f774c0b640075fbad1b695", 189968), + DE_DEU, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesNone, + "disk0.stk", 0, 0 +}, +{ + { + "fascination", + "", + AD_ENTRY1s("disk0.stk", "7062117e9c5adfb6bfb2dac3ff74df9e", 189951), + EN_ANY, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesNone, + "disk0.stk", 0, 0 +}, +{ + { + "fascination", + "", + AD_ENTRY1s("disk0.stk", "55c154e5a3e8e98afebdcff4b522e1eb", 190005), + FR_FRA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesNone, + "disk0.stk", 0, 0 +}, +{ + { + "fascination", + "", + AD_ENTRY1s("disk0.stk", "7691827fff35df7799f14cfd6be178ad", 189931), + IT_ITA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesNone, + "disk0.stk", 0, 0 +}, + +// -- Atari ST -- + +{ + { + "fascination", + "", + AD_ENTRY1s("disk0.stk", "aff9fcc619f4dd19eae228affd0d34c8", 189964), + EN_ANY, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeFascination, + kFeaturesNone, + "disk0.stk", 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_FASCIN_H diff --git a/engines/gob/detection/tables_geisha.h b/engines/gob/detection/tables_geisha.h new file mode 100644 index 0000000000..331e17e31d --- /dev/null +++ b/engines/gob/detection/tables_geisha.h @@ -0,0 +1,76 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Geisha. */ + +#ifndef GOB_DETECTION_TABLES_GEISHA_H +#define GOB_DETECTION_TABLES_GEISHA_H + +// -- DOS EGA Floppy -- + +{ + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "6eebbb98ad90cd3c44549fc2ab30f632", 212153), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA | kFeaturesAdLib, + "disk1.stk", "intro.tot", 0 +}, +{ + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "f4d4d9d20f7ad1f879fc417d47faba89", 336732), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA | kFeaturesAdLib, + "disk1.stk", "intro.tot", 0 +}, + +// -- Amiga -- + +{ + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "e5892f00917c62423e93f5fd9920cf47", 208120), + UNK_LANG, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA, + "disk1.stk", "intro.tot", 0 +}, + +#endif // GOB_DETECTION_TABLES_GEISHA_H diff --git a/engines/gob/detection/tables_gob1.h b/engines/gob/detection/tables_gob1.h new file mode 100644 index 0000000000..e6086e990a --- /dev/null +++ b/engines/gob/detection/tables_gob1.h @@ -0,0 +1,716 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Gobliiins. */ + +#ifndef GOB_DETECTION_TABLES_GOB1_H +#define GOB_DETECTION_TABLES_GOB1_H + +// -- DOS EGA Floppy -- + +{ // Supplied by Florian Zeitz on scummvm-devel + { + "gob1", + "EGA", + AD_ENTRY1("intro.stk", "c65e9cc8ba23a38456242e1f2b1caad4"), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesEGA | kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob1", + "EGA", + AD_ENTRY1("intro.stk", "f9233283a0be2464248d83e14b95f09c"), + RU_RUS, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesEGA | kFeaturesAdLib, + 0, 0, 0 +}, + +// -- DOS VGA Floppy -- + +{ // Supplied by Theruler76 in bug report #1201233 + { + "gob1", + "VGA", + AD_ENTRY1("intro.stk", "26a9118c0770fa5ac93a9626761600b2"), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by raziel_ in bug report #1891864 + { + "gob1", + "VGA", + AD_ENTRY1s("intro.stk", "e157cb59c6d330ca70d12ab0ef1dd12b", 288972), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- DOS VGA CD -- + +{ // Provided by pykman in the forums. + { + "gob1cd", + "Polish", + AD_ENTRY1s("intro.stk", "97d2443948b2e367cf567fe7e101f5f2", 4049267), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.000 version. + { + "gob1cd", + "v1.000", + AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.000 version. + { + "gob1cd", + "v1.000", + AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.000 version. + { + "gob1cd", + "v1.000", + AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.000 version. + { + "gob1cd", + "v1.000", + AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.000 version. + { + "gob1cd", + "v1.000", + AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.02 version. Multilingual + { + "gob1cd", + "v1.02", + AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.02 version. Multilingual + { + "gob1cd", + "v1.02", + AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.02 version. Multilingual + { + "gob1cd", + "v1.02", + AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.02 version. Multilingual + { + "gob1cd", + "v1.02", + AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // CD 1.02 version. Multilingual + { + "gob1cd", + "v1.02", + AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + HU_HUN, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 +}, + +// -- Mac -- + +{ // Supplied by raina in the forums + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "6d837c6380d8f4d984c9f6cc0026df4f", 192712), + EN_ANY, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug report #1652352 + { + "gob1", + "", + AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), + EN_ANY, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug report #1652352 + { + "gob1", + "", + AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), + DE_DEU, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug report #1652352 + { + "gob1", + "", + AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), + FR_FRA, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug report #1652352 + { + "gob1", + "", + AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), + IT_ITA, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug report #1652352 + { + "gob1", + "", + AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), + ES_ESP, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Windows -- + +{ // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "gob1", + "Demo", + AD_ENTRY1("intro.stk", "972f22c6ff8144a6636423f0354ca549"), + UNK_LANG, + kPlatformAmiga, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "gob1", + "Interactive Demo", + AD_ENTRY1("intro.stk", "e72bd1e3828c7dec4c8a3e58c48bdfdb"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "gob1", + "Interactive Demo", + AD_ENTRY1s("intro.stk", "a796096280d5efd48cf8e7dfbe426eb5", 193595), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2785958 + { + "gob1", + "Interactive Demo", + AD_ENTRY1s("intro.stk", "35a098571af9a03c04e2303aec7c9249", 116582), + FR_FRA, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "gob1", + "", + AD_ENTRY1s("intro.stk", "0e022d3f2481b39e9175d37b2c6ad4c6", 2390121), + FR_FRA, + kPlatformCDi, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob1, + kFeaturesAdLib, + 0, "AVT003.TOT", 0 +}, + +#endif // GOB_DETECTION_TABLES_GOB1_H diff --git a/engines/gob/detection/tables_gob2.h b/engines/gob/detection/tables_gob2.h new file mode 100644 index 0000000000..659e6df063 --- /dev/null +++ b/engines/gob/detection/tables_gob2.h @@ -0,0 +1,641 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Gobliins 2: The Prince Buffoon. */ + +#ifndef GOB_DETECTION_TABLES_GOB2_H +#define GOB_DETECTION_TABLES_GOB2_H + +// -- DOS VGA Floppy -- + +{ + { + "gob2", + "", + AD_ENTRY1("intro.stk", "b45b984ee8017efd6ea965b9becd4d66"), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + AD_ENTRY1("intro.stk", "dedb5d31d8c8050a8cf77abedcc53dae"), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by raziel_ in bug report #1891867 + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "25a99827cd59751a80bed9620fb677a0", 893302), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "a13ecb4f6d8fd881ebbcc02e45cb5475", 837275), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by blackwhiteeagle in bug report #1605235 + { + "gob2", + "", + AD_ENTRY1("intro.stk", "3e4e7db0d201587dd2df4003b2993ef6"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + AD_ENTRY1("intro.stk", "a13892cdf4badda85a6f6fb47603a128"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2602017 + { + "gob2", + "", + AD_ENTRY1("intro.stk", "c47faf1d406504e6ffe63243610bb1f4"), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + AD_ENTRY1("intro.stk", "cd3e1df8b273636ee32e34b7064f50e8"), + RU_RUS, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by arcepi in bug report #1659884 + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "5f53c56e3aa2f1e76c2e4f0caa15887f", 829232), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- DOS VGA CD -- + +{ + { + "gob2cd", + "v1.000", + AD_ENTRY1("intro.stk", "9de5fbb41cf97182109e5fecc9d90347"), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by pykman in bug report #3067489 + { + "gob2cd", + "v2.01 Polish", + AD_ENTRY1s("intro.stk", "3025f05482b646c18c2c79c615a3a1df", 5011726), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "gob2cd", + "v2.01", + AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "gob2cd", + "v2.01", + AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "gob2cd", + "v2.01", + AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "gob2cd", + "v2.01", + AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "gob2cd", + "v2.01", + AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + HU_HUN, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 +}, + +// -- Windows -- + +{ + { + "gob2", + "", + { + {"intro.stk", 0, "285d7340f98ebad65d465585da12910b", 837286}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + { + {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + EN_USA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + { + {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + { + {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + { + {"intro.stk", 0, "6efac0a14c0de4d57dde8592456c8acf", 845172}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + EN_USA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "", + { + {"intro.stk", 0, "6efac0a14c0de4d57dde8592456c8acf", 845172}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1 + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "24489330a1d67ff978211f574822a5a6", 883756), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "285d7340f98ebad65d465585da12910b", 837286), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Mac -- + +{ // Supplied by fac76 in bug report #1673397 + { + "gob2", + "", + { + {"intro.stk", 0, "b45b984ee8017efd6ea965b9becd4d66", 828443}, + {"musmac1.mid", 0, "7f96f491448c7a001b32df89cf8d2af2", 1658}, + {0, 0, 0, 0} + }, + UNK_LANG, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by koalet in bug report #2478585 + { + "gob2", + "", + { + {"intro.stk", 0, "a13ecb4f6d8fd881ebbcc02e45cb5475", 837275}, + {"musmac1.mid", 0, "7f96f491448c7a001b32df89cf8d2af2", 1658}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Amiga -- + +{ // Supplied by fac76 in bug report #1883808 + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "eebf2810122cfd17399260cd1468e994", 554014), + EN_ANY, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "gob2", + "", + AD_ENTRY1("intro.stk", "d28b9e9b41f31acfa58dcd12406c7b2c"), + DE_DEU, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2602057 + { + "gob2", + "", + AD_ENTRY1("intro.stk", "686c88f7302a80b744aae9f8413e853d"), + IT_ITA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by aldozx in the forums + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "abc3e786cd78197773954c75815b278b", 554721), + ES_ESP, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Atari ST -- + +{ // Supplied by bgk in bug report #1706861 + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "4b13c02d1069b86bcfec80f4e474b98b", 554680), + FR_FRA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "gob2", + "Non-Interactive Demo", + AD_ENTRY1("intro.stk", "8b1c98ff2ab2e14f47a1b891e9b92217"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, "usa.tot", 0 +}, +{ + { + "gob2", + "Interactive Demo", + AD_ENTRY1("intro.stk", "cf1c95b2939bd8ff58a25c756cb6125e"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob2", + "Interactive Demo", + AD_ENTRY1("intro.stk", "4b278c2678ea01383fd5ca114d947eea"), + UNK_LANG, + kPlatformAmiga, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by polluks in bug report #1895126 + { + "gob2", + "Interactive Demo", + AD_ENTRY1s("intro.stk", "9fa85aea959fa8c582085855fbd99346", 553063), + UNK_LANG, + kPlatformAmiga, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob2, + kFeaturesNone, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_GOB2_H diff --git a/engines/gob/detection/tables_gob3.h b/engines/gob/detection/tables_gob3.h new file mode 100644 index 0000000000..22ec69054b --- /dev/null +++ b/engines/gob/detection/tables_gob3.h @@ -0,0 +1,564 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Goblins 3 / Goblins Quest 3. */ + +#ifndef GOB_DETECTION_TABLES_GOB3_H +#define GOB_DETECTION_TABLES_GOB3_H + +// -- DOS VGA Floppy -- + +{ + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "32b0f57f5ae79a9ae97e8011df38af42", 157084), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "904fc32032295baa3efb3a41f17db611", 178582), + HE_ISR, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by raziel_ in bug report #1891869 + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "16b014bf32dbd6ab4c5163c44f56fed1", 445104), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + AD_ENTRY1("intro.stk", "1e2f64ec8dfa89f42ee49936a27e66e7"), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by paul66 in bug report #1652352 + { + "gob3", + "", + AD_ENTRY1("intro.stk", "f6d225b25a180606fa5dbe6405c97380"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + AD_ENTRY1("intro.stk", "e42a4f2337d6549487a80864d7826972"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by Paranoimia on #scummvm + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "fe8144daece35538085adb59c2d29613", 159402), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + AD_ENTRY1("intro.stk", "4e3af248a48a2321364736afab868527"), + RU_RUS, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + AD_ENTRY1("intro.stk", "8d28ce1591b0e9cc79bf41cad0fc4c9c"), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2098621 + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "d3b72938fbbc8159198088811f9e6d19", 160382), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Windows -- + +{ + { + "gob3", + "", + { + {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + { + {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + { + {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + { + {"intro.stk", 0, "edd7403e5dc2a14459d2665a4c17714d", 209534}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + { + {"intro.stk", 0, "428e2de130cf3b303c938924539dc50d", 324420}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "", + { + {"intro.stk", 0, "428e2de130cf3b303c938924539dc50d", 324420}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in Found in french ADI 2.5 Anglais Multimedia 5e + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "edd7403e5dc2a14459d2665a4c17714d", 209534), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Mac -- + +{ // Supplied by fac76 in bug report #1742716 + { + "gob3", + "", + { + {"intro.stk", 0, "32b0f57f5ae79a9ae97e8011df38af42", 157084}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Amiga -- + +{ + { + "gob3", + "", + AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), + EN_GRB, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesNone, + 0, "menu.tot", 0 +}, +{ + { + "gob3", + "", + AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), + DE_DEU, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesNone, + 0, "menu.tot", 0 +}, + +// -- DOS VGA CD -- + +{ + { + "gob3cd", + "v1.000", + AD_ENTRY1("intro.stk", "6f2c226c62dd7ab0ab6f850e89d3fc47"), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by pykman in bug report #3067489 + { + "gob3cd", + "v1.02 Polish", + AD_ENTRY1s("intro.stk", "978afddcac81bb95a04757b61f78471c", 619825), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 + { + "gob3cd", + "v1.02", + AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 + { + "gob3cd", + "v1.02", + AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 + { + "gob3cd", + "v1.02", + AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 + { + "gob3cd", + "v1.02", + AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 + { + "gob3cd", + "v1.02", + AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + HU_HUN, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "gob3", + "Non-interactive Demo", + AD_ENTRY1("intro.stk", "b9b898fccebe02b69c086052d5024a55"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "Interactive Demo", + AD_ENTRY1("intro.stk", "7aebd94e49c2c5c518c9e7b74f25de9d"), + FR_FRA, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "Interactive Demo 2", + AD_ENTRY1("intro.stk", "e5dcbc9f6658ebb1e8fe26bc4da0806d"), + FR_FRA, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "gob3", + "Interactive Demo 3", + AD_ENTRY1s("intro.stk", "9e20ad7b471b01f84db526da34eaf0a2", 395561), + EN_ANY, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGob3, + kFeaturesAdLib, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_GOB3_H diff --git a/engines/gob/detection/tables_inca2.h b/engines/gob/detection/tables_inca2.h new file mode 100644 index 0000000000..26989f7d1a --- /dev/null +++ b/engines/gob/detection/tables_inca2.h @@ -0,0 +1,249 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Inca II: Wiracocha. */ + +#ifndef GOB_DETECTION_TABLES_INCA2_H +#define GOB_DETECTION_TABLES_INCA2_H + +// -- DOS VGA Floppy -- + +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- DOS VGA CD -- + +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesCD, + 0, 0, 0 +}, + +// -- Windows -- + +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + EN_USA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "inca2", + "Non-Interactive Demo", + { + {"cons.imd", 0, "f896ba0c4a1ac7f7260d342655980b49", 17804}, + {"conseil.imd", 0, "aaedd5482d5b271e233e86c5a03cf62e", 33999}, + {"int.imd", 0, "6308222fcefbcb20925f01c1aff70dee", 30871}, + {"inter.imd", 0, "39bd6d3540f3bedcc97293f352c7f3fc", 191719}, + {"machu.imd", 0, "c0bc8211d93b467bfd063b63fe61b85c", 34609}, + {"post.imd", 0, "d75cad0e3fc22cb0c8b6faf597f509b2", 1047709}, + {"posta.imd", 0, "2a5b3fe75681ddf4d21ac724db8111b4", 547250}, + {"postb.imd", 0, "24260ce4e80a4c472352b76637265d09", 868312}, + {"postc.imd", 0, "24accbcc8b83a9c2be4bd82849a2bd29", 415637}, + {"tum.imd", 0, "0993d4810ec9deb3f77c5e92095320fd", 20330}, + {"tumi.imd", 0, "bf53f229480d694de0947fe3366fbec6", 248952}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeInca2, + kFeaturesAdLib | kFeaturesBATDemo, + 0, 0, 7 +}, + +#endif // GOB_DETECTION_TABLES_INCA2_H diff --git a/engines/gob/detection/tables_lit.h b/engines/gob/detection/tables_lit.h new file mode 100644 index 0000000000..019d001f97 --- /dev/null +++ b/engines/gob/detection/tables_lit.h @@ -0,0 +1,484 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Lost in Time. */ + +#ifndef GOB_DETECTION_TABLES_LIT_H +#define GOB_DETECTION_TABLES_LIT_H + +// -- DOS VGA Floppy (Part I and II) -- + +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "7b7f48490dedc8a7cb999388e2fadbe3", 3930674), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "e0767783ff662ed93665446665693aef", 4371238), + HE_ISR, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by cartman_ on #scummvm + { + "lit", + "", + AD_ENTRY1s("intro.stk", "f1f78b663893b58887add182a77df151", 3944090), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2105220 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "cd322cb3c64ef2ba2f2134aa2122cfe9", 3936700), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2093672 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2093672 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2093672 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2093672 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2093672 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, +{ // Supplied by SiRoCs in bug report #2093672 + { + "lit", + "", + AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesCD, + 0, 0, 0 +}, + +// -- Windows (Part I and II) -- + +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4219382), + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4219382), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Found in french ADI 2.6 Francais-Maths 4e + { + "lit", + "", + AD_ENTRY1s("intro.stk", "58ee9583a4fb837f02d9a58e5f442656", 3937120), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Windows (Part I only) -- +{ + { + "lit1", + "Light install", + { + {"intro.stk", 0, "93c91bc9e783d00033042ae83144d7dd", 72318}, + {"partie2.itk", 0, "78f00bd8eb9e680e6289bba0130b1b33", 664064}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit1", + "Full install", + { + {"intro.stk", 0, "93c91bc9e783d00033042ae83144d7dd", 72318}, + {"partie2.itk", 0, "78f00bd8eb9e680e6289bba0130b1b33", 4396644}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Windows (Part II only) -- + +{ + { + "lit2", + "Light install", + AD_ENTRY1s("intro.stk", "17acbb212e62addbe48dc8f2282c98cb", 72318), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "lit2", + "Full install", + { + {"intro.stk", 0, "17acbb212e62addbe48dc8f2282c98cb", 72318}, + {"partie4.itk", 0, "6ce4967e0c79d7daeabc6c1d26783d4c", 2612087}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Mac (Part I and II) -- + +{ // Supplied by koalet in bug report #2479034 + { + "lit", + "", + { + {"intro.stk", 0, "af98bcdc70e1f1c1635577fd726fe7f1", 3937310}, + {"musmac1.mid", 0, "ae7229bb09c6abe4e60a2768b24bc890", 9398}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformMacintosh, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "lit", + "Demo", + AD_ENTRY1("demo.stk", "c06f8cc20eb239d4c71f225ce3093edf"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + "demo.stk", "demo.tot", 0 +}, +{ + { + "lit", + "Non-interactive Demo", + AD_ENTRY1("demo.stk", "2eba8abd9e3878c57307576012dd2fec"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + "demo.stk", "demo.tot", 0 +}, + +// -- Pirated! Do not re-add nor un-tag! -- + +{ + { + "lit", + "", + AD_ENTRY1s("intro.stk", "3712e7527ba8ce5637d2aadf62783005", 72318), + FR_FRA, + kPlatformPC, + ADGF_PIRATED, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLostInTime, + kFeaturesAdLib, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_LIT_H diff --git a/engines/gob/detection/tables_littlered.h b/engines/gob/detection/tables_littlered.h new file mode 100644 index 0000000000..2b41b65a71 --- /dev/null +++ b/engines/gob/detection/tables_littlered.h @@ -0,0 +1,265 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Once Upon A Time: Little Red Riding Hood. */ + +#ifndef GOB_DETECTION_TABLES_LITTLERED_H +#define GOB_DETECTION_TABLES_LITTLERED_H + +// -- DOS EGA Floppy -- + +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, + +// -- Windows -- + +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1 + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1 + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1 + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1 + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ // Found in french ADI 2 Francais-Maths CM1 + { + "littlered", + "", + AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, + +// -- Amiga -- + +{ + { + "littlered", + "", + { + {"intro.stk", 0, "0b72992f5d8b5e6e0330572a5753ea25", 256490}, + {"mod.babayaga", 0, "43484cde74e0860785f8e19f0bc776d1", 60248}, + {0, 0, 0, 0} + }, + UNK_LANG, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesNone, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_LITTLERED_H diff --git a/engines/gob/detection/tables_playtoons.h b/engines/gob/detection/tables_playtoons.h new file mode 100644 index 0000000000..4eb5945b04 --- /dev/null +++ b/engines/gob/detection/tables_playtoons.h @@ -0,0 +1,517 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for the Playtoons series. */ + +#ifndef GOB_DETECTION_TABLES_PLAYTOONS_H +#define GOB_DETECTION_TABLES_PLAYTOONS_H + +// -- Playtoons 1: Uncle Archibald -- + +{ + { + "playtoons1", + "", + { + {"playtoon.stk", 0, "8c98e9a11be9bb203a55e8c6e68e519b", 25574338}, + {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons1", + "Pack mes histoires anim\xE9""es", + { + {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, + {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons1", + "", + { + {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, + {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ // Supplied by scoriae in the forums + { + "playtoons1", + "", + { + {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, + {"archi.stk", 0, "00d8274519dfcf8a0d8ae3099daea0f8", 5532135}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons1", + "Non-Interactive Demo", + { + {"play123.scn", 0, "4689a31f543915e488c3bc46ea358add", 258}, + {"archi.vmd", 0, "a410fcc8116bc173f038100f5857191c", 5617210}, + {"chato.vmd", 0, "5a10e39cb66c396f2f9d8fb35e9ac016", 5445937}, + {"genedeb.vmd", 0, "3bb4a45585f88f4d839efdda6a1b582b", 1244228}, + {"generik.vmd", 0, "b46bdd64b063e86927fb2826500ad512", 603242}, + {"genespi.vmd", 0, "b7611916f32a370ae9832962fc17ef72", 758719}, + {"spirou.vmd", 0, "8513dbf7ac51c057b21d371d6b217b47", 2550788}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 3 +}, +{ + { + "playtoons1", + "Non-Interactive Demo", + { + {"e.scn", 0, "8a0db733c3f77be86e74e8242e5caa61", 124}, + {"demarchg.vmd", 0, "d14a95da7d8792faf5503f649ffcbc12", 5619415}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 4 +}, +{ + { + "playtoons1", + "Non-Interactive Demo", + { + {"i.scn", 0, "8b3294474d39970463663edd22341730", 285}, + {"demarita.vmd", 0, "84c8672b91c7312462603446e224bfec", 5742533}, + {"dembouit.vmd", 0, "7a5fdf0a4dbdfe72e31dd489ea0f8aa2", 3536786}, + {"demo5.vmd", 0, "2abb7b6a26406c984f389f0b24b5e28e", 13290970}, + {"demoita.vmd", 0, "b4c0622d14c8749965cd0f5dfca4cf4b", 1183566}, + {"wooddem3.vmd", 0, "a1700596172c2d4e264760030c3a3d47", 8994250}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 5 +}, +{ + { + "playtoons1", + "Non-Interactive Demo", + { + {"s.scn", 0, "1f527010626b5490761f16ba7a6f639a", 251}, + {"demaresp.vmd", 0, "3f860f944056842b35a5fd05416f208e", 5720619}, + {"demboues.vmd", 0, "3a0caa10c98ef92a15942f8274075b43", 3535838}, + {"demo5.vmd", 0, "2abb7b6a26406c984f389f0b24b5e28e", 13290970}, + {"wooddem3.vmd", 0, "a1700596172c2d4e264760030c3a3d47", 8994250}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 6 +}, + +// -- Playtoons 2: The Case of the Counterfeit Collaborator (Spirou) -- + +{ + { + "playtoons2", + "", + { + {"playtoon.stk", 0, "4772c96be88a57f0561519e4a1526c62", 24406262}, + {"spirou.stk", 0, "5d9c7644d0c47840169b4d016765cc1a", 9816201}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons2", + "", + { + {"playtoon.stk", 0, "55a85036dd93cce93532d8f743d90074", 17467154}, + {"spirou.stk", 0, "e3e1b6148dd72fafc3637f1a8e5764f5", 9812043}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons2", + "", + { + {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, + {"spirou.stk", 0, "91080dc148de1bbd6a97321c1a1facf3", 9817086}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ // Supplied by Hkz + { + "playtoons2", + "", + { + {"playtoon.stk", 0, "2572685400852d12759a2fbf09ec88eb", 9698780}, + {"spirou.stk", 0, "d3cfeff920b6343a2ece55088f530dba", 7076608}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ // Supplied by scoriae in the forums + { + "playtoons2", + "", + { + {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, + {"spirou.stk", 0, "993737f112ca6a9b33c814273280d832", 9825760}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Playtoons 3: The Secret of the Castle -- + +{ + { + "playtoons3", + "", + { + {"playtoon.stk", 0, "8c98e9a11be9bb203a55e8c6e68e519b", 25574338}, + {"chato.stk", 0, "4fa4ed96a427c344e9f916f9f236598d", 6033793}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons3", + "", + { + {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, + {"chato.stk", 0, "8fc8d0da5b3e758908d1d7298d497d0b", 6041026}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons3", + "Pack mes histoires anim\xE9""es", + { + {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, + {"chato.stk", 0, "4fa4ed96a427c344e9f916f9f236598d", 6033793}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ + { + "playtoons3", + "", + { + {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, + {"chato.stk", 0, "3c6cb3ac8a5a7cf681a19971a92a748d", 6033791}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "playtoons3", + "", + { + {"playtoon.stk", 0, "4772c96be88a57f0561519e4a1526c62", 24406262}, + {"chato.stk", 0, "bdef407387112bfcee90e664865ac3af", 6033867}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Playtoons 4: The Mandarin Prince -- + +{ + { + "playtoons4", + "", + { + {"playtoon.stk", 0, "b7f5afa2dc1b0f75970b7c07d175db1b", 24340406}, + {"manda.stk", 0, "92529e0b927191d9898a34c2892e9a3a", 6485072}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, +{ //Supplied by goodoldgeorg in bug report #2820006 + { + "playtoons4", + "", + { + {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, + {"manda.stk", 0, "69a79c9f61b2618e482726f2ff68078d", 6499208}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Playtoons 5: The Stone of Wakan -- + +{ + { + "playtoons5", + "", + { + {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, + {"wakan.stk", 0, "f493bf82851bc5ba74d57de6b7e88df8", 5520153}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Playtoons Construction Kit 1: Monsters -- + +{ + { + "playtnck1", + "", + { + {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, + {"dan.itk", 0, "906d67b3e438d5e95ec7ea9e781a94f3", 3000320}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Playtoons Construction Kit 2: Knights -- + +{ + { + "playtnck2", + "", + { + {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, + {"dan.itk", 0, "74eeb075bd2cb47b243349730264af01", 3213312}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Playtoons Construction Kit 3: Far West -- + +{ + { + "playtnck3", + "", + { + {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, + {"dan.itk", 0, "9a8f62809eca5a52f429b5b6a8e70f8f", 2861056}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypePlaytoons, + kFeatures640x480, + "intro2.stk", 0, 0 +}, + +// -- Bambou le sauveur de la jungle -- + +{ + { + "bambou", + "", + { + {"intro.stk", 0, "2f8db6963ff8d72a8331627ebda918f4", 3613238}, + {"bambou.itk", 0, "0875914d31126d0749313428f10c7768", 114440192}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeBambou, + kFeatures640x480, + "intro.stk", "intro.tot", 0 +}, + +#endif // GOB_DETECTION_TABLES_PLAYTOONS_H diff --git a/engines/gob/detection/tables_urban.h b/engines/gob/detection/tables_urban.h new file mode 100644 index 0000000000..d24f6a5011 --- /dev/null +++ b/engines/gob/detection/tables_urban.h @@ -0,0 +1,151 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Urban Runner. */ + +#ifndef GOB_DETECTION_TABLES_URBAN_H +#define GOB_DETECTION_TABLES_URBAN_H + +// -- Windows -- + +{ + { + "urban", + "", + AD_ENTRY1s("intro.stk", "3ab2c542bd9216ae5d02cc6f45701ae1", 1252436), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, +{ // Supplied by Collector9 in bug report #3228040 + { + "urban", + "", + AD_ENTRY1s("intro.stk", "6ce3d878178932053267237ec4843ce1", 1252518), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, +{ // Supplied by gamin in the forums + { + "urban", + "", + AD_ENTRY1s("intro.stk", "b991ed1d31c793e560edefdb349882ef", 1276408), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, +{ // Supplied by jvprat on #scummvm + { + "urban", + "", + AD_ENTRY1s("intro.stk", "4ec3c0864e2b54c5b4ccf9f6ad96528d", 1253328), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, +{ // Supplied by Alex on the gobsmacked blog + { + "urban", + "", + AD_ENTRY1s("intro.stk", "9ea647085a16dd0fb9ecd84cd8778ec9", 1253436), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, +{ // Supplied by alex86r in bug report #3297602 + { + "urban", + "", + AD_ENTRY1s("intro.stk", "4e4a3c017fe5475353bf94c455fe3efd", 1253448), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2770340 + { + "urban", + "", + AD_ENTRY1s("intro.stk", "4bd31979ea3d77a58a358c09000a85ed", 1253018), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "urban", + "Non-Interactive Demo", + { + {"wdemo.s24", 0, "14ac9bd51db7a075d69ddb144904b271", 87}, + {"demo.vmd", 0, "65d04715d871c292518b56dd160b0161", 9091237}, + {"urband.vmd", 0, "60343891868c91854dd5c82766c70ecc", 922461}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO1(GUIO_NOASPECT) + }, + kGameTypeUrban, + kFeatures640x480 | kFeaturesTrueColor | kFeaturesSCNDemo, + 0, 0, 2 +}, + +#endif // GOB_DETECTION_TABLES_URBAN_H diff --git a/engines/gob/detection/tables_ween.h b/engines/gob/detection/tables_ween.h new file mode 100644 index 0000000000..a02b931b85 --- /dev/null +++ b/engines/gob/detection/tables_ween.h @@ -0,0 +1,349 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Ween: The Prophecy. */ + +#ifndef GOB_DETECTION_TABLES_WEEN_H +#define GOB_DETECTION_TABLES_WEEN_H + +// -- DOS VGA Floppy -- + +{ + { + "ween", + "", + AD_ENTRY1("intro.stk", "2bb8878a8042244dd2b96ff682381baa"), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "ween", + "", + AD_ENTRY1s("intro.stk", "de92e5c6a8c163007ffceebef6e67f7d", 7117568), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by cybot_tmin in bug report #1667743 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "6d60f9205ecfbd8735da2ee7823a70dc", 7014426), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "ween", + "", + AD_ENTRY1("intro.stk", "4b10525a3782aa7ecd9d833b5c1d308b"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by cartman_ on #scummvm + { + "ween", + "", + AD_ENTRY1("intro.stk", "63170e71f04faba88673b3f510f9c4c8"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by glorfindel in bugreport #1722142 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "8b57cd510da8a3bbd99e3a0297a8ebd1", 7018771), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Amiga -- + +{ // Supplied by vampir_raziel in bug report #1658373 + { + "ween", + "", + { + {"intro.stk", 0, "bfd9d02faf3d8d60a2cf744f95eb48dd", 456570}, + {"ween.ins", 0, "d2cb24292c9ddafcad07e23382027218", 87800}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by vampir_raziel in bug report #1658373 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "257fe669705ac4971efdfd5656eef16a", 457719), + FR_FRA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by vampir_raziel in bug report #1658373 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "dffd1ab98fe76150d6933329ca6f4cc4", 459458), + FR_FRA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by vampir_raziel in bug report #1658373 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "af83debf2cbea21faa591c7b4608fe92", 458192), + DE_DEU, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2563539 + { + "ween", + "", + { + {"intro.stk", 0, "dffd1ab98fe76150d6933329ca6f4cc4", 459458}, + {"ween.ins", 0, "d2cb24292c9ddafcad07e23382027218", 87800}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, + +// -- Atari ST -- + +{ // Supplied by pwigren in bug report #1764174 + { + "ween", + "", + { + {"intro.stk", 0, "bfd9d02faf3d8d60a2cf744f95eb48dd", 456570}, + {"music__5.snd", 0, "7d1819b9981ecddd53d3aacbc75f1cc8", 13446}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, +{ + { + "ween", + "", + AD_ENTRY1("intro.stk", "e6d13fb3b858cb4f78a8780d184d5b2c"), + FR_FRA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesNone, + 0, 0, 0 +}, + +// -- DOS VGA Floppy -- + +{ + { + "ween", + "", + AD_ENTRY1("intro.stk", "2bb8878a8042244dd2b96ff682381baa"), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "ween", + "", + AD_ENTRY1s("intro.stk", "de92e5c6a8c163007ffceebef6e67f7d", 7117568), + EN_USA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by cybot_tmin in bug report #1667743 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "6d60f9205ecfbd8735da2ee7823a70dc", 7014426), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ + { + "ween", + "", + AD_ENTRY1("intro.stk", "4b10525a3782aa7ecd9d833b5c1d308b"), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by cartman_ on #scummvm + { + "ween", + "", + AD_ENTRY1("intro.stk", "63170e71f04faba88673b3f510f9c4c8"), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, +{ // Supplied by glorfindel in bugreport #1722142 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "8b57cd510da8a3bbd99e3a0297a8ebd1", 7018771), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "ween", + "Demo", + AD_ENTRY1("intro.stk", "2e9c2898f6bf206ede801e3b2e7ee428"), + UNK_LANG, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, "show.tot", 0 +}, +{ + { + "ween", + "Demo", + AD_ENTRY1("intro.stk", "15fb91a1b9b09684b28ac75edf66e504"), + EN_USA, + kPlatformPC, + ADGF_DEMO, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeWeen, + kFeaturesAdLib, + 0, "show.tot", 0 +}, + +#endif // GOB_DETECTION_TABLES_WEEN_H diff --git a/engines/gob/detection/tables_woodruff.h b/engines/gob/detection/tables_woodruff.h new file mode 100644 index 0000000000..e369539984 --- /dev/null +++ b/engines/gob/detection/tables_woodruff.h @@ -0,0 +1,402 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for (The Bizarre Adventures of) Woodruff and the Schnibble (of Azimuth). */ + +#ifndef GOB_DETECTION_TABLES_WOODRUFF_H +#define GOB_DETECTION_TABLES_WOODRUFF_H + +// -- Windows CD -- + +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "5f5f4e0a72c33391e67a47674b120cc6", 20296422), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by jvprat on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by jvprat on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by jvprat on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by jvprat on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by jvprat on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by Hkz on #scummvm + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by DjDiabolik in bug report #1971294 + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), + EN_GRB, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by DjDiabolik in bug report #1971294 + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by DjDiabolik in bug report #1971294 + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by DjDiabolik in bug report #1971294 + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by DjDiabolik in bug report #1971294 + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, +{ // Supplied by goodoldgeorg in bug report #2098838 + { + "woodruff", + "", + AD_ENTRY1s("intro.stk", "08a96bf061af1fa4f75c6a7cc56b60a4", 20734979), + PL_POL, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480, + 0, 0, 0 +}, + +// -- Demos -- + +{ + { + "woodruff", + "Non-Interactive Demo", + { + {"demo.scn", 0, "16bb85fc5f8e519147b60475dbf33962", 89}, + {"wooddem3.vmd", 0, "a1700596172c2d4e264760030c3a3d47", 8994250}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) + }, + kGameTypeWoodruff, + kFeatures640x480 | kFeaturesSCNDemo, + 0, 0, 1 +}, + +#endif // GOB_DETECTION_TABLES_WOODRUFF_H diff --git a/engines/gob/detection_tables.h b/engines/gob/detection_tables.h deleted file mode 100644 index f3dc375fc3..0000000000 --- a/engines/gob/detection_tables.h +++ /dev/null @@ -1,5276 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -namespace Gob { - -static const GOBGameDescription gameDescriptions[] = { - { // Supplied by Florian Zeitz on scummvm-devel - { - "gob1", - "EGA", - AD_ENTRY1("intro.stk", "c65e9cc8ba23a38456242e1f2b1caad4"), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesEGA | kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob1", - "EGA", - AD_ENTRY1("intro.stk", "f9233283a0be2464248d83e14b95f09c"), - RU_RUS, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesEGA | kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Theruler76 in bug report #1201233 - { - "gob1", - "VGA", - AD_ENTRY1("intro.stk", "26a9118c0770fa5ac93a9626761600b2"), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by raziel_ in bug report #1891864 - { - "gob1", - "VGA", - AD_ENTRY1s("intro.stk", "e157cb59c6d330ca70d12ab0ef1dd12b", 288972), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by raina in the forums - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "6d837c6380d8f4d984c9f6cc0026df4f", 192712), - EN_ANY, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by paul66 in bug report #1652352 - { - "gob1", - "", - AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), - EN_ANY, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by paul66 in bug report #1652352 - { - "gob1", - "", - AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), - DE_DEU, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by paul66 in bug report #1652352 - { - "gob1", - "", - AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), - FR_FRA, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by paul66 in bug report #1652352 - { - "gob1", - "", - AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), - IT_ITA, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by paul66 in bug report #1652352 - { - "gob1", - "", - AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), - ES_ESP, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "gob1", - "", - { - {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "gob1", - "", - { - {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - IT_ITA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "gob1", - "", - { - {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "gob1", - "", - { - {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "gob1", - "", - { - {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob1", - "", - { - {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob1", - "", - { - {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob1", - "", - { - {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob1", - "", - { - {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - IT_ITA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob1", - "", - { - {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, - {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), - IT_ITA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "f5f028ee39c456fa51fa63b606583918", 313472), - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Provided by pykman in the forums. - { - "gob1cd", - "Polish", - AD_ENTRY1s("intro.stk", "97d2443948b2e367cf567fe7e101f5f2", 4049267), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.000 version. - { - "gob1cd", - "v1.000", - AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.000 version. - { - "gob1cd", - "v1.000", - AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.000 version. - { - "gob1cd", - "v1.000", - AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.000 version. - { - "gob1cd", - "v1.000", - AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.000 version. - { - "gob1cd", - "v1.000", - AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.02 version. Multilingual - { - "gob1cd", - "v1.02", - AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.02 version. Multilingual - { - "gob1cd", - "v1.02", - AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.02 version. Multilingual - { - "gob1cd", - "v1.02", - AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.02 version. Multilingual - { - "gob1cd", - "v1.02", - AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // CD 1.02 version. Multilingual - { - "gob1cd", - "v1.02", - AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob1cd", - "v1.02", - AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), - HU_HUN, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob1cd", - "v1.02", - AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob1cd", - "v1.02", - AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob1cd", - "v1.02", - AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob1", - "Demo", - AD_ENTRY1("intro.stk", "972f22c6ff8144a6636423f0354ca549"), - UNK_LANG, - kPlatformAmiga, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "gob1", - "Interactive Demo", - AD_ENTRY1("intro.stk", "e72bd1e3828c7dec4c8a3e58c48bdfdb"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "gob1", - "Interactive Demo", - AD_ENTRY1s("intro.stk", "a796096280d5efd48cf8e7dfbe426eb5", 193595), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2785958 - { - "gob1", - "Interactive Demo", - AD_ENTRY1s("intro.stk", "35a098571af9a03c04e2303aec7c9249", 116582), - FR_FRA, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "gob1", - "", - AD_ENTRY1s("intro.stk", "0e022d3f2481b39e9175d37b2c6ad4c6", 2390121), - FR_FRA, - kPlatformCDi, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesAdLib, - 0, "AVT003.TOT", 0 - }, - { // Supplied by fac76 in bug report #1883808 - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "eebf2810122cfd17399260cd1468e994", 554014), - EN_ANY, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "gob2", - "", - AD_ENTRY1("intro.stk", "d28b9e9b41f31acfa58dcd12406c7b2c"), - DE_DEU, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2602057 - { - "gob2", - "", - AD_ENTRY1("intro.stk", "686c88f7302a80b744aae9f8413e853d"), - IT_ITA, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by aldozx in the forums - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "abc3e786cd78197773954c75815b278b", 554721), - ES_ESP, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by bgk in bug report #1706861 - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "4b13c02d1069b86bcfec80f4e474b98b", 554680), - FR_FRA, - kPlatformAtariST, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by fac76 in bug report #1673397 - { - "gob2", - "", - { - {"intro.stk", 0, "b45b984ee8017efd6ea965b9becd4d66", 828443}, - {"musmac1.mid", 0, "7f96f491448c7a001b32df89cf8d2af2", 1658}, - {0, 0, 0, 0} - }, - UNK_LANG, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by koalet in bug report #2478585 - { - "gob2", - "", - { - {"intro.stk", 0, "a13ecb4f6d8fd881ebbcc02e45cb5475", 837275}, - {"musmac1.mid", 0, "7f96f491448c7a001b32df89cf8d2af2", 1658}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - AD_ENTRY1("intro.stk", "b45b984ee8017efd6ea965b9becd4d66"), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - AD_ENTRY1("intro.stk", "dedb5d31d8c8050a8cf77abedcc53dae"), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by raziel_ in bug report #1891867 - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "25a99827cd59751a80bed9620fb677a0", 893302), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "a13ecb4f6d8fd881ebbcc02e45cb5475", 837275), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by blackwhiteeagle in bug report #1605235 - { - "gob2", - "", - AD_ENTRY1("intro.stk", "3e4e7db0d201587dd2df4003b2993ef6"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - AD_ENTRY1("intro.stk", "a13892cdf4badda85a6f6fb47603a128"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2602017 - { - "gob2", - "", - AD_ENTRY1("intro.stk", "c47faf1d406504e6ffe63243610bb1f4"), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - AD_ENTRY1("intro.stk", "cd3e1df8b273636ee32e34b7064f50e8"), - RU_RUS, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by arcepi in bug report #1659884 - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "5f53c56e3aa2f1e76c2e4f0caa15887f", 829232), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - { - {"intro.stk", 0, "285d7340f98ebad65d465585da12910b", 837286}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - { - {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - EN_USA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - { - {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - { - {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - { - {"intro.stk", 0, "6efac0a14c0de4d57dde8592456c8acf", 845172}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - EN_USA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "", - { - {"intro.stk", 0, "6efac0a14c0de4d57dde8592456c8acf", 845172}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in french ADI 2 Francais-Maths CM1 - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "24489330a1d67ff978211f574822a5a6", 883756), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob2", - "", - AD_ENTRY1s("intro.stk", "285d7340f98ebad65d465585da12910b", 837286), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2cd", - "v1.000", - AD_ENTRY1("intro.stk", "9de5fbb41cf97182109e5fecc9d90347"), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by pykman in bug report #3067489 - { - "gob2cd", - "v2.01 Polish", - AD_ENTRY1s("intro.stk", "3025f05482b646c18c2c79c615a3a1df", 5011726), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob2cd", - "v2.01", - AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob2cd", - "v2.01", - AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob2cd", - "v2.01", - AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob2cd", - "v2.01", - AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob2cd", - "v2.01", - AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob2cd", - "v1.02", - AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), - HU_HUN, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob2cd", - "v1.02", - AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob2cd", - "v1.02", - AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob2cd", - "v1.02", - AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob2cd", - "v1.02", - AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob2", - "Non-Interactive Demo", - AD_ENTRY1("intro.stk", "8b1c98ff2ab2e14f47a1b891e9b92217"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, "usa.tot", 0 - }, - { - { - "gob2", - "Interactive Demo", - AD_ENTRY1("intro.stk", "cf1c95b2939bd8ff58a25c756cb6125e"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob2", - "Interactive Demo", - AD_ENTRY1("intro.stk", "4b278c2678ea01383fd5ca114d947eea"), - UNK_LANG, - kPlatformAmiga, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by polluks in bug report #1895126 - { - "gob2", - "Interactive Demo", - AD_ENTRY1s("intro.stk", "9fa85aea959fa8c582085855fbd99346", 553063), - UNK_LANG, - kPlatformAmiga, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by vampir_raziel in bug report #1658373 - { - "ween", - "", - { - {"intro.stk", 0, "bfd9d02faf3d8d60a2cf744f95eb48dd", 456570}, - {"ween.ins", 0, "d2cb24292c9ddafcad07e23382027218", 87800}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by vampir_raziel in bug report #1658373 - { - "ween", - "", - AD_ENTRY1s("intro.stk", "257fe669705ac4971efdfd5656eef16a", 457719), - FR_FRA, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by vampir_raziel in bug report #1658373 - { - "ween", - "", - AD_ENTRY1s("intro.stk", "dffd1ab98fe76150d6933329ca6f4cc4", 459458), - FR_FRA, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by vampir_raziel in bug report #1658373 - { - "ween", - "", - AD_ENTRY1s("intro.stk", "af83debf2cbea21faa591c7b4608fe92", 458192), - DE_DEU, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2563539 - { - "ween", - "", - { - {"intro.stk", 0, "dffd1ab98fe76150d6933329ca6f4cc4", 459458}, - {"ween.ins", 0, "d2cb24292c9ddafcad07e23382027218", 87800}, - {0, 0, 0, 0} - }, - IT_ITA, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by pwigren in bug report #1764174 - { - "ween", - "", - { - {"intro.stk", 0, "bfd9d02faf3d8d60a2cf744f95eb48dd", 456570}, - {"music__5.snd", 0, "7d1819b9981ecddd53d3aacbc75f1cc8", 13446}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformAtariST, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "ween", - "", - AD_ENTRY1("intro.stk", "e6d13fb3b858cb4f78a8780d184d5b2c"), - FR_FRA, - kPlatformAtariST, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "ween", - "", - AD_ENTRY1("intro.stk", "2bb8878a8042244dd2b96ff682381baa"), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "ween", - "", - AD_ENTRY1s("intro.stk", "de92e5c6a8c163007ffceebef6e67f7d", 7117568), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by cybot_tmin in bug report #1667743 - { - "ween", - "", - AD_ENTRY1s("intro.stk", "6d60f9205ecfbd8735da2ee7823a70dc", 7014426), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "ween", - "", - AD_ENTRY1("intro.stk", "4b10525a3782aa7ecd9d833b5c1d308b"), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by cartman_ on #scummvm - { - "ween", - "", - AD_ENTRY1("intro.stk", "63170e71f04faba88673b3f510f9c4c8"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by glorfindel in bugreport #1722142 - { - "ween", - "", - AD_ENTRY1s("intro.stk", "8b57cd510da8a3bbd99e3a0297a8ebd1", 7018771), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "ween", - "Demo", - AD_ENTRY1("intro.stk", "2e9c2898f6bf206ede801e3b2e7ee428"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, "show.tot", 0 - }, - { - { - "ween", - "Demo", - AD_ENTRY1("intro.stk", "15fb91a1b9b09684b28ac75edf66e504"), - EN_USA, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeWeen, - kFeaturesAdLib, - 0, "show.tot", 0 - }, - { - { - "bargon", - "", - AD_ENTRY1("intro.stk", "da3c54be18ab73fbdb32db24624a9c23"), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by Trekky in the forums - { - "bargon", - "", - AD_ENTRY1s("intro.stk", "2f54b330d21f65b04b7c1f8cca76426c", 262109), - FR_FRA, - kPlatformAtariST, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by cesardark in bug #1681649 - { - "bargon", - "", - AD_ENTRY1s("intro.stk", "11103b304286c23945560b391fd37e7d", 3181890), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by paul66 in bug #1692667 - { - "bargon", - "", - AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by pwigren in bugreport #1764174 - { - "bargon", - "", - AD_ENTRY1s("intro.stk", "569d679fe41d49972d34c9fce5930dda", 269825), - EN_ANY, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by kizkoool in bugreport #2089734 - { - "bargon", - "", - AD_ENTRY1s("intro.stk", "00f6b4e2ee26e5c40b488e2df5adcf03", 3975580), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { // Supplied by glorfindel in bugreport #1722142 - { - "bargon", - "Fanmade", - AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - { - {"intro.stk", 0, "0b72992f5d8b5e6e0330572a5753ea25", 256490}, - {"mod.babayaga", 0, "43484cde74e0860785f8e19f0bc776d1", 60248}, - {0, 0, 0, 0} - }, - UNK_LANG, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), - IT_ITA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "113a16877e4f72037d9714be1c2b0221", 1187522), - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { // Found in french ADI 2 Francais-Maths CM1 - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { // Found in french ADI 2 Francais-Maths CM1 - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { // Found in french ADI 2 Francais-Maths CM1 - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { // Found in french ADI 2 Francais-Maths CM1 - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), - IT_ITA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, - { // Found in french ADI 2 Francais-Maths CM1 - { - "littlered", - "", - AD_ENTRY1s("intro.stk", "5c15b37ed27ac2470854e9e09374d50e", 1248610), - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLittleRed, - kFeaturesAdLib | kFeaturesEGA, - 0, 0, 0 - }, -// This version is not detected on purpose: it's a pirated version. -// Tagged ADGF_PIRATED! Do not re-add nor un-tag! - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "3712e7527ba8ce5637d2aadf62783005", 72318), - FR_FRA, - kPlatformPC, - ADGF_PIRATED, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "7b7f48490dedc8a7cb999388e2fadbe3", 3930674), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "e0767783ff662ed93665446665693aef", 4371238), - HE_ISR, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by cartman_ on #scummvm - { - "lit", - "", - AD_ENTRY1s("intro.stk", "f1f78b663893b58887add182a77df151", 3944090), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2105220 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "cd322cb3c64ef2ba2f2134aa2122cfe9", 3936700), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by koalet in bug report #2479034 - { - "lit", - "", - { - {"intro.stk", 0, "af98bcdc70e1f1c1635577fd726fe7f1", 3937310}, - {"musmac1.mid", 0, "ae7229bb09c6abe4e60a2768b24bc890", 9398}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2093672 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2093672 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2093672 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2093672 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2093672 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2093672 - { - "lit", - "", - AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4219382), - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "", - AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4219382), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in french ADI 2.6 Francais-Maths 4e - { - "lit", - "", - AD_ENTRY1s("intro.stk", "58ee9583a4fb837f02d9a58e5f442656", 3937120), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit1", - "Full install", - { - {"intro.stk", 0, "93c91bc9e783d00033042ae83144d7dd", 72318}, - {"partie2.itk", 0, "78f00bd8eb9e680e6289bba0130b1b33", 4396644}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit1", - "Light install", - { - {"intro.stk", 0, "93c91bc9e783d00033042ae83144d7dd", 72318}, - {"partie2.itk", 0, "78f00bd8eb9e680e6289bba0130b1b33", 664064}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit2", - "Light install", - AD_ENTRY1s("intro.stk", "17acbb212e62addbe48dc8f2282c98cb", 72318), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit2", - "Full install", - { - {"intro.stk", 0, "17acbb212e62addbe48dc8f2282c98cb", 72318}, - {"partie4.itk", 0, "6ce4967e0c79d7daeabc6c1d26783d4c", 2612087}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "lit", - "Demo", - AD_ENTRY1("demo.stk", "c06f8cc20eb239d4c71f225ce3093edf"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - "demo.stk", "demo.tot", 0 - }, - { - { - "lit", - "Non-interactive Demo", - AD_ENTRY1("demo.stk", "2eba8abd9e3878c57307576012dd2fec"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - "demo.stk", "demo.tot", 0 - }, - { // Supplied by scoriae - { - "fascination", - "VGA", - AD_ENTRY1s("disk0.stk", "c14330d052fe4da5a441ac9d81bc5891", 1061955), - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesAdLib, - "disk0.stk", 0, 0 - }, - { // Supplied by alex86r in bug report #3297633 - { - "fascination", - "VGA 3 disks edition", - AD_ENTRY1s("disk0.stk", "ab3dfdce43917bc806812959d692fc8f", 1061929), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesAdLib, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "VGA 3 disks edition", - AD_ENTRY1s("disk0.stk", "a50a8495e1b2d67699fb562cb98fc3e2", 1064387), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesAdLib, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "Hebrew edition (censored)", - AD_ENTRY1s("intro.stk", "d6e45ce548598727e2b5587a99718eba", 1055909), - HE_ISR, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesAdLib, - "intro.stk", 0, 0 - }, - { // Supplied by windlepoons in bug report #2809247 - { - "fascination", - "VGA 3 disks edition", - AD_ENTRY1s("disk0.stk", "3a24e60a035250189643c86a9ceafb97", 1062480), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesAdLib, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "VGA", - AD_ENTRY1s("disk0.stk", "e8ab4f200a2304849f462dc901705599", 183337), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesAdLib, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "", - AD_ENTRY1s("disk0.stk", "68b1c01564f774c0b640075fbad1b695", 189968), - DE_DEU, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesNone, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "", - AD_ENTRY1s("disk0.stk", "7062117e9c5adfb6bfb2dac3ff74df9e", 189951), - EN_ANY, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesNone, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "", - AD_ENTRY1s("disk0.stk", "55c154e5a3e8e98afebdcff4b522e1eb", 190005), - FR_FRA, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesNone, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "", - AD_ENTRY1s("disk0.stk", "7691827fff35df7799f14cfd6be178ad", 189931), - IT_ITA, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesNone, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "", - AD_ENTRY1s("disk0.stk", "aff9fcc619f4dd19eae228affd0d34c8", 189964), - EN_ANY, - kPlatformAtariST, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesNone, - "disk0.stk", 0, 0 - }, - { - { - "fascination", - "CD Version (Censored)", - AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOSUBTITLES) - }, - kGameTypeFascination, - kFeaturesCD, - "intro.stk", 0, 0 - }, - { - { - "fascination", - "CD Version (Censored)", - AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOSUBTITLES) - }, - kGameTypeFascination, - kFeaturesCD, - "intro.stk", 0, 0 - }, - { - { - "fascination", - "CD Version (Censored)", - AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOSUBTITLES) - }, - kGameTypeFascination, - kFeaturesCD, - "intro.stk", 0, 0 - }, - { - { - "fascination", - "CD Version (Censored)", - AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOSUBTITLES) - }, - kGameTypeFascination, - kFeaturesCD, - "intro.stk", 0, 0 - }, - { - { - "fascination", - "CD Version (Censored)", - AD_ENTRY1s("intro.stk", "9c61e9c22077f72921f07153e37ccf01", 545953), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOSUBTITLES) - }, - kGameTypeFascination, - kFeaturesCD, - "intro.stk", 0, 0 - }, - { - { - "geisha", - "", - AD_ENTRY1s("disk1.stk", "6eebbb98ad90cd3c44549fc2ab30f632", 212153), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGeisha, - kFeaturesEGA | kFeaturesAdLib, - "disk1.stk", "intro.tot", 0 - }, - { - { - "geisha", - "", - AD_ENTRY1s("disk1.stk", "f4d4d9d20f7ad1f879fc417d47faba89", 336732), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGeisha, - kFeaturesEGA | kFeaturesAdLib, - "disk1.stk", "intro.tot", 0 - }, - { - { - "geisha", - "", - AD_ENTRY1s("disk1.stk", "e5892f00917c62423e93f5fd9920cf47", 208120), - UNK_LANG, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGeisha, - kFeaturesEGA, - "disk1.stk", "intro.tot", 0 - }, - { - { - "gob3", - "", - AD_ENTRY1s("intro.stk", "32b0f57f5ae79a9ae97e8011df38af42", 157084), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - AD_ENTRY1s("intro.stk", "904fc32032295baa3efb3a41f17db611", 178582), - HE_ISR, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by raziel_ in bug report #1891869 - { - "gob3", - "", - AD_ENTRY1s("intro.stk", "16b014bf32dbd6ab4c5163c44f56fed1", 445104), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - { - {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, - {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - { - {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, - {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - { - {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, - {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by fac76 in bug report #1742716 - { - "gob3", - "", - { - {"intro.stk", 0, "32b0f57f5ae79a9ae97e8011df38af42", 157084}, - {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - AD_ENTRY1("intro.stk", "1e2f64ec8dfa89f42ee49936a27e66e7"), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by paul66 in bug report #1652352 - { - "gob3", - "", - AD_ENTRY1("intro.stk", "f6d225b25a180606fa5dbe6405c97380"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - AD_ENTRY1("intro.stk", "e42a4f2337d6549487a80864d7826972"), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by Paranoimia on #scummvm - { - "gob3", - "", - AD_ENTRY1s("intro.stk", "fe8144daece35538085adb59c2d29613", 159402), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - AD_ENTRY1("intro.stk", "4e3af248a48a2321364736afab868527"), - RU_RUS, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - AD_ENTRY1("intro.stk", "8d28ce1591b0e9cc79bf41cad0fc4c9c"), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Supplied by SiRoCs in bug report #2098621 - { - "gob3", - "", - AD_ENTRY1s("intro.stk", "d3b72938fbbc8159198088811f9e6d19", 160382), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), - EN_GRB, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesNone, - 0, "menu.tot", 0 - }, - { - { - "gob3", - "", - AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), - DE_DEU, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesNone, - 0, "menu.tot", 0 - }, - { - { - "gob3", - "", - { - {"intro.stk", 0, "edd7403e5dc2a14459d2665a4c17714d", 209534}, - {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - { - {"intro.stk", 0, "428e2de130cf3b303c938924539dc50d", 324420}, - {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "", - { - {"intro.stk", 0, "428e2de130cf3b303c938924539dc50d", 324420}, - {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { // Found in Found in french ADI 2.5 Anglais Multimedia 5e - { - "gob3", - "", - AD_ENTRY1s("intro.stk", "edd7403e5dc2a14459d2665a4c17714d", 209534), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3cd", - "v1.000", - AD_ENTRY1("intro.stk", "6f2c226c62dd7ab0ab6f850e89d3fc47"), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by pykman in bug report #3067489 - { - "gob3cd", - "v1.02 Polish", - AD_ENTRY1s("intro.stk", "978afddcac81bb95a04757b61f78471c", 619825), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 - { - "gob3cd", - "v1.02", - AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 - { - "gob3cd", - "v1.02", - AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 - { - "gob3cd", - "v1.02", - AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 - { - "gob3cd", - "v1.02", - AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 - { - "gob3cd", - "v1.02", - AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob3cd", - "v1.02", - AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), - HU_HUN, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob3cd", - "v1.02", - AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob3cd", - "v1.02", - AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2810082 - { - "gob3cd", - "v1.02", - AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "gob3", - "Interactive Demo", - AD_ENTRY1("intro.stk", "7aebd94e49c2c5c518c9e7b74f25de9d"), - FR_FRA, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "Interactive Demo 2", - AD_ENTRY1("intro.stk", "e5dcbc9f6658ebb1e8fe26bc4da0806d"), - FR_FRA, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "Interactive Demo 3", - AD_ENTRY1s("intro.stk", "9e20ad7b471b01f84db526da34eaf0a2", 395561), - EN_ANY, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "gob3", - "Non-interactive Demo", - AD_ENTRY1("intro.stk", "b9b898fccebe02b69c086052d5024a55"), - UNK_LANG, - kPlatformPC, - ADGF_DEMO, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesCD, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), - EN_USA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), - DE_DEU, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), - IT_ITA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), - ES_ESP, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "", - AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), - FR_FRA, - kPlatformWindows, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "inca2", - "Non-Interactive Demo", - { - {"cons.imd", 0, "f896ba0c4a1ac7f7260d342655980b49", 17804}, - {"conseil.imd", 0, "aaedd5482d5b271e233e86c5a03cf62e", 33999}, - {"int.imd", 0, "6308222fcefbcb20925f01c1aff70dee", 30871}, - {"inter.imd", 0, "39bd6d3540f3bedcc97293f352c7f3fc", 191719}, - {"machu.imd", 0, "c0bc8211d93b467bfd063b63fe61b85c", 34609}, - {"post.imd", 0, "d75cad0e3fc22cb0c8b6faf597f509b2", 1047709}, - {"posta.imd", 0, "2a5b3fe75681ddf4d21ac724db8111b4", 547250}, - {"postb.imd", 0, "24260ce4e80a4c472352b76637265d09", 868312}, - {"postc.imd", 0, "24accbcc8b83a9c2be4bd82849a2bd29", 415637}, - {"tum.imd", 0, "0993d4810ec9deb3f77c5e92095320fd", 20330}, - {"tumi.imd", 0, "bf53f229480d694de0947fe3366fbec6", 248952}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeInca2, - kFeaturesAdLib | kFeaturesBATDemo, - 0, 0, 7 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "5f5f4e0a72c33391e67a47674b120cc6", 20296422), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by jvprat on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by jvprat on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by jvprat on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by jvprat on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by jvprat on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by DjDiabolik in bug report #1971294 - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by DjDiabolik in bug report #1971294 - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by DjDiabolik in bug report #1971294 - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by DjDiabolik in bug report #1971294 - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by DjDiabolik in bug report #1971294 - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2098838 - { - "woodruff", - "", - AD_ENTRY1s("intro.stk", "08a96bf061af1fa4f75c6a7cc56b60a4", 20734979), - PL_POL, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "woodruff", - "Non-Interactive Demo", - { - {"demo.scn", 0, "16bb85fc5f8e519147b60475dbf33962", 89}, - {"wooddem3.vmd", 0, "a1700596172c2d4e264760030c3a3d47", 8994250}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 1 - }, - { - { - "dynasty", - "", - AD_ENTRY1s("intro.stk", "6190e32404b672f4bbbc39cf76f41fda", 2511470), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "dynasty", - "", - AD_ENTRY1s("intro.stk", "61e4069c16e27775a6cc6d20f529fb36", 2511300), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "dynasty", - "", - AD_ENTRY1s("intro.stk", "61e4069c16e27775a6cc6d20f529fb36", 2511300), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "dynasty", - "", - AD_ENTRY1s("intro.stk", "b3f8472484b7a1df94557b51e7b6fca0", 2322644), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "dynasty", - "", - AD_ENTRY1s("intro.stk", "bdbdac8919200a5e71ffb9fb0709f704", 2446652), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "dynasty", - "Demo", - AD_ENTRY1s("intro.stk", "464538a17ed39755d7f1ba9c751af1bd", 1847864), - EN_USA, - kPlatformPC, - ADGF_DEMO, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "dynasty", - "Demo", - AD_ENTRY1s("lda1.stk", "0e56a899357cbc0bf503260fd2dd634e", 15032774), - UNK_LANG, - kPlatformWindows, - ADGF_DEMO, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - "lda1.stk", 0, 0 - }, - { - { - "dynasty", - "Demo", - AD_ENTRY1s("lda1.stk", "8669ea2e9a8239c070dc73958fbc8753", 15567724), - DE_DEU, - kPlatformWindows, - ADGF_DEMO, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeDynasty, - kFeatures640x480, - "lda1.stk", 0, 0 - }, - { - { - "urban", - "", - AD_ENTRY1s("intro.stk", "3ab2c542bd9216ae5d02cc6f45701ae1", 1252436), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { // Supplied by Collector9 in bug report #3228040 - { - "urban", - "", - AD_ENTRY1s("intro.stk", "6ce3d878178932053267237ec4843ce1", 1252518), - EN_USA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { // Supplied by gamin in the forums - { - "urban", - "", - AD_ENTRY1s("intro.stk", "b991ed1d31c793e560edefdb349882ef", 1276408), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { // Supplied by jvprat on #scummvm - { - "urban", - "", - AD_ENTRY1s("intro.stk", "4ec3c0864e2b54c5b4ccf9f6ad96528d", 1253328), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { // Supplied by Alex on the gobsmacked blog - { - "urban", - "", - AD_ENTRY1s("intro.stk", "9ea647085a16dd0fb9ecd84cd8778ec9", 1253436), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { // Supplied by alex86r in bug report #3297602 - { - "urban", - "", - AD_ENTRY1s("intro.stk", "4e4a3c017fe5475353bf94c455fe3efd", 1253448), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { // Supplied by goodoldgeorg in bug report #2770340 - { - "urban", - "", - AD_ENTRY1s("intro.stk", "4bd31979ea3d77a58a358c09000a85ed", 1253018), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { - { - "urban", - "Non-Interactive Demo", - { - {"wdemo.s24", 0, "14ac9bd51db7a075d69ddb144904b271", 87}, - {"demo.vmd", 0, "65d04715d871c292518b56dd160b0161", 9091237}, - {"urband.vmd", 0, "60343891868c91854dd5c82766c70ecc", 922461}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor | kFeaturesSCNDemo, - 0, 0, 2 - }, - { - { - "playtoons1", - "", - { - {"playtoon.stk", 0, "8c98e9a11be9bb203a55e8c6e68e519b", 25574338}, - {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons1", - "Pack mes histoires anim\xE9""es", - { - {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, - {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons1", - "", - { - {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, - {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { // Supplied by scoriae in the forums - { - "playtoons1", - "", - { - {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, - {"archi.stk", 0, "00d8274519dfcf8a0d8ae3099daea0f8", 5532135}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons1", - "Non-Interactive Demo", - { - {"play123.scn", 0, "4689a31f543915e488c3bc46ea358add", 258}, - {"archi.vmd", 0, "a410fcc8116bc173f038100f5857191c", 5617210}, - {"chato.vmd", 0, "5a10e39cb66c396f2f9d8fb35e9ac016", 5445937}, - {"genedeb.vmd", 0, "3bb4a45585f88f4d839efdda6a1b582b", 1244228}, - {"generik.vmd", 0, "b46bdd64b063e86927fb2826500ad512", 603242}, - {"genespi.vmd", 0, "b7611916f32a370ae9832962fc17ef72", 758719}, - {"spirou.vmd", 0, "8513dbf7ac51c057b21d371d6b217b47", 2550788}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 3 - }, - { - { - "playtoons1", - "Non-Interactive Demo", - { - {"e.scn", 0, "8a0db733c3f77be86e74e8242e5caa61", 124}, - {"demarchg.vmd", 0, "d14a95da7d8792faf5503f649ffcbc12", 5619415}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 4 - }, - { - { - "playtoons1", - "Non-Interactive Demo", - { - {"i.scn", 0, "8b3294474d39970463663edd22341730", 285}, - {"demarita.vmd", 0, "84c8672b91c7312462603446e224bfec", 5742533}, - {"dembouit.vmd", 0, "7a5fdf0a4dbdfe72e31dd489ea0f8aa2", 3536786}, - {"demo5.vmd", 0, "2abb7b6a26406c984f389f0b24b5e28e", 13290970}, - {"demoita.vmd", 0, "b4c0622d14c8749965cd0f5dfca4cf4b", 1183566}, - {"wooddem3.vmd", 0, "a1700596172c2d4e264760030c3a3d47", 8994250}, - {0, 0, 0, 0} - }, - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 5 - }, - { - { - "playtoons1", - "Non-Interactive Demo", - { - {"s.scn", 0, "1f527010626b5490761f16ba7a6f639a", 251}, - {"demaresp.vmd", 0, "3f860f944056842b35a5fd05416f208e", 5720619}, - {"demboues.vmd", 0, "3a0caa10c98ef92a15942f8274075b43", 3535838}, - {"demo5.vmd", 0, "2abb7b6a26406c984f389f0b24b5e28e", 13290970}, - {"wooddem3.vmd", 0, "a1700596172c2d4e264760030c3a3d47", 8994250}, - {0, 0, 0, 0} - }, - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 6 - }, - { - { - "playtoons2", - "", - { - {"playtoon.stk", 0, "4772c96be88a57f0561519e4a1526c62", 24406262}, - {"spirou.stk", 0, "5d9c7644d0c47840169b4d016765cc1a", 9816201}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons2", - "", - { - {"playtoon.stk", 0, "55a85036dd93cce93532d8f743d90074", 17467154}, - {"spirou.stk", 0, "e3e1b6148dd72fafc3637f1a8e5764f5", 9812043}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons2", - "", - { - {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, - {"spirou.stk", 0, "91080dc148de1bbd6a97321c1a1facf3", 9817086}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { // Supplied by Hkz - { - "playtoons2", - "", - { - {"playtoon.stk", 0, "2572685400852d12759a2fbf09ec88eb", 9698780}, - {"spirou.stk", 0, "d3cfeff920b6343a2ece55088f530dba", 7076608}, - {0, 0, 0, 0} - }, - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { // Supplied by scoriae in the forums - { - "playtoons2", - "", - { - {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, - {"spirou.stk", 0, "993737f112ca6a9b33c814273280d832", 9825760}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons3", - "", - { - {"playtoon.stk", 0, "8c98e9a11be9bb203a55e8c6e68e519b", 25574338}, - {"chato.stk", 0, "4fa4ed96a427c344e9f916f9f236598d", 6033793}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons3", - "", - { - {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, - {"chato.stk", 0, "8fc8d0da5b3e758908d1d7298d497d0b", 6041026}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons3", - "Pack mes histoires anim\xE9""es", - { - {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, - {"chato.stk", 0, "4fa4ed96a427c344e9f916f9f236598d", 6033793}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons3", - "", - { - {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, - {"chato.stk", 0, "3c6cb3ac8a5a7cf681a19971a92a748d", 6033791}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { // Supplied by Hkz on #scummvm - { - "playtoons3", - "", - { - {"playtoon.stk", 0, "4772c96be88a57f0561519e4a1526c62", 24406262}, - {"chato.stk", 0, "bdef407387112bfcee90e664865ac3af", 6033867}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons4", - "", - { - {"playtoon.stk", 0, "b7f5afa2dc1b0f75970b7c07d175db1b", 24340406}, - {"manda.stk", 0, "92529e0b927191d9898a34c2892e9a3a", 6485072}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { //Supplied by goodoldgeorg in bug report #2820006 - { - "playtoons4", - "", - { - {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, - {"manda.stk", 0, "69a79c9f61b2618e482726f2ff68078d", 6499208}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtoons5", - "", - { - {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, - {"wakan.stk", 0, "f493bf82851bc5ba74d57de6b7e88df8", 5520153}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "bambou", - "", - { - {"intro.stk", 0, "2f8db6963ff8d72a8331627ebda918f4", 3613238}, - {"bambou.itk", 0, "0875914d31126d0749313428f10c7768", 114440192}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeBambou, - kFeatures640x480, - "intro.stk", "intro.tot", 0 - }, - { - { - "playtnck1", - "", - { - {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, - {"dan.itk", 0, "906d67b3e438d5e95ec7ea9e781a94f3", 3000320}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtnck2", - "", - { - {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, - {"dan.itk", 0, "74eeb075bd2cb47b243349730264af01", 3213312}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "playtnck3", - "", - { - {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, - {"dan.itk", 0, "9a8f62809eca5a52f429b5b6a8e70f8f", 2861056}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - "intro2.stk", 0, 0 - }, - { - { - "adi2", - "Adi 2.0 for Teachers", - AD_ENTRY1s("adi2.stk", "da6f1fb68bff32260c5eecdf9286a2f5", 1533168), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdi2, - kFeaturesNone, - "adi2.stk", "ediintro.tot", 0 - }, - { // Found in french ADI 2 Francais-Maths CM1. Exact version not specified. - { - "adi2", - "Adi 2", - AD_ENTRY1s("adi2.stk", "23f279615c736dc38320f1348e70c36e", 10817668), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { // Found in french ADI 2 Francais-Maths CE2. Exact version not specified. - { - "adi2", - "Adi 2", - AD_ENTRY1s("adi2.stk", "d4162c4298f9423ecc1fb04965557e90", 11531214), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2", - AD_ENTRY1s("adi2.stk", "29694c5a649298a42f87ae731d6d6f6d", 311132), - EN_ANY, - kPlatformAmiga, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdi2, - kFeaturesNone, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2", - AD_ENTRY1s("adi2.stk", "2a40bb48ccbd4e6fb3f7f0fc2f069d80", 17720132), - ES_ESP, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2.5", - AD_ENTRY1s("adi2.stk", "fcac60e6627f37aee219575b60859de9", 16944268), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2.5", - AD_ENTRY1s("adi2.stk", "072d5e2d7826a7c055865568ebf918bb", 16934596), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2.6", - AD_ENTRY1s("adi2.stk", "2fb940eb8105b12871f6b88c8c4d1615", 16780058), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2.6", - AD_ENTRY1s("adi2.stk", "fde7d98a67dbf859423b6473796e932a", 18044780), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Adi 2.7.1", - AD_ENTRY1s("adi2.stk", "6fa5dffebf5c7243c6af6b8c188ee00a", 19278008), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", "ediintro.tot", 0 - }, - { - { - "adi2", - "Non-Interactive Demo", - { - {"demo.scn", 0, "8b5ba359fd87d586ad39c1754bf6ea35", 168}, - {"demadi2t.vmd", 0, "08a1b18cfe2015d3b43270da35cc813d", 7250723}, - {"demarch.vmd", 0, "4c4a4616585d40ef3df209e3c3911062", 5622731}, - {"demobou.vmd", 0, "2208b9855775564d15c4a5a559da0aec", 3550511}, - {0, 0, 0, 0} - }, - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 1 - }, - { - { - "adi4", - "Addy 4 Grundschule Basis CD", - AD_ENTRY1s("intro.stk", "d2f0fb8909e396328dc85c0e29131ba8", 5847588), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Addy 4 Sekundarstufe Basis CD", - AD_ENTRY1s("intro.stk", "367340e59c461b4fa36651cd74e32c4e", 5847378), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Adi 4.0", - AD_ENTRY1s("intro.stk", "a3c35d19b2d28ea261d96321d208cb5a", 6021466), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Adi 4.0", - AD_ENTRY1s("intro.stk", "44491d85648810bc6fcf84f9b3aa47d5", 5834944), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Adi 4.0", - AD_ENTRY1s("intro.stk", "29374c0e3c10b17dd8463b06a55ad093", 6012072), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Adi 4.0 Limited Edition", - AD_ENTRY1s("intro.stk", "ebbbc5e28a4adb695535ed989c1b8d66", 5929644), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "ADI 4.10", - AD_ENTRY1s("intro.stk", "3e3fa9656e37d802027635ace88c4cc5", 5359144), - EN_GRB, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adi4", - "ADI 4.10", - AD_ENTRY1s("intro.stk", "6afc2590856433b9f5295b032f2b205d", 5923112), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adi4", - "ADI 4.11", - AD_ENTRY1s("intro.stk", "6296e4be4e0c270c24d1330881900c7f", 5921234), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adi4", - "Addy 4.21", - AD_ENTRY1s("intro.stk", "534f0b674cd4830df94a9c32c4ea7225", 6878034), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "ADI 4.21", - AD_ENTRY1s("intro.stk", "c5b9f6222c0b463f51dab47317c5b687", 5950490), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Adi 4.0 Interactive Demo", - AD_ENTRY1s("intro.stk", "89ace204dbaac001425c73f394334f6f", 2413102), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "adi4", - "Adi 4.0 / Adibou 2 Demo", - AD_ENTRY1s("intro.stk", "d41d8cd98f00b204e9800998ecf8427e", 0), - FR_FRA, - kPlatformPC, - ADGF_DEMO, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - 0, 0, 0 - }, - { - { - "ajworld", - "", - AD_ENTRY1s("intro.stk", "e453bea7b28a67c930764d945f64d898", 3913628), - EN_ANY, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeAJWorld, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "adibou1", - "ADIBOU 1 Environnement 4-7 ans", - AD_ENTRY1s("intro.stk", "6db110188fcb7c5208d9721b5282682a", 4805104), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeAdibou1, - kFeaturesAdLib, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU 2", - AD_ENTRY1s("intro.stk", "94ae7004348dc8bf99c23a9a6ef81827", 956162), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "Le Jardin Magique d'Adibou", - AD_ENTRY1s("intro.stk", "a8ff86f3cc40dfe5898e0a741217ef27", 956328), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU 2", - AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), - DE_DEU, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIB\xD9 2", - AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), - IT_ITA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU Version Decouverte", - AD_ENTRY1s("intro.stk", "558c14327b79ed39214b49d567a75e33", 8737856), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU 2.10 Environnement", - AD_ENTRY1s("intro.stk", "f2b797819aeedee557e904b0b5ccd82e", 8736454), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU 2.11 Environnement", - AD_ENTRY1s("intro.stk", "7b1f1f6f6477f54401e95d913f75e333", 8736904), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU 2.12 Environnement", - AD_ENTRY1s("intro.stk", "1e49c39a4a3ce6032a84b712539c2d63", 8738134), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOU 2.13s Environnement", - AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "ADIBOO 2.14 Environnement", - AD_ENTRY1s("intro.stk", "ff63637e3cb7f0a457edf79457b1c6b3", 9333874), - FR_FRA, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO0() - }, - kGameTypeAdibou2, - kFeaturesNone, - 0, 0, 0 - }, - { - { - "adibou2", - "Non-Interactive Demo", - { - {"demogb.scn", 0, "9291455a908ac0e6aaaca686e532609b", 105}, - {"demogb.vmd", 0, "bc9c1db97db7bec8f566332444fa0090", 14320840}, - {0, 0, 0, 0} - }, - EN_GRB, - kPlatformPC, - ADGF_DEMO, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeAdibou2, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 9 - }, - { - { - "adibou2", - "Non-Interactive Demo", - { - {"demoall.scn", 0, "c8fd308c037b829800006332b2c32674", 106}, - {"demoall.vmd", 0, "4672b2deacc6fca97484840424b1921b", 14263433}, - {0, 0, 0, 0} - }, - DE_DEU, - kPlatformPC, - ADGF_DEMO, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeAdibou2, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 10 - }, - { - { - "adibou2", - "Non-Interactive Demo", - { - {"demofra.scn", 0, "d1b2b1618af384ea1120def8b986c02b", 106}, - {"demofra.vmd", 0, "b494cdec1aac7e54c3f2480512d2880e", 14297100}, - {0, 0, 0, 0} - }, - FR_FRA, - kPlatformPC, - ADGF_DEMO, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeAdibou2, - kFeatures640x480 | kFeaturesSCNDemo, - 0, 0, 11 - }, - { AD_TABLE_END_MARKER, kGameTypeNone, kFeaturesNone, 0, 0, 0} -}; - -static const GOBGameDescription fallbackDescs[] = { - { //0 - { - "gob1", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesNone, - 0, 0, 0 - }, - { //1 - { - "gob1cd", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob1, - kFeaturesCD, - 0, 0, 0 - }, - { //2 - { - "gob2", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { //3 - { - "gob2mac", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesAdLib, - 0, 0, 0 - }, - { //4 - { - "gob2cd", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob2, - kFeaturesCD, - 0, 0, 0 - }, - { //5 - { - "bargon", - "", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeBargon, - kFeaturesNone, - 0, 0, 0 - }, - { //6 - { - "gob3", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesAdLib, - 0, 0, 0 - }, - { //7 - { - "gob3cd", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGob3, - kFeaturesCD, - 0, 0, 0 - }, - { //8 - { - "woodruff", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeWoodruff, - kFeatures640x480, - 0, 0, 0 - }, - { //9 - { - "lostintime", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { //10 - { - "lostintime", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformMacintosh, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesAdLib, - 0, 0, 0 - }, - { //11 - { - "lostintime", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeLostInTime, - kFeaturesCD, - 0, 0, 0 - }, - { //12 - { - "urban", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeatures640x480 | kFeaturesTrueColor, - 0, 0, 0 - }, - { //13 - { - "playtoons1", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - 0, 0, 0 - }, - { //14 - { - "playtoons2", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - 0, 0, 0 - }, - { //15 - { - "playtoons3", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - 0, 0, 0 - }, - { //16 - { - "playtoons4", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - 0, 0, 0 - }, - { //17 - { - "playtoons5", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - 0, 0, 0 - }, - { //18 - { - "playtoons construction kit", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypePlaytoons, - kFeatures640x480, - 0, 0, 0 - }, - { //19 - { - "bambou", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeBambou, - kFeatures640x480, - 0, 0, 0 - }, - { //20 - { - "fascination", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeFascination, - kFeaturesNone, - "disk0.stk", 0, 0 - }, - { //21 - { - "geisha", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) - }, - kGameTypeGeisha, - kFeaturesEGA, - "disk1.stk", "intro.tot", 0 - }, - { //22 - { - "adi2", - "", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeAdi2, - kFeatures640x480, - "adi2.stk", 0, 0 - }, - { //23 - { - "adi4", - "", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO3(GUIO_NOSUBTITLES, GUIO_NOSPEECH, GUIO_NOASPECT) - }, - kGameTypeAdi4, - kFeatures640x480, - "adif41.stk", 0, 0 - }, - { //24 - { - "coktelplayer", - "unknown", - AD_ENTRY1(0, 0), - UNK_LANG, - kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NOASPECT) - }, - kGameTypeUrban, - kFeaturesAdLib | kFeatures640x480 | kFeaturesSCNDemo, - "", "", 8 - } -}; - -static const ADFileBasedFallback fileBased[] = { - { &fallbackDescs[ 0].desc, { "intro.stk", "disk1.stk", "disk2.stk", "disk3.stk", "disk4.stk", 0 } }, - { &fallbackDescs[ 1].desc, { "intro.stk", "gob.lic", 0 } }, - { &fallbackDescs[ 2].desc, { "intro.stk", 0 } }, - { &fallbackDescs[ 2].desc, { "intro.stk", "disk2.stk", "disk3.stk", 0 } }, - { &fallbackDescs[ 3].desc, { "intro.stk", "disk2.stk", "disk3.stk", "musmac1.mid", 0 } }, - { &fallbackDescs[ 4].desc, { "intro.stk", "gobnew.lic", 0 } }, - { &fallbackDescs[ 5].desc, { "intro.stk", "scaa.imd", "scba.imd", "scbf.imd", 0 } }, - { &fallbackDescs[ 6].desc, { "intro.stk", "imd.itk", 0 } }, - { &fallbackDescs[ 7].desc, { "intro.stk", "mus_gob3.lic", 0 } }, - { &fallbackDescs[ 8].desc, { "intro.stk", "woodruff.itk", 0 } }, - { &fallbackDescs[ 9].desc, { "intro.stk", "commun1.itk", 0 } }, - { &fallbackDescs[10].desc, { "intro.stk", "commun1.itk", "musmac1.mid", 0 } }, - { &fallbackDescs[11].desc, { "intro.stk", "commun1.itk", "lost.lic", 0 } }, - { &fallbackDescs[12].desc, { "intro.stk", "cd1.itk", "objet1.itk", 0 } }, - { &fallbackDescs[13].desc, { "playtoon.stk", "archi.stk", 0 } }, - { &fallbackDescs[14].desc, { "playtoon.stk", "spirou.stk", 0 } }, - { &fallbackDescs[15].desc, { "playtoon.stk", "chato.stk", 0 } }, - { &fallbackDescs[16].desc, { "playtoon.stk", "manda.stk", 0 } }, - { &fallbackDescs[17].desc, { "playtoon.stk", "wakan.stk", 0 } }, - { &fallbackDescs[18].desc, { "playtoon.stk", "dan.itk" } }, - { &fallbackDescs[19].desc, { "intro.stk", "bambou.itk", 0 } }, - { &fallbackDescs[20].desc, { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, - { &fallbackDescs[21].desc, { "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, - { &fallbackDescs[22].desc, { "adi2.stk", 0 } }, - { &fallbackDescs[23].desc, { "adif41.stk", "adim41.stk", 0 } }, - { &fallbackDescs[24].desc, { "coktelplayer.scn", 0 } }, - { 0, { 0 } } -}; - -} diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 2249f44852..3395046b6c 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -11,7 +11,6 @@ MODULE_OBJS := \ databases.o \ dbase.o \ decfile.o \ - detection.o \ draw.o \ draw_v1.o \ draw_v2.o \ @@ -77,6 +76,7 @@ MODULE_OBJS := \ demos/demoplayer.o \ demos/scnplayer.o \ demos/batplayer.o \ + detection/detection.o \ minigames/geisha/evilfish.o \ minigames/geisha/oko.o \ minigames/geisha/meter.o \ -- cgit v1.2.3 From f76416f00f37d8f09ed2874231e7d396bdcf11bf Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 22 Jun 2012 17:52:23 +0200 Subject: GOB: Add fallback detection entries for Little Red --- engines/gob/detection/tables_fallback.h | 40 ++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/tables_fallback.h b/engines/gob/detection/tables_fallback.h index d8a5760080..e5a5828f2c 100644 --- a/engines/gob/detection/tables_fallback.h +++ b/engines/gob/detection/tables_fallback.h @@ -333,6 +333,34 @@ static const GOBGameDescription fallbackDescs[] = { "disk1.stk", "intro.tot", 0 }, { //22 + { + "littlered", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 + }, + { //23 + { + "littlered", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeLittleRed, + kFeaturesNone, + 0, 0, 0 + }, + { //24 { "adi2", "", @@ -346,7 +374,7 @@ static const GOBGameDescription fallbackDescs[] = { kFeatures640x480, "adi2.stk", 0, 0 }, - { //23 + { //25 { "adi4", "", @@ -360,7 +388,7 @@ static const GOBGameDescription fallbackDescs[] = { kFeatures640x480, "adif41.stk", 0, 0 }, - { //24 + { //26 { "coktelplayer", "unknown", @@ -400,9 +428,11 @@ static const ADFileBasedFallback fileBased[] = { { &fallbackDescs[19].desc, { "intro.stk", "bambou.itk", 0 } }, { &fallbackDescs[20].desc, { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, { &fallbackDescs[21].desc, { "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, - { &fallbackDescs[22].desc, { "adi2.stk", 0 } }, - { &fallbackDescs[23].desc, { "adif41.stk", "adim41.stk", 0 } }, - { &fallbackDescs[24].desc, { "coktelplayer.scn", 0 } }, + { &fallbackDescs[22].desc, { "intro.stk", "stk2.stk", "stk3.stk", 0 } }, + { &fallbackDescs[23].desc, { "intro.stk", "stk2.stk", "stk3.stk", "mod.babayaga", 0 } }, + { &fallbackDescs[24].desc, { "adi2.stk", 0 } }, + { &fallbackDescs[25].desc, { "adif41.stk", "adim41.stk", 0 } }, + { &fallbackDescs[26].desc, { "coktelplayer.scn", 0 } }, { 0, { 0 } } }; -- cgit v1.2.3 From 50d328af3a4115a9c81b25e0b4b241144a42c305 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 22 Jun 2012 17:54:20 +0200 Subject: GOB: Give Geisha and Fascination fallback entries AdLib feature flags --- engines/gob/detection/tables_fallback.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/tables_fallback.h b/engines/gob/detection/tables_fallback.h index e5a5828f2c..2853ee7b4f 100644 --- a/engines/gob/detection/tables_fallback.h +++ b/engines/gob/detection/tables_fallback.h @@ -315,7 +315,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, kGameTypeFascination, - kFeaturesNone, + kFeaturesAdLib, "disk0.stk", 0, 0 }, { //21 @@ -329,7 +329,7 @@ static const GOBGameDescription fallbackDescs[] = { GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) }, kGameTypeGeisha, - kFeaturesEGA, + kFeaturesEGA | kFeaturesAdLib, "disk1.stk", "intro.tot", 0 }, { //22 -- cgit v1.2.3 From 95d9052c8de83737e86b584510efe1961b86ff0a Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 23 Jun 2012 18:24:29 +0200 Subject: GOB: Fix a very stupid mistake in the Gob1 background track selection Thanks to salty-horse for catching that. :) --- engines/gob/sound/sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 184e14a2e6..403bd632a1 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -352,7 +352,7 @@ void Sound::adlibPlayBgMusic() { const char *track = 0; if (_vm->getPlatform() == Common::kPlatformWindows) - track = tracksWin[ARRAYSIZE(tracksWin)]; + track = tracksWin[_vm->_util->getRandom(ARRAYSIZE(tracksWin))]; else track = tracksMac[_vm->_util->getRandom(ARRAYSIZE(tracksMac))]; -- cgit v1.2.3 From 2c760cb15e27de29ef9262cb6e2a102d8dbe3935 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 27 Jun 2012 04:42:36 +0200 Subject: DETECTOR: Make detectGameFilebased() return a list of MD5s and file sizes Since we need a FSNode parent for Mac resource forks, we need to change signature of detectGameFilebased(), too. --- engines/gob/detection/detection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/detection.cpp b/engines/gob/detection/detection.cpp index bcfd5dacfa..9400001636 100644 --- a/engines/gob/detection/detection.cpp +++ b/engines/gob/detection/detection.cpp @@ -40,7 +40,7 @@ public: } virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { - return detectGameFilebased(allFiles, Gob::fileBased); + return detectGameFilebased(allFiles, fslist, Gob::fileBased); } virtual const char *getName() const { -- cgit v1.2.3 From 02375fa1e62aef578117e98c864d83939cac7229 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 27 Jun 2012 04:53:39 +0200 Subject: GOB: Report unknown game variant when using the file based fallback detector --- engines/gob/detection/detection.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/detection.cpp b/engines/gob/detection/detection.cpp index 9400001636..14da54637b 100644 --- a/engines/gob/detection/detection.cpp +++ b/engines/gob/detection/detection.cpp @@ -40,7 +40,14 @@ public: } virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { - return detectGameFilebased(allFiles, fslist, Gob::fileBased); + ADFilePropertiesMap filesProps; + + const ADGameDescription *game = detectGameFilebased(allFiles, fslist, Gob::fileBased, &filesProps); + if (!game) + return 0; + + reportUnknown(fslist.begin()->getParent(), filesProps); + return game; } virtual const char *getName() const { -- cgit v1.2.3 From 8884d7735c652de035f83889ef62ac4177a05996 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 4 Jul 2012 00:23:46 +0200 Subject: GOB: Give the Geisha detection entries proper languages --- engines/gob/detection/tables_geisha.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/tables_geisha.h b/engines/gob/detection/tables_geisha.h index 331e17e31d..83aa543668 100644 --- a/engines/gob/detection/tables_geisha.h +++ b/engines/gob/detection/tables_geisha.h @@ -32,7 +32,21 @@ "geisha", "", AD_ENTRY1s("disk1.stk", "6eebbb98ad90cd3c44549fc2ab30f632", 212153), - UNK_LANG, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA | kFeaturesAdLib, + "disk1.stk", "intro.tot", 0 +}, +{ + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "6eebbb98ad90cd3c44549fc2ab30f632", 212153), + DE_DEU, kPlatformPC, ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) @@ -63,7 +77,7 @@ "geisha", "", AD_ENTRY1s("disk1.stk", "e5892f00917c62423e93f5fd9920cf47", 208120), - UNK_LANG, + EN_ANY, kPlatformAmiga, ADGF_NO_FLAGS, GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) -- cgit v1.2.3 From 1657b173cc58cea02d99f27abff5e336c52c6d0f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 4 Jul 2012 00:26:37 +0200 Subject: GOB: Add a French DOS version of Geisha As supplied by misterhands in bug report #3539797. --- engines/gob/detection/tables_geisha.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/detection/tables_geisha.h b/engines/gob/detection/tables_geisha.h index 83aa543668..d05659d9e5 100644 --- a/engines/gob/detection/tables_geisha.h +++ b/engines/gob/detection/tables_geisha.h @@ -55,6 +55,20 @@ kFeaturesEGA | kFeaturesAdLib, "disk1.stk", "intro.tot", 0 }, +{ // Supplied by misterhands in bug report #3539797 + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "0c4c16090921664f50baefdfd24d7f5d", 211889), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA | kFeaturesAdLib, + "disk1.stk", "intro.tot", 0 +}, { { "geisha", -- cgit v1.2.3 From ff0ab5b5814fd790595d72786bdac2b61937abed Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 4 Jul 2012 00:37:28 +0200 Subject: GOB: Don't print a warning when oGeisha_checkData() doesn't find fin.tot Geisha looks if fin.tot exists to check if it needs to open disk3.stk. This is completely normal, so don't print a warning. --- engines/gob/inter_geisha.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter_geisha.cpp b/engines/gob/inter_geisha.cpp index 8a4d4246b6..8d05cefa66 100644 --- a/engines/gob/inter_geisha.cpp +++ b/engines/gob/inter_geisha.cpp @@ -200,8 +200,12 @@ void Inter_Geisha::oGeisha_checkData(OpFuncParams ¶ms) { if (mode == SaveLoad::kSaveModeNone) { exists = _vm->_dataIO->hasFile(file); - if (!exists) - warning("File \"%s\" not found", file.c_str()); + if (!exists) { + // NOTE: Geisha looks if fin.tot exists to check if it needs to open disk3.stk. + // This is completely normal, so don't print a warning. + if (file != "fin.tot") + warning("File \"%s\" not found", file.c_str()); + } } else if (mode == SaveLoad::kSaveModeSave) exists = _vm->_saveLoad->getSize(file.c_str()) >= 0; -- cgit v1.2.3 From dd35e72a7eefa922eba68dd28e8a18cbb98c0b16 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 27 Jun 2012 19:58:20 +0200 Subject: GOB: Return proper errors in GobEngine::run() --- engines/gob/gob.cpp | 29 +++++++++++++++-------------- engines/gob/gob.h | 6 +++--- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 3d8a18ed38..3202b5e23d 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -274,15 +274,15 @@ void GobEngine::setTrueColor(bool trueColor) { } Common::Error GobEngine::run() { - if (!initGameParts()) { - GUIErrorMessage("GobEngine::init(): Unknown version of game engine"); - return Common::kUnknownError; - } + Common::Error err; - if (!initGraphics()) { - GUIErrorMessage("GobEngine::init(): Failed to set up graphics"); - return Common::kUnknownError; - } + err = initGameParts(); + if (err.getCode() != Common::kNoError) + return err; + + err = initGraphics(); + if (err.getCode() != Common::kNoError) + return err; // On some systems it's not safe to run CD audio games from the CD. if (isCD()) @@ -392,7 +392,7 @@ void GobEngine::pauseGame() { pauseEngineIntern(false); } -bool GobEngine::initGameParts() { +Common::Error GobEngine::initGameParts() { _resourceSizeWorkaround = false; // just detect some devices some of which will be always there if the music is not disabled @@ -605,9 +605,10 @@ bool GobEngine::initGameParts() { _scenery = new Scenery_v2(this); _saveLoad = new SaveLoad_v2(this, _targetName.c_str()); break; + default: deinitGameParts(); - return false; + return Common::kUnsupportedGameidError; } // Setup mixer @@ -615,7 +616,7 @@ bool GobEngine::initGameParts() { _inter->setupOpcodes(); - return true; + return Common::kNoError; } void GobEngine::deinitGameParts() { @@ -637,10 +638,10 @@ void GobEngine::deinitGameParts() { delete _dataIO; _dataIO = 0; } -bool GobEngine::initGraphics() { +Common::Error GobEngine::initGraphics() { if (is800x600()) { warning("GobEngine::initGraphics(): 800x600 games currently unsupported"); - return false; + return Common::kUnsupportedGameidError; } else if (is640x480()) { _width = 640; _height = 480; @@ -664,7 +665,7 @@ bool GobEngine::initGraphics() { _global->_primarySurfDesc = SurfacePtr(new Surface(_width, _height, _pixelFormat.bytesPerPixel)); - return true; + return Common::kNoError; } } // End of namespace Gob diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 52f3ba8f2d..d3d2bf1576 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -176,10 +176,10 @@ private: virtual void pauseEngineIntern(bool pause); virtual void syncSoundSettings(); - bool initGameParts(); - void deinitGameParts(); + Common::Error initGameParts(); + Common::Error initGraphics(); - bool initGraphics(); + void deinitGameParts(); public: static const Common::Language _gobToScummVMLang[]; -- cgit v1.2.3 From 2d05974b5cfef94be9e3edad02e66169a215db4c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 19:09:56 +0200 Subject: GOB: const correctness in SoundBlaster::playComposition() --- engines/gob/inter_bargon.cpp | 4 ++-- engines/gob/sound/sound.cpp | 2 +- engines/gob/sound/sound.h | 2 +- engines/gob/sound/soundblaster.cpp | 2 +- engines/gob/sound/soundblaster.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index 134203fa9d..029f7c697b 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -119,7 +119,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { MouseButtons buttons; SurfacePtr surface; SoundDesc samples[4]; - int16 comp[5] = { 0, 1, 2, 3, -1 }; + static const int16 comp[5] = { 0, 1, 2, 3, -1 }; static const char *const sndFiles[] = {"1INTROII.snd", "2INTROII.snd", "1INTRO3.snd", "2INTRO3.snd"}; surface = _vm->_video->initSurfDesc(320, 200); @@ -167,8 +167,8 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { MouseButtons buttons; Video::Color *palBak; SoundDesc samples[2]; - int16 comp[3] = { 0, 1, -1 }; byte *palettes[4]; + static const int16 comp[3] = { 0, 1, -1 }; static const char *const sndFiles[] = {"1INTROIV.snd", "2INTROIV.snd"}; static const char *const palFiles[] = {"2ou2.clt", "2ou3.clt", "2ou4.clt", "2ou5.clt"}; diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 403bd632a1..69a668e5fb 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -458,7 +458,7 @@ void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) { _blaster->stopSound(fadeLength, sndDesc); } -void Sound::blasterPlayComposition(int16 *composition, int16 freqVal, +void Sound::blasterPlayComposition(const int16 *composition, int16 freqVal, SoundDesc *sndDescs, int8 sndCount) { if (!_blaster) return; diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index 6ad0ec5483..7beffb5dc7 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -60,7 +60,7 @@ public: int16 frequency, int16 fadeLength = 0); void blasterStop(int16 fadeLength, SoundDesc *sndDesc = 0); - void blasterPlayComposition(int16 *composition, int16 freqVal, + void blasterPlayComposition(const int16 *composition, int16 freqVal, SoundDesc *sndDescs = 0, int8 sndCount = kSoundsCount); void blasterStopComposition(); void blasterRepeatComposition(int32 repCount); diff --git a/engines/gob/sound/soundblaster.cpp b/engines/gob/sound/soundblaster.cpp index 19c2346448..f267eee32d 100644 --- a/engines/gob/sound/soundblaster.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -88,7 +88,7 @@ void SoundBlaster::nextCompositionPos() { _compositionPos = -1; } -void SoundBlaster::playComposition(int16 *composition, int16 freqVal, +void SoundBlaster::playComposition(const int16 *composition, int16 freqVal, SoundDesc *sndDescs, int8 sndCount) { _compositionSamples = sndDescs; diff --git a/engines/gob/sound/soundblaster.h b/engines/gob/sound/soundblaster.h index c740ba2269..3c4968d611 100644 --- a/engines/gob/sound/soundblaster.h +++ b/engines/gob/sound/soundblaster.h @@ -41,7 +41,7 @@ public: int16 frequency, int16 fadeLength = 0); void stopSound(int16 fadeLength, SoundDesc *sndDesc = 0); - void playComposition(int16 *composition, int16 freqVal, + void playComposition(const int16 *composition, int16 freqVal, SoundDesc *sndDescs = 0, int8 sndCount = 60); void stopComposition(); void endComposition(); -- cgit v1.2.3 From 945115f09927ff2e9e7d5197524bb929f4ba5561 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 27 Jun 2012 19:45:04 +0200 Subject: GOB: Don't crash when the engine wasn't fully initialized on exit --- engines/gob/game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 0d1953322f..de0c3f2d5c 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -64,7 +64,7 @@ void Environments::clear() { // Deleting unique variables, script and resources for (uint i = 0; i < kEnvironmentCount; i++) { - if (_environments[i].variables == _vm->_inter->_variables) + if (_vm->_inter && (_environments[i].variables == _vm->_inter->_variables)) continue; if (!has(_environments[i].variables, i + 1)) -- cgit v1.2.3 From 099a76ea20fa0f8290815f988d2202b6702d589b Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 01:30:29 +0200 Subject: GOB: Don't crash when there's no _inter object --- engines/gob/draw.cpp | 6 +++--- engines/gob/gob.cpp | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index fe59b11f76..9253a0a242 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -256,7 +256,7 @@ void Draw::blitInvalidated() { if (_cursorIndex == 4) blitCursor(); - if (_vm->_inter->_terminate) + if (_vm->_inter && _vm->_inter->_terminate) return; if (_noInvalidated && !_applyPal) @@ -446,7 +446,7 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); - uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter); + uint16 centerOffset = _vm->_game->_script ? _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter) : 0; if (centerOffset != 0) { _vm->_game->_script->call(centerOffset); @@ -505,7 +505,7 @@ void Draw::oPlaytoons_sub_F_1B(uint16 id, int16 left, int16 top, int16 right, in adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); - uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter); + uint16 centerOffset = _vm->_game->_script ? _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter) : 0; if (centerOffset != 0) { _vm->_game->_script->call(centerOffset); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 3202b5e23d..ef9a7112f9 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -368,11 +368,12 @@ void GobEngine::pauseEngineIntern(bool pause) { _game->_startTimeKey += duration; _draw->_cursorTimeKey += duration; - if (_inter->_soundEndTimeKey != 0) + if (_inter && (_inter->_soundEndTimeKey != 0)) _inter->_soundEndTimeKey += duration; } - _vidPlayer->pauseAll(pause); + if (_vidPlayer) + _vidPlayer->pauseAll(pause); _mixer->pauseAll(pause); } -- cgit v1.2.3 From 1cb6cc0218382bbf5fe487fd0e84d233e56592bb Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 01:31:59 +0200 Subject: GOB: Don't crash when drawPackedSprite() can't open the sprite --- engines/gob/video.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 3b1c6423bb..f1f014cce0 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -332,6 +332,10 @@ void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, void Video::drawPackedSprite(const char *path, Surface &dest, int width) { int32 size; byte *data = _vm->_dataIO->getFile(path, size); + if (!data) { + warning("Video::drawPackedSprite(): Failed to open sprite \"%s\"", path); + return; + } drawPackedSprite(data, width, dest.getHeight(), 0, 0, 0, dest); delete[] data; -- cgit v1.2.3 From b5fa752b78c63bedcb53d38fb11244b7e99f9941 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 17:37:58 +0200 Subject: GOB: Keep the mouse responsive while waiting for the frame to end --- engines/gob/minigames/geisha/penetration.cpp | 2 +- engines/gob/util.cpp | 20 ++++++++++++++------ engines/gob/util.h | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 3be9f1f651..05695e5dbb 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -505,7 +505,7 @@ bool Penetration::play(bool hasAccessPass, bool hasMaxEnergy, bool testMode) { // Draw, fade in if necessary and wait for the end of the frame _vm->_draw->blitInvalidated(); fadeIn(); - _vm->_util->waitEndFrame(); + _vm->_util->waitEndFrame(false); // Handle the input checkInput(); diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 64dfcf9b12..5d6ae78872 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -367,21 +367,29 @@ void Util::notifyNewAnim() { _startFrameTime = getTimeKey(); } -void Util::waitEndFrame() { +void Util::waitEndFrame(bool handleInput) { int32 time; - _vm->_video->waitRetrace(); - time = getTimeKey() - _startFrameTime; if ((time > 1000) || (time < 0)) { + _vm->_video->retrace(); _startFrameTime = getTimeKey(); return; } - int32 toWait = _frameWaitTime - time; + int32 toWait = 0; + do { + if (toWait > 0) + delay(MIN(toWait, 10)); + + if (handleInput) + processInput(); + + _vm->_video->retrace(); - if (toWait > 0) - delay(toWait); + time = getTimeKey() - _startFrameTime; + toWait = _frameWaitTime - time; + } while (toWait > 0); _startFrameTime = getTimeKey(); } diff --git a/engines/gob/util.h b/engines/gob/util.h index b26a78ab2c..30bff72325 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -124,7 +124,7 @@ public: int16 getFrameRate(); void setFrameRate(int16 rate); void notifyNewAnim(); - void waitEndFrame(); + void waitEndFrame(bool handleInput = true); void setScrollOffset(int16 x = -1, int16 y = -1); static void insertStr(const char *str1, char *str2, int16 pos); -- cgit v1.2.3 From 00fa997039525eeeacc34734e9a12e53f7b847dd Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 01:46:24 +0200 Subject: GOB: Move drawString into Font --- engines/gob/draw.cpp | 15 ---------- engines/gob/draw.h | 2 -- engines/gob/draw_fascin.cpp | 4 +-- engines/gob/draw_playtoons.cpp | 4 +-- engines/gob/draw_v2.cpp | 4 +-- engines/gob/inter_v5.cpp | 10 +++---- engines/gob/minigames/geisha/penetration.cpp | 45 +++++++++++----------------- engines/gob/video.cpp | 17 +++++++++++ engines/gob/video.h | 3 ++ 9 files changed, 49 insertions(+), 55 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 9253a0a242..3932987e0a 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -425,21 +425,6 @@ int Draw::stringLength(const char *str, uint16 fontIndex) { return len; } -void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, Surface &dest, const Font &font) { - - while (*str != '\0') { - const int16 charRight = x + font.getCharWidth(*str); - const int16 charBottom = y + font.getCharHeight(); - - if ((charRight <= dest.getWidth()) && (charBottom <= dest.getHeight())) - font.drawLetter(dest, *str, x, y, color1, color2, transp); - - x += font.getCharWidth(*str); - str++; - } -} - void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, const char *str, int16 fontIndex, int16 color) { diff --git a/engines/gob/draw.h b/engines/gob/draw.h index e7af1f9af3..b51c6466e0 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -194,8 +194,6 @@ public: adjustCoords(adjust, (int16 *)coord1, (int16 *)coord2); } int stringLength(const char *str, uint16 fontIndex); - void drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, Surface &dest, const Font &font); void printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, const char *str, int16 fontIndex, int16 color); void oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 var3, int16 var4, int16 shortId); diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 54cd52b660..12009d7ee5 100644 --- a/engines/gob/draw_fascin.cpp +++ b/engines/gob/draw_fascin.cpp @@ -222,8 +222,8 @@ void Draw_Fascination::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); } } else { - drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, - _backColor, _transparency, *_spritesArray[_destSurface], *font); + font->drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, + _backColor, _transparency, *_spritesArray[_destSurface]); _destSpriteX += len * font->getCharWidth(); } } else { diff --git a/engines/gob/draw_playtoons.cpp b/engines/gob/draw_playtoons.cpp index a443f81ccf..76e2ae591c 100644 --- a/engines/gob/draw_playtoons.cpp +++ b/engines/gob/draw_playtoons.cpp @@ -283,8 +283,8 @@ void Draw_Playtoons::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _frontColor, _backColor, _transparency); } } else { - drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, - _backColor, _transparency, *_spritesArray[_destSurface], *font); + font->drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, + _backColor, _transparency, *_spritesArray[_destSurface]); _destSpriteX += len * font->getCharWidth(); } } else { diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index b637ecbd2b..ac43c7b86a 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -831,8 +831,8 @@ void Draw_v2::spriteOperation(int16 operation) { getColor(_backColor), _transparency); } } else { - drawString(_textToPrint, _destSpriteX, _destSpriteY, getColor(_frontColor), - getColor(_backColor), _transparency, *_spritesArray[_destSurface], *font); + font->drawString(_textToPrint, _destSpriteX, _destSpriteY, getColor(_frontColor), + getColor(_backColor), _transparency, *_spritesArray[_destSurface]); _destSpriteX += len * font->getCharWidth(); } } else { diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp index c0e8978afd..24905b08d1 100644 --- a/engines/gob/inter_v5.cpp +++ b/engines/gob/inter_v5.cpp @@ -281,7 +281,7 @@ void Inter_v5::o5_getSystemCDSpeed(OpGobParams ¶ms) { Font *font; if ((font = _vm->_draw->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface, *font); + font->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface); _vm->_draw->forceBlit(); delete font; @@ -293,7 +293,7 @@ void Inter_v5::o5_getSystemRAM(OpGobParams ¶ms) { Font *font; if ((font = _vm->_draw->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface, *font); + font->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface); _vm->_draw->forceBlit(); delete font; @@ -305,7 +305,7 @@ void Inter_v5::o5_getSystemCPUSpeed(OpGobParams ¶ms) { Font *font; if ((font = _vm->_draw->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface, *font); + font->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface); _vm->_draw->forceBlit(); delete font; @@ -317,7 +317,7 @@ void Inter_v5::o5_getSystemDrawSpeed(OpGobParams ¶ms) { Font *font; if ((font = _vm->_draw->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface, *font); + font->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface); _vm->_draw->forceBlit(); delete font; @@ -329,7 +329,7 @@ void Inter_v5::o5_totalSystemSpecs(OpGobParams ¶ms) { Font *font; if ((font = _vm->_draw->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface, *font); + font->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface); _vm->_draw->forceBlit(); delete font; diff --git a/engines/gob/minigames/geisha/penetration.cpp b/engines/gob/minigames/geisha/penetration.cpp index 05695e5dbb..c8c4f2bba7 100644 --- a/engines/gob/minigames/geisha/penetration.cpp +++ b/engines/gob/minigames/geisha/penetration.cpp @@ -778,29 +778,24 @@ void Penetration::drawFloorText() { else if (_floor == 2) floorString = strings[kString1stBasement]; + Surface &surface = *_vm->_draw->_backSurface; + if (floorString) - _vm->_draw->drawString(floorString, 10, 15, kColorFloorText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); + font->drawString(floorString, 10, 15, kColorFloorText, kColorBlack, 1, surface); if (_exits.size() > 0) { int exitCount = kString2Exits; if (_exits.size() == 1) exitCount = kString1Exit; - _vm->_draw->drawString(strings[kStringYouHave] , 10, 38, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[exitCount] , 10, 53, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringToReach] , 10, 68, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringUpperLevel1], 10, 84, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringUpperLevel2], 10, 98, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); + font->drawString(strings[kStringYouHave] , 10, 38, kColorExitText, kColorBlack, 1, surface); + font->drawString(strings[exitCount] , 10, 53, kColorExitText, kColorBlack, 1, surface); + font->drawString(strings[kStringToReach] , 10, 68, kColorExitText, kColorBlack, 1, surface); + font->drawString(strings[kStringUpperLevel1], 10, 84, kColorExitText, kColorBlack, 1, surface); + font->drawString(strings[kStringUpperLevel2], 10, 98, kColorExitText, kColorBlack, 1, surface); } else - _vm->_draw->drawString(strings[kStringNoExit], 10, 53, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); + font->drawString(strings[kStringNoExit], 10, 53, kColorExitText, kColorBlack, 1, surface); } void Penetration::drawEndText() { @@ -814,21 +809,17 @@ void Penetration::drawEndText() { if (!font) return; + Surface &surface = *_vm->_draw->_backSurface; + const char **strings = kStrings[getLanguage()]; - _vm->_draw->drawString(strings[kStringLevel0] , 11, 21, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringPenetration], 11, 42, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringSuccessful] , 11, 58, kColorExitText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - - _vm->_draw->drawString(strings[kStringDanger] , 11, 82, kColorFloorText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringGynoides] , 11, 98, kColorFloorText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); - _vm->_draw->drawString(strings[kStringActivated], 11, 113, kColorFloorText, kColorBlack, 1, - *_vm->_draw->_backSurface, *font); + font->drawString(strings[kStringLevel0] , 11, 21, kColorExitText, kColorBlack, 1, surface); + font->drawString(strings[kStringPenetration], 11, 42, kColorExitText, kColorBlack, 1, surface); + font->drawString(strings[kStringSuccessful] , 11, 58, kColorExitText, kColorBlack, 1, surface); + + font->drawString(strings[kStringDanger] , 11, 82, kColorFloorText, kColorBlack, 1, surface); + font->drawString(strings[kStringGynoides] , 11, 98, kColorFloorText, kColorBlack, 1, surface); + font->drawString(strings[kStringActivated], 11, 113, kColorFloorText, kColorBlack, 1, surface); _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, kTextAreaLeft, kTextAreaTop, kTextAreaRight, kTextAreaBigBottom); _vm->_draw->blitInvalidated(); diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index f1f014cce0..8bcf14e040 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -134,6 +134,23 @@ void Font::drawLetter(Surface &surf, uint8 c, uint16 x, uint16 y, } } +void Font::drawString(const Common::String &str, int16 x, int16 y, int16 color1, int16 color2, + bool transp, Surface &dest) const { + + const char *s = str.c_str(); + + while (*s != '\0') { + const int16 charRight = x + getCharWidth(*s); + const int16 charBottom = y + getCharHeight(); + + if ((x >= 0) && (y >= 0) && (charRight <= dest.getWidth()) && (charBottom <= dest.getHeight())) + drawLetter(dest, *s, x, y, color1, color2, transp); + + x += getCharWidth(*s); + s++; + } +} + const byte *Font::getCharData(uint8 c) const { if (_endItem == 0) { warning("Font::getCharData(): _endItem == 0"); diff --git a/engines/gob/video.h b/engines/gob/video.h index ecbb579c5f..a8c1480a6b 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -46,6 +46,9 @@ public: void drawLetter(Surface &surf, uint8 c, uint16 x, uint16 y, uint32 color1, uint32 color2, bool transp) const; + void drawString(const Common::String &str, int16 x, int16 y, int16 color1, int16 color2, + bool transp, Surface &dest) const; + private: const byte *_dataPtr; const byte *_data; -- cgit v1.2.3 From bba2028fbaa1c2b3b2b89badd6bf8f36cbbe1cc1 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 27 Jun 2012 19:11:28 +0200 Subject: GOB: Move the method definitions out of the GobMetaEngine class definition --- engines/gob/detection/detection.cpp | 71 ++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 28 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/detection.cpp b/engines/gob/detection/detection.cpp index 14da54637b..8b4fab4409 100644 --- a/engines/gob/detection/detection.cpp +++ b/engines/gob/detection/detection.cpp @@ -30,43 +30,51 @@ class GobMetaEngine : public AdvancedMetaEngine { public: - GobMetaEngine() : AdvancedMetaEngine(Gob::gameDescriptions, sizeof(Gob::GOBGameDescription), gobGames) { - _singleid = "gob"; - _guioptions = GUIO1(GUIO_NOLAUNCHLOAD); - } - - virtual GameDescriptor findGame(const char *gameid) const { - return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable); - } + GobMetaEngine(); - virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { - ADFilePropertiesMap filesProps; + virtual GameDescriptor findGame(const char *gameid) const; - const ADGameDescription *game = detectGameFilebased(allFiles, fslist, Gob::fileBased, &filesProps); - if (!game) - return 0; + virtual const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const; - reportUnknown(fslist.begin()->getParent(), filesProps); - return game; - } - - virtual const char *getName() const { - return "Gob"; - } - - virtual const char *getOriginalCopyright() const { - return "Goblins Games (C) Coktel Vision"; - } + virtual const char *getName() const; + virtual const char *getOriginalCopyright() const; virtual bool hasFeature(MetaEngineFeature f) const; - virtual Common::Error createInstance(OSystem *syst, Engine **engine) const { - Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable); - return AdvancedMetaEngine::createInstance(syst, engine); - } + virtual Common::Error createInstance(OSystem *syst, Engine **engine) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; }; +GobMetaEngine::GobMetaEngine() : + AdvancedMetaEngine(Gob::gameDescriptions, sizeof(Gob::GOBGameDescription), gobGames) { + + _singleid = "gob"; + _guioptions = GUIO1(GUIO_NOLAUNCHLOAD); +} + +GameDescriptor GobMetaEngine::findGame(const char *gameid) const { + return Engines::findGameID(gameid, _gameids, obsoleteGameIDsTable); +} + +const ADGameDescription *GobMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { + ADFilePropertiesMap filesProps; + + const ADGameDescription *game = detectGameFilebased(allFiles, fslist, Gob::fileBased, &filesProps); + if (!game) + return 0; + + reportUnknown(fslist.begin()->getParent(), filesProps); + return game; +} + +const char *GobMetaEngine::getName() const { + return "Gob"; +} + +const char *GobMetaEngine::getOriginalCopyright() const { + return "Goblins Games (C) Coktel Vision"; +} + bool GobMetaEngine::hasFeature(MetaEngineFeature f) const { return false; } @@ -75,6 +83,12 @@ bool Gob::GobEngine::hasFeature(EngineFeature f) const { return (f == kSupportsRTL); } + +Common::Error GobMetaEngine::createInstance(OSystem *syst, Engine **engine) const { + Engines::upgradeTargetIfNecessary(obsoleteGameIDsTable); + return AdvancedMetaEngine::createInstance(syst, engine); +} + bool GobMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { const Gob::GOBGameDescription *gd = (const Gob::GOBGameDescription *)desc; if (gd) { @@ -84,6 +98,7 @@ bool GobMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD return gd != 0; } + #if PLUGIN_ENABLED_DYNAMIC(GOB) REGISTER_PLUGIN_DYNAMIC(GOB, PLUGIN_TYPE_ENGINE, GobMetaEngine); #else -- cgit v1.2.3 From 4a380ce668c45e5eaba1cdba9406d0c7fe7f3635 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 24 Jun 2012 21:36:58 +0200 Subject: GOB: Add detection tables for Baba Yaga and Abracadabra --- engines/gob/detection/tables.h | 4 + engines/gob/detection/tables_ajworld.h | 1 - engines/gob/detection/tables_fallback.h | 25 +- engines/gob/detection/tables_onceupon.h | 518 ++++++++++++++++++++++++++++++++ engines/gob/gob.h | 3 + 5 files changed, 545 insertions(+), 6 deletions(-) create mode 100644 engines/gob/detection/tables_onceupon.h (limited to 'engines/gob') diff --git a/engines/gob/detection/tables.h b/engines/gob/detection/tables.h index 5d211ac7d8..271f75af79 100644 --- a/engines/gob/detection/tables.h +++ b/engines/gob/detection/tables.h @@ -48,7 +48,10 @@ static const PlainGameDescriptor gobGames[] = { {"gob2cd", "Gobliins 2 CD"}, {"ween", "Ween: The Prophecy"}, {"bargon", "Bargon Attack"}, + {"babayaga", "Once Upon A Time: Baba Yaga"}, + {"abracadabra", "Once Upon A Time: Abracadabra"}, {"littlered", "Once Upon A Time: Little Red Riding Hood"}, + {"onceupon", "Once Upon A Time"}, {"ajworld", "A.J.'s World of Discovery"}, {"gob3", "Goblins Quest 3"}, {"gob3cd", "Goblins Quest 3 CD"}, @@ -94,6 +97,7 @@ static const GOBGameDescription gameDescriptions[] = { #include "gob/detection/tables_ween.h" // Ween: The Prophecy #include "gob/detection/tables_bargon.h" // Bargon Attack #include "gob/detection/tables_littlered.h" // Once Upon A Time: Little Red Riding Hood + #include "gob/detection/tables_onceupon.h" // Once Upon A Time: Baba Yaga and Abracadabra #include "gob/detection/tables_lit.h" // Lost in Time #include "gob/detection/tables_fascin.h" // Fascination #include "gob/detection/tables_geisha.h" // Geisha diff --git a/engines/gob/detection/tables_ajworld.h b/engines/gob/detection/tables_ajworld.h index c78d11a6ad..d86bdb16be 100644 --- a/engines/gob/detection/tables_ajworld.h +++ b/engines/gob/detection/tables_ajworld.h @@ -1,4 +1,3 @@ - /* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names diff --git a/engines/gob/detection/tables_fallback.h b/engines/gob/detection/tables_fallback.h index 2853ee7b4f..0e0aa92ae1 100644 --- a/engines/gob/detection/tables_fallback.h +++ b/engines/gob/detection/tables_fallback.h @@ -361,6 +361,20 @@ static const GOBGameDescription fallbackDescs[] = { 0, 0, 0 }, { //24 + { + "onceupon", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformUnknown, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeOnceUponATime, + kFeaturesEGA, + 0, 0, 0 + }, + { //25 { "adi2", "", @@ -374,7 +388,7 @@ static const GOBGameDescription fallbackDescs[] = { kFeatures640x480, "adi2.stk", 0, 0 }, - { //25 + { //26 { "adi4", "", @@ -388,7 +402,7 @@ static const GOBGameDescription fallbackDescs[] = { kFeatures640x480, "adif41.stk", 0, 0 }, - { //26 + { //27 { "coktelplayer", "unknown", @@ -430,9 +444,10 @@ static const ADFileBasedFallback fileBased[] = { { &fallbackDescs[21].desc, { "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, { &fallbackDescs[22].desc, { "intro.stk", "stk2.stk", "stk3.stk", 0 } }, { &fallbackDescs[23].desc, { "intro.stk", "stk2.stk", "stk3.stk", "mod.babayaga", 0 } }, - { &fallbackDescs[24].desc, { "adi2.stk", 0 } }, - { &fallbackDescs[25].desc, { "adif41.stk", "adim41.stk", 0 } }, - { &fallbackDescs[26].desc, { "coktelplayer.scn", 0 } }, + { &fallbackDescs[24].desc, { "stk1.stk", "stk2.stk", "stk3.stk", 0 } }, + { &fallbackDescs[25].desc, { "adi2.stk", 0 } }, + { &fallbackDescs[26].desc, { "adif41.stk", "adim41.stk", 0 } }, + { &fallbackDescs[27].desc, { "coktelplayer.scn", 0 } }, { 0, { 0 } } }; diff --git a/engines/gob/detection/tables_onceupon.h b/engines/gob/detection/tables_onceupon.h new file mode 100644 index 0000000000..366024d43c --- /dev/null +++ b/engines/gob/detection/tables_onceupon.h @@ -0,0 +1,518 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Detection tables for Once Upon A Time: Baba Yaga and Abracadabra. */ + +#ifndef GOB_DETECTION_TABLES_ONCEUPON_H +#define GOB_DETECTION_TABLES_ONCEUPON_H + +// -- Once Upon A Time: Abracadabra, Amiga -- + +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "e4b21818af03930dc9cab2ad4c93cb5b", 362106}, + {"stk3.stk", 0, "76874ad92782f9b2de57beafc05ec877", 353482}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "e4b21818af03930dc9cab2ad4c93cb5b", 362106}, + {"stk3.stk", 0, "76874ad92782f9b2de57beafc05ec877", 353482}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "e4b21818af03930dc9cab2ad4c93cb5b", 362106}, + {"stk3.stk", 0, "76874ad92782f9b2de57beafc05ec877", 353482}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "e4b21818af03930dc9cab2ad4c93cb5b", 362106}, + {"stk3.stk", 0, "76874ad92782f9b2de57beafc05ec877", 353482}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "e4b21818af03930dc9cab2ad4c93cb5b", 362106}, + {"stk3.stk", 0, "76874ad92782f9b2de57beafc05ec877", 353482}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, + +// -- Once Upon A Time: Abracadabra, Atari ST -- + +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "c6440aaf068ec3149ae89bc5c41ebf02", 362123}, + {"stk3.stk", 0, "5af3c1202ba6fcf8dad2b2125e1c1383", 353257}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "c6440aaf068ec3149ae89bc5c41ebf02", 362123}, + {"stk3.stk", 0, "5af3c1202ba6fcf8dad2b2125e1c1383", 353257}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "c6440aaf068ec3149ae89bc5c41ebf02", 362123}, + {"stk3.stk", 0, "5af3c1202ba6fcf8dad2b2125e1c1383", 353257}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "c6440aaf068ec3149ae89bc5c41ebf02", 362123}, + {"stk3.stk", 0, "5af3c1202ba6fcf8dad2b2125e1c1383", 353257}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "abracadabra", + "", + { + {"stk1.stk", 0, "a8e963eea170155548e5bc1d0f07d50d", 209806}, + {"stk2.stk", 0, "c6440aaf068ec3149ae89bc5c41ebf02", 362123}, + {"stk3.stk", 0, "5af3c1202ba6fcf8dad2b2125e1c1383", 353257}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 +}, + +// -- Once Upon A Time: Baba Yaga, DOS EGA Floppy -- + +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "3c777f43e6fb49fde9222543447e135a", 204813}, + {"stk2.stk", 0, "6cf0b009dd185a8f589e91a1f9c33df5", 361582}, + {"stk3.stk", 0, "6473183ca4db1b5b5cea047f9af59a26", 328925}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "3c777f43e6fb49fde9222543447e135a", 204813}, + {"stk2.stk", 0, "6cf0b009dd185a8f589e91a1f9c33df5", 361582}, + {"stk3.stk", 0, "6473183ca4db1b5b5cea047f9af59a26", 328925}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "3c777f43e6fb49fde9222543447e135a", 204813}, + {"stk2.stk", 0, "6cf0b009dd185a8f589e91a1f9c33df5", 361582}, + {"stk3.stk", 0, "6473183ca4db1b5b5cea047f9af59a26", 328925}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "3c777f43e6fb49fde9222543447e135a", 204813}, + {"stk2.stk", 0, "6cf0b009dd185a8f589e91a1f9c33df5", 361582}, + {"stk3.stk", 0, "6473183ca4db1b5b5cea047f9af59a26", 328925}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "3c777f43e6fb49fde9222543447e135a", 204813}, + {"stk2.stk", 0, "6cf0b009dd185a8f589e91a1f9c33df5", 361582}, + {"stk3.stk", 0, "6473183ca4db1b5b5cea047f9af59a26", 328925}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 +}, + +// -- Once Upon A Time: Baba Yaga, Amiga -- + +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "bcc823d2888057031e54716ed1b3c80e", 205090}, + {"stk2.stk", 0, "f76bf7c2ff60d816d69962d1a593207c", 362122}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "bcc823d2888057031e54716ed1b3c80e", 205090}, + {"stk2.stk", 0, "f76bf7c2ff60d816d69962d1a593207c", 362122}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "bcc823d2888057031e54716ed1b3c80e", 205090}, + {"stk2.stk", 0, "f76bf7c2ff60d816d69962d1a593207c", 362122}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "bcc823d2888057031e54716ed1b3c80e", 205090}, + {"stk2.stk", 0, "f76bf7c2ff60d816d69962d1a593207c", 362122}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "bcc823d2888057031e54716ed1b3c80e", 205090}, + {"stk2.stk", 0, "f76bf7c2ff60d816d69962d1a593207c", 362122}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, + +// -- Once Upon A Time: Baba Yaga, Atari ST -- + +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "17a4e3e7a18cc97231c92d280c7878a1", 205095}, + {"stk2.stk", 0, "bfbc380e5461f63af28e9e6b10f334b5", 362128}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "17a4e3e7a18cc97231c92d280c7878a1", 205095}, + {"stk2.stk", 0, "bfbc380e5461f63af28e9e6b10f334b5", 362128}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "17a4e3e7a18cc97231c92d280c7878a1", 205095}, + {"stk2.stk", 0, "bfbc380e5461f63af28e9e6b10f334b5", 362128}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "17a4e3e7a18cc97231c92d280c7878a1", 205095}, + {"stk2.stk", 0, "bfbc380e5461f63af28e9e6b10f334b5", 362128}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, +{ + { + "babayaga", + "", + { + {"stk1.stk", 0, "17a4e3e7a18cc97231c92d280c7878a1", 205095}, + {"stk2.stk", 0, "bfbc380e5461f63af28e9e6b10f334b5", 362128}, + {"stk3.stk", 0, "6227d1aefdf39d88dcf83e38bea2a9af", 328922}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 +}, + +#endif // GOB_DETECTION_TABLES_ONCEUPON_H diff --git a/engines/gob/gob.h b/engines/gob/gob.h index d3d2bf1576..5d4c3d7c55 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -129,7 +129,10 @@ enum GameType { kGameTypeAdi4, kGameTypeAdibou2, kGameTypeAdibou1, + kGameTypeAbracadabra, + kGameTypeBabaYaga, kGameTypeLittleRed, + kGameTypeOnceUponATime, // Need more inspection to see if Baba Yaga or Abracadabra kGameTypeAJWorld }; -- cgit v1.2.3 From 55c75756ea3c38cdd7074caff7085e35a658c9e7 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Wed, 27 Jun 2012 20:48:39 +0200 Subject: GOB: Add a more complex detection for Once Upon A Time titles The hard-coded Once Upon A Time titles, Abracadabra and Baba Yaga, are impossible to distinguish by file name alone. The same is true for the each three platforms, DOS, Amiga and Atari ST. We do need to know exactly which game and platform a specific path holds, though, because they're a) completely hard-coded b) the data files have platform-specific endianness Therefore, when the filename-based fallback detector finds one of those games, we open the archives and look inside them. We detect the specific game by looking at which animal names are present; and the platform by inspecting the endianness of the title screen's DEC file, in addition to the existence of a MOD file to distinguish the Atari ST from the Amiga version. --- engines/gob/detection/detection.cpp | 95 ++++++++++++++++++++++++++- engines/gob/detection/tables_fallback.h | 110 ++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/detection/detection.cpp b/engines/gob/detection/detection.cpp index 8b4fab4409..8fb0052a5b 100644 --- a/engines/gob/detection/detection.cpp +++ b/engines/gob/detection/detection.cpp @@ -25,6 +25,7 @@ #include "engines/obsolete.h" #include "gob/gob.h" +#include "gob/dataio.h" #include "gob/detection/tables.h" @@ -43,6 +44,12 @@ public: virtual Common::Error createInstance(OSystem *syst, Engine **engine) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + +private: + /** + * Inspect the game archives to detect which Once Upon A Time game this is. + */ + static const Gob::GOBGameDescription *detectOnceUponATime(const Common::FSList &fslist); }; GobMetaEngine::GobMetaEngine() : @@ -59,12 +66,96 @@ GameDescriptor GobMetaEngine::findGame(const char *gameid) const { const ADGameDescription *GobMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { ADFilePropertiesMap filesProps; - const ADGameDescription *game = detectGameFilebased(allFiles, fslist, Gob::fileBased, &filesProps); + const Gob::GOBGameDescription *game; + game = (const Gob::GOBGameDescription *)detectGameFilebased(allFiles, fslist, Gob::fileBased, &filesProps); if (!game) return 0; + if (game->gameType == Gob::kGameTypeOnceUponATime) { + game = detectOnceUponATime(fslist); + if (!game) + return 0; + } + reportUnknown(fslist.begin()->getParent(), filesProps); - return game; + return (const ADGameDescription *)game; +} + +const Gob::GOBGameDescription *GobMetaEngine::detectOnceUponATime(const Common::FSList &fslist) { + // Add the game path to the search manager + SearchMan.clear(); + SearchMan.addDirectory(fslist.begin()->getParent().getPath(), fslist.begin()->getParent()); + + // Open the archives + Gob::DataIO dataIO; + if (!dataIO.openArchive("stk1.stk", true) || + !dataIO.openArchive("stk2.stk", true) || + !dataIO.openArchive("stk3.stk", true)) { + + SearchMan.clear(); + return 0; + } + + Gob::OnceUponATime gameType = Gob::kOnceUponATimeInvalid; + Gob::OnceUponATimePlatform platform = Gob::kOnceUponATimePlatformInvalid; + + // If these animal files are present, it's Abracadabra + if (dataIO.hasFile("arai.anm") && + dataIO.hasFile("crab.anm") && + dataIO.hasFile("crap.anm") && + dataIO.hasFile("drag.anm") && + dataIO.hasFile("guep.anm") && + dataIO.hasFile("loup.anm") && + dataIO.hasFile("mous.anm") && + dataIO.hasFile("rhin.anm") && + dataIO.hasFile("saut.anm") && + dataIO.hasFile("scor.anm")) + gameType = Gob::kOnceUponATimeAbracadabra; + + // If these animal files are present, it's Baba Yaga + if (dataIO.hasFile("abei.anm") && + dataIO.hasFile("arai.anm") && + dataIO.hasFile("drag.anm") && + dataIO.hasFile("fauc.anm") && + dataIO.hasFile("gren.anm") && + dataIO.hasFile("rena.anm") && + dataIO.hasFile("sang.anm") && + dataIO.hasFile("serp.anm") && + dataIO.hasFile("tort.anm") && + dataIO.hasFile("vaut.anm")) + gameType = Gob::kOnceUponATimeBabaYaga; + + // Detect the platform by endianness and existence of a MOD file + Common::SeekableReadStream *villeDEC = dataIO.getFile("ville.dec"); + if (villeDEC && (villeDEC->size() > 6)) { + byte data[6]; + + if (villeDEC->read(data, 6) == 6) { + if (!memcmp(data, "\000\000\000\001\000\007", 6)) { + // Big endian -> Amiga or Atari ST + + if (dataIO.hasFile("mod.babayaga")) + platform = Gob::kOnceUponATimePlatformAmiga; + else + platform = Gob::kOnceUponATimePlatformAtariST; + + } else if (!memcmp(data, "\000\000\001\000\007\000", 6)) + // Little endian -> DOS + platform = Gob::kOnceUponATimePlatformDOS; + } + + delete villeDEC; + } + + SearchMan.clear(); + + if ((gameType == Gob::kOnceUponATimeInvalid) || (platform == Gob::kOnceUponATimePlatformInvalid)) { + warning("GobMetaEngine::detectOnceUponATime(): Detection failed (%d, %d)", + (int) gameType, (int) platform); + return 0; + } + + return &Gob::fallbackOnceUpon[gameType][platform]; } const char *GobMetaEngine::getName() const { diff --git a/engines/gob/detection/tables_fallback.h b/engines/gob/detection/tables_fallback.h index 0e0aa92ae1..05f579c08c 100644 --- a/engines/gob/detection/tables_fallback.h +++ b/engines/gob/detection/tables_fallback.h @@ -23,6 +23,8 @@ #ifndef GOB_DETECTION_TABLES_FALLBACK_H #define GOB_DETECTION_TABLES_FALLBACK_H +// -- Tables for the filename-based fallback -- + static const GOBGameDescription fallbackDescs[] = { { //0 { @@ -451,4 +453,112 @@ static const ADFileBasedFallback fileBased[] = { { 0, { 0 } } }; +// -- Tables for detecting the specific Once Upon A Time game -- + +enum OnceUponATime { + kOnceUponATimeInvalid = -1, + kOnceUponATimeAbracadabra = 0, + kOnceUponATimeBabaYaga = 1, + kOnceUponATimeMAX +}; + +enum OnceUponATimePlatform { + kOnceUponATimePlatformInvalid = -1, + kOnceUponATimePlatformDOS = 0, + kOnceUponATimePlatformAmiga = 1, + kOnceUponATimePlatformAtariST = 2, + kOnceUponATimePlatformMAX +}; + +static const GOBGameDescription fallbackOnceUpon[kOnceUponATimeMAX][kOnceUponATimePlatformMAX] = { + { // kOnceUponATimeAbracadabra + { // kOnceUponATimePlatformDOS + { + "abracadabra", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 + }, + { // kOnceUponATimePlatformAmiga + { + "abracadabra", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 + }, + { // kOnceUponATimePlatformAtariST + { + "abracadabra", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeAbracadabra, + kFeaturesEGA, + 0, 0, 0 + } + }, + { // kOnceUponATimeBabaYaga + { // kOnceUponATimePlatformDOS + { + "babayaga", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesAdLib | kFeaturesEGA, + 0, 0, 0 + }, + { // kOnceUponATimePlatformAmiga + { + "babayaga", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformAmiga, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 + }, + { // kOnceUponATimePlatformAtariST + { + "babayaga", + "", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformAtariST, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeBabaYaga, + kFeaturesEGA, + 0, 0, 0 + } + } +}; + #endif // GOB_DETECTION_TABLES_FALLBACK_H -- cgit v1.2.3 From 4819468d9ad8218d04a2e4563ef71d7d00964515 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 00:07:29 +0200 Subject: GOB: Add PreGob stubs for the Once Upon A Time games --- engines/gob/gob.cpp | 33 ++++++++++++++++++++-- engines/gob/gob.h | 2 ++ engines/gob/init.cpp | 14 ++++++++- engines/gob/module.mk | 4 +++ engines/gob/pregob/onceupon/abracadabra.cpp | 43 ++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/abracadabra.h | 44 +++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/babayaga.cpp | 43 ++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/babayaga.h | 44 +++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.cpp | 37 ++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 42 +++++++++++++++++++++++++++ engines/gob/pregob/pregob.cpp | 35 +++++++++++++++++++++++ engines/gob/pregob/pregob.h | 43 ++++++++++++++++++++++++++++ 12 files changed, 380 insertions(+), 4 deletions(-) create mode 100644 engines/gob/pregob/onceupon/abracadabra.cpp create mode 100644 engines/gob/pregob/onceupon/abracadabra.h create mode 100644 engines/gob/pregob/onceupon/babayaga.cpp create mode 100644 engines/gob/pregob/onceupon/babayaga.h create mode 100644 engines/gob/pregob/onceupon/onceupon.cpp create mode 100644 engines/gob/pregob/onceupon/onceupon.h create mode 100644 engines/gob/pregob/pregob.cpp create mode 100644 engines/gob/pregob/pregob.h (limited to 'engines/gob') diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index ef9a7112f9..02aea63377 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -48,6 +48,10 @@ #include "gob/videoplayer.h" #include "gob/save/saveload.h" +#include "gob/pregob/pregob.h" +#include "gob/pregob/onceupon/abracadabra.h" +#include "gob/pregob/onceupon/babayaga.h" + namespace Gob { #define MAX_TIME_DELTA 100 @@ -115,7 +119,7 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst), _rnd("gob") { _vidPlayer = 0; _init = 0; _inter = 0; _map = 0; _palAnim = 0; _scenery = 0; _draw = 0; _util = 0; _video = 0; - _saveLoad = 0; + _saveLoad = 0; _preGob = 0; _pauseStart = 0; @@ -398,7 +402,6 @@ Common::Error GobEngine::initGameParts() { // just detect some devices some of which will be always there if the music is not disabled _noMusic = MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB)) == MT_NULL ? true : false; - _saveLoad = 0; _global = new Global(this); _util = new Util(this); @@ -607,6 +610,28 @@ Common::Error GobEngine::initGameParts() { _saveLoad = new SaveLoad_v2(this, _targetName.c_str()); break; + case kGameTypeAbracadabra: + _init = new Init_v2(this); + _video = new Video_v2(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); + _preGob = new OnceUpon::Abracadabra(this); + break; + + case kGameTypeBabaYaga: + _init = new Init_v2(this); + _video = new Video_v2(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); + _preGob = new OnceUpon::BabaYaga(this); + break; + default: deinitGameParts(); return Common::kUnsupportedGameidError; @@ -615,12 +640,14 @@ Common::Error GobEngine::initGameParts() { // Setup mixer syncSoundSettings(); - _inter->setupOpcodes(); + if (_inter) + _inter->setupOpcodes(); return Common::kNoError; } void GobEngine::deinitGameParts() { + delete _preGob; _preGob = 0; delete _saveLoad; _saveLoad = 0; delete _mult; _mult = 0; delete _vidPlayer; _vidPlayer = 0; diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 5d4c3d7c55..9b919098d6 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -75,6 +75,7 @@ class Scenery; class Util; class SaveLoad; class GobConsole; +class PreGob; #define WRITE_VAR_UINT32(var, val) _vm->_inter->_variables->writeVar32(var, val) #define WRITE_VAR_UINT16(var, val) _vm->_inter->_variables->writeVar16(var, val) @@ -223,6 +224,7 @@ public: Inter *_inter; SaveLoad *_saveLoad; VideoPlayer *_vidPlayer; + PreGob *_preGob; const char *getLangDesc(int16 language) const; void validateLanguage(); diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index a61261f355..814d4d1821 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -34,9 +34,13 @@ #include "gob/inter.h" #include "gob/video.h" #include "gob/videoplayer.h" + +#include "gob/sound/sound.h" + #include "gob/demos/scnplayer.h" #include "gob/demos/batplayer.h" -#include "gob/sound/sound.h" + +#include "gob/pregob/pregob.h" namespace Gob { @@ -118,6 +122,14 @@ void Init::initGame() { return; } + if (_vm->_preGob) { + _vm->_preGob->run(); + delete _palDesc; + _vm->_video->initPrimary(-1); + cleanup(); + return; + } + Common::SeekableReadStream *infFile = _vm->_dataIO->getFile("intro.inf"); if (!infFile) { diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 3395046b6c..8a792049e8 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -77,6 +77,10 @@ MODULE_OBJS := \ demos/scnplayer.o \ demos/batplayer.o \ detection/detection.o \ + pregob/pregob.o \ + pregob/onceupon/onceupon.o \ + pregob/onceupon/abracadabra.o \ + pregob/onceupon/babayaga.o \ minigames/geisha/evilfish.o \ minigames/geisha/oko.o \ minigames/geisha/meter.o \ diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp new file mode 100644 index 0000000000..14a362ce12 --- /dev/null +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -0,0 +1,43 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/textconsole.h" + +#include "gob/pregob/onceupon/abracadabra.h" + +namespace Gob { + +namespace OnceUpon { + +Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) { +} + +Abracadabra::~Abracadabra() { +} + +void Abracadabra::run() { + warning("TODO: Abracadabra::run()"); +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h new file mode 100644 index 0000000000..855d2bf131 --- /dev/null +++ b/engines/gob/pregob/onceupon/abracadabra.h @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_ABRACADABRA_H +#define GOB_PREGOB_ONCEUPON_ABRACADABRA_H + +#include "gob/pregob/onceupon/onceupon.h" + +namespace Gob { + +namespace OnceUpon { + +class Abracadabra : public OnceUpon { +public: + Abracadabra(GobEngine *vm); + ~Abracadabra(); + + void run(); +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_ABRACADABRA_H diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp new file mode 100644 index 0000000000..f2c7569460 --- /dev/null +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -0,0 +1,43 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/textconsole.h" + +#include "gob/pregob/onceupon/babayaga.h" + +namespace Gob { + +namespace OnceUpon { + +BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) { +} + +BabaYaga::~BabaYaga() { +} + +void BabaYaga::run() { + warning("TODO: BabaYaga::run()"); +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h new file mode 100644 index 0000000000..b3339b0ca8 --- /dev/null +++ b/engines/gob/pregob/onceupon/babayaga.h @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_BABAYAGA_H +#define GOB_PREGOB_ONCEUPON_BABAYAGA_H + +#include "gob/pregob/onceupon/onceupon.h" + +namespace Gob { + +namespace OnceUpon { + +class BabaYaga : public OnceUpon { +public: + BabaYaga(GobEngine *vm); + ~BabaYaga(); + + void run(); +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_BABAYAGA_H diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp new file mode 100644 index 0000000000..639f5b1ee8 --- /dev/null +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -0,0 +1,37 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/pregob/onceupon/onceupon.h" + +namespace Gob { + +namespace OnceUpon { + +OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm) { +} + +OnceUpon::~OnceUpon() { +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h new file mode 100644 index 0000000000..f937701537 --- /dev/null +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -0,0 +1,42 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_ONCEUPON_H +#define GOB_PREGOB_ONCEUPON_ONCEUPON_H + +#include "gob/pregob/pregob.h" + +namespace Gob { + +namespace OnceUpon { + +class OnceUpon : public PreGob { +public: + OnceUpon(GobEngine *vm); + ~OnceUpon(); +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_ONCEUPON_H diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp new file mode 100644 index 0000000000..ab47adaac6 --- /dev/null +++ b/engines/gob/pregob/pregob.cpp @@ -0,0 +1,35 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/gob.h" + +#include "gob/pregob/pregob.h" + +namespace Gob { + +PreGob::PreGob(GobEngine *vm) : _vm(vm) { +} + +PreGob::~PreGob() { +} + +} // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h new file mode 100644 index 0000000000..e77e0ba17b --- /dev/null +++ b/engines/gob/pregob/pregob.h @@ -0,0 +1,43 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_PREGOB_H +#define GOB_PREGOB_PREGOB_H + +namespace Gob { + +class GobEngine; + +class PreGob { +public: + PreGob(GobEngine *vm); + virtual ~PreGob(); + + virtual void run() = 0; + +protected: + GobEngine *_vm; +}; + +} // End of namespace Gob + +#endif // GOB_PREGOB_PREGOB_H -- cgit v1.2.3 From 8b19e10104a98a95963ad2ee97b255d6804e7fdd Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 03:38:27 +0200 Subject: GOB: Add some generic PreGob graphics functions --- engines/gob/pregob/pregob.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++- engines/gob/pregob/pregob.h | 17 ++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index ab47adaac6..aea290214c 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -21,15 +21,73 @@ */ #include "gob/gob.h" +#include "gob/global.h" +#include "gob/util.h" +#include "gob/palanim.h" +#include "gob/draw.h" +#include "gob/video.h" #include "gob/pregob/pregob.h" namespace Gob { -PreGob::PreGob(GobEngine *vm) : _vm(vm) { +PreGob::PreGob(GobEngine *vm) : _vm(vm), _fadedOut(false) { } PreGob::~PreGob() { } +void PreGob::fadeOut() { + if (_fadedOut || _vm->shouldQuit()) + return; + + // Fade to black + _vm->_palAnim->fade(0, 0, 0); + + _fadedOut = true; +} + +void PreGob::fadeIn() { + if (!_fadedOut || _vm->shouldQuit()) + return; + + // Fade to palette + _vm->_draw->blitInvalidated(); + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); + + _fadedOut = false; +} + +void PreGob::clearScreen() { + _vm->_draw->_backSurface->clear(); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); + _vm->_draw->blitInvalidated(); + _vm->_video->retrace(); +} + +void PreGob::initScreen() { + _vm->_util->setFrameRate(15); + + _fadedOut = true; + + _vm->_draw->initScreen(); + + _vm->_draw->_backSurface->clear(); + _vm->_util->clearPalette(); + + _vm->_draw->forceBlit(); + _vm->_video->retrace(); + + _vm->_util->processInput(); +} + +void PreGob::setPalette(const byte *palette, uint16 size) { + memcpy(_vm->_draw->_vgaPalette, palette, 3 * size); + + // If we didn't fade out prior, immediately set the palette + if (!_fadedOut) + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index e77e0ba17b..6418d6fd8a 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -35,7 +35,24 @@ public: virtual void run() = 0; protected: + void initScreen(); ///< Initialize the game screen. + + void fadeOut(); ///< Fade to black. + void fadeIn(); ///< Fade to the current palette. + + void clearScreen(); + + /** Change the palette. + * + * @param palette The palette to change to. + * @param size Size of the palette in colors. + */ + void setPalette(const byte *palette, uint16 size); ///< Change the palette + GobEngine *_vm; + +private: + bool _fadedOut; ///< Did we fade out? }; } // End of namespace Gob -- cgit v1.2.3 From 38fe3c3cd9e656b3e3f2b35011895d6703a1a896 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 03:39:33 +0200 Subject: GOB: Add palettes for Once Upon A Time --- engines/gob/pregob/onceupon/abracadabra.cpp | 2 + engines/gob/pregob/onceupon/babayaga.cpp | 2 + engines/gob/pregob/onceupon/onceupon.cpp | 150 ++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 8 ++ 4 files changed, 162 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 14a362ce12..84d84e89a5 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -36,6 +36,8 @@ Abracadabra::~Abracadabra() { void Abracadabra::run() { warning("TODO: Abracadabra::run()"); + + initScreen(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index f2c7569460..21355ab9ed 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -36,6 +36,8 @@ BabaYaga::~BabaYaga() { void BabaYaga::run() { warning("TODO: BabaYaga::run()"); + + initScreen(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 639f5b1ee8..35127cbfb3 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -20,8 +20,147 @@ * */ +#include "gob/gob.h" +#include "gob/util.h" +#include "gob/dataio.h" +#include "gob/draw.h" +#include "gob/video.h" + #include "gob/pregob/onceupon/onceupon.h" +static const int kPaletteSize = 16; +static const uint kPaletteCount = 20; + +static const byte kCopyProtectionPalette[3 * kPaletteSize] = { + 0x00, 0x00, 0x00, 0x19, 0x00, 0x19, 0x00, 0x3F, 0x00, 0x00, 0x2A, 0x2A, + 0x2A, 0x00, 0x00, 0x2A, 0x00, 0x2A, 0x2A, 0x15, 0x00, 0x00, 0x19, 0x12, + 0x00, 0x00, 0x00, 0x15, 0x15, 0x3F, 0x15, 0x3F, 0x15, 0x00, 0x20, 0x3F, + 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x20, 0x3F, 0x3F, 0x00, 0x3F, 0x3F, 0x3F +}; + +static const byte kGamePalettes[kPaletteCount][3 * kPaletteSize] = { + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3C, + 0x1C, 0x28, 0x00, 0x10, 0x18, 0x00, 0x1C, 0x1C, 0x20, 0x14, 0x14, 0x14, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x14, 0x20, 0x04, + 0x3C, 0x2C, 0x00, 0x02, 0x00, 0x18, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x38, 0x20, 0x3C, 0x2C, 0x10, 0x30, 0x20, 0x08, 0x28, + 0x14, 0x00, 0x1C, 0x20, 0x20, 0x38, 0x18, 0x18, 0x2C, 0x10, 0x10, 0x24, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x3C, 0x20, 0x20, 0x24, 0x14, 0x14, 0x1C, 0x10, 0x10, + 0x14, 0x0C, 0x0C, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x10, 0x10, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x10, 0x28, 0x1C, 0x10, 0x1C, 0x10, 0x10, 0x14, 0x0C, + 0x1C, 0x1C, 0x3C, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x24, 0x10, 0x10, 0x18, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x3F, 0x26, 0x3F, 0x36, 0x1C, 0x36, 0x2C, 0x12, 0x2A, + 0x27, 0x0C, 0x24, 0x22, 0x07, 0x1E, 0x1D, 0x03, 0x18, 0x16, 0x00, 0x10, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3A, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x3F, 0x39, 0x26, 0x38, 0x34, 0x1C, 0x30, 0x2F, 0x13, + 0x27, 0x29, 0x0C, 0x1D, 0x22, 0x07, 0x14, 0x1B, 0x03, 0x0C, 0x14, 0x00, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3A, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x1C, 0x34, 0x38, 0x14, 0x2C, 0x30, + 0x0C, 0x20, 0x2C, 0x08, 0x18, 0x28, 0x04, 0x10, 0x20, 0x00, 0x08, 0x1C, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x3C, 0x2C, 0x24, 0x38, 0x24, 0x1C, 0x30, 0x1C, 0x14, + 0x28, 0x18, 0x0C, 0x20, 0x10, 0x04, 0x1C, 0x0C, 0x00, 0x14, 0x08, 0x00, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x3C, 0x34, 0x24, 0x38, 0x2C, 0x1C, 0x30, 0x24, 0x14, + 0x2C, 0x1C, 0x10, 0x30, 0x30, 0x3C, 0x1C, 0x1C, 0x38, 0x0C, 0x0C, 0x38, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x03, 0x14, 0x07, 0x07, 0x1D, + 0x0E, 0x0E, 0x25, 0x17, 0x17, 0x2E, 0x21, 0x22, 0x36, 0x2F, 0x2F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3B, 0x0D, 0x3A, 0x31, 0x0A, 0x35, 0x28, 0x07, + 0x30, 0x21, 0x04, 0x2B, 0x19, 0x02, 0x26, 0x12, 0x01, 0x16, 0x0B, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x21, 0x01, 0x00, 0x2A, 0x02, 0x00, + 0x33, 0x03, 0x00, 0x3D, 0x06, 0x00, 0x2A, 0x19, 0x05, 0x15, 0x14, 0x14, + 0x22, 0x1F, 0x1E, 0x2F, 0x2C, 0x28, 0x3F, 0x3C, 0x29, 0x3F, 0x38, 0x0B, + 0x3B, 0x30, 0x0A, 0x37, 0x29, 0x08, 0x33, 0x23, 0x07, 0x2F, 0x1D, 0x06 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x34, 0x30, 0x28, 0x2C, 0x24, 0x1C, + 0x24, 0x18, 0x10, 0x1C, 0x10, 0x08, 0x14, 0x04, 0x04, 0x10, 0x00, 0x00, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x34, 0x30, 0x28, 0x2C, 0x24, 0x1C, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x1A, 0x30, 0x37, 0x14, 0x28, 0x31, 0x10, 0x20, 0x2C, + 0x0C, 0x19, 0x27, 0x08, 0x12, 0x21, 0x05, 0x0C, 0x1C, 0x03, 0x07, 0x16, + 0x01, 0x03, 0x11, 0x00, 0x00, 0x0C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x34, 0x30, 0x34, 0x30, 0x24, 0x30, 0x28, 0x1C, 0x28, + 0x24, 0x14, 0x24, 0x1C, 0x0C, 0x1C, 0x18, 0x08, 0x18, 0x14, 0x04, 0x14, + 0x0C, 0x04, 0x0C, 0x08, 0x00, 0x08, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x2C, 0x24, 0x0C, 0x34, 0x34, 0x28, 0x2C, 0x2C, 0x1C, + 0x24, 0x24, 0x10, 0x1C, 0x18, 0x08, 0x14, 0x14, 0x08, 0x10, 0x10, 0x04, + 0x0C, 0x0C, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x31, 0x10, 0x20, 0x2C, + 0x0C, 0x19, 0x27, 0x08, 0x12, 0x21, 0x05, 0x0C, 0x1C, 0x03, 0x07, 0x16, + 0x01, 0x03, 0x11, 0x00, 0x3C, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x10, 0x28, 0x1C, 0x10, 0x1C, 0x10, 0x10, 0x14, 0x0C, + 0x1C, 0x1C, 0x3C, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x24, 0x10, 0x10, 0x18, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x10, 0x28, 0x1C, 0x10, 0x1C, 0x10, 0x10, 0x14, 0x0C, + 0x1C, 0x1C, 0x3C, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x24, 0x10, 0x10, 0x18, + 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 + } +}; + namespace Gob { namespace OnceUpon { @@ -32,6 +171,17 @@ OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm) { OnceUpon::~OnceUpon() { } +void OnceUpon::setCopyProtectionPalette() { + setPalette(kCopyProtectionPalette, kPaletteSize); +} + +void OnceUpon::setGamePalette(uint palette) { + if (palette >= kPaletteCount) + return; + + setPalette(kGamePalettes[palette], kPaletteSize); +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index f937701537..816d4dc051 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -23,6 +23,8 @@ #ifndef GOB_PREGOB_ONCEUPON_ONCEUPON_H #define GOB_PREGOB_ONCEUPON_ONCEUPON_H +#include "common/system.h" + #include "gob/pregob/pregob.h" namespace Gob { @@ -33,6 +35,12 @@ class OnceUpon : public PreGob { public: OnceUpon(GobEngine *vm); ~OnceUpon(); + +protected: + void setGamePalette(uint palette); + +private: + void setCopyProtectionPalette(); }; } // End of namespace OnceUpon -- cgit v1.2.3 From 27782700a5631a25129b12779abb540a906f6a96 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 17:45:02 +0200 Subject: GOB: Add some PreGob and Once Upon A Time cursor functions --- engines/gob/draw.cpp | 4 ++- engines/gob/draw_v2.cpp | 5 +++- engines/gob/pregob/onceupon/onceupon.cpp | 1 + engines/gob/pregob/onceupon/onceupon.h | 2 ++ engines/gob/pregob/pregob.cpp | 47 ++++++++++++++++++++++++++++++++ engines/gob/pregob/pregob.h | 14 ++++++++++ engines/gob/video.cpp | 2 +- 7 files changed, 72 insertions(+), 3 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 3932987e0a..8c6919416d 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -271,7 +271,9 @@ void Draw::blitInvalidated() { return; } - _showCursor = (_showCursor & ~2) | ((_showCursor & 1) << 1); + if (_cursorSprites) + _showCursor = (_showCursor & ~2) | ((_showCursor & 1) << 1); + if (_applyPal) { clearPalette(); forceBlit(); diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index ac43c7b86a..f5475278c4 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -74,13 +74,16 @@ void Draw_v2::closeScreen() { } void Draw_v2::blitCursor() { - if (_cursorIndex == -1) + if (!_cursorSprites || (_cursorIndex == -1)) return; _showCursor = (_showCursor & ~2) | ((_showCursor & 1) << 1); } void Draw_v2::animateCursor(int16 cursor) { + if (!_cursorSprites) + return; + int16 cursorIndex = cursor; int16 newX = 0, newY = 0; uint16 hotspotX, hotspotY; diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 35127cbfb3..7f7dffa7ec 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -23,6 +23,7 @@ #include "gob/gob.h" #include "gob/util.h" #include "gob/dataio.h" +#include "gob/surface.h" #include "gob/draw.h" #include "gob/video.h" diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 816d4dc051..c1c4d6fa0d 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -29,6 +29,8 @@ namespace Gob { +class Surface; + namespace OnceUpon { class OnceUpon : public PreGob { diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index aea290214c..18aac50352 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -20,9 +20,12 @@ * */ +#include "graphics/cursorman.h" + #include "gob/gob.h" #include "gob/global.h" #include "gob/util.h" +#include "gob/surface.h" #include "gob/palanim.h" #include "gob/draw.h" #include "gob/video.h" @@ -90,4 +93,48 @@ void PreGob::setPalette(const byte *palette, uint16 size) { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); } +void PreGob::addCursor() { + CursorMan.pushCursor(0, 0, 0, 0, 0, 0); +} + +void PreGob::removeCursor() { + CursorMan.popCursor(); +} + +void PreGob::setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY) { + CursorMan.replaceCursor(sprite.getData(), sprite.getWidth(), sprite.getHeight(), hotspotX, hotspotY, 0); +} + +void PreGob::setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom, + int16 hotspotX, int16 hotspotY) { + + const int width = right - left + 1; + const int height = bottom - top + 1; + + if ((width <= 0) || (height <= 0)) + return; + + Surface cursor(width, height, 1); + + cursor.blit(sprite, left, top, right, bottom, 0, 0); + + setCursor(cursor, hotspotX, hotspotX); +} + +void PreGob::showCursor() { + CursorMan.showMouse(true); + + _vm->_draw->_showCursor = 4; +} + +void PreGob::hideCursor() { + CursorMan.showMouse(false); + + _vm->_draw->_showCursor = 0; +} + +bool PreGob::isCursorVisible() const { + return CursorMan.isVisible(); +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 6418d6fd8a..e0f7ca907d 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -26,6 +26,7 @@ namespace Gob { class GobEngine; +class Surface; class PreGob { public: @@ -49,6 +50,19 @@ protected: */ void setPalette(const byte *palette, uint16 size); ///< Change the palette + void addCursor(); + void removeCursor(); + + void setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY); + void setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom, + int16 hotspotX, int16 hotspotY); + + void showCursor(); + void hideCursor(); + + bool isCursorVisible() const; + + GobEngine *_vm; private: diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 8bcf14e040..62bb210a8e 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -242,7 +242,7 @@ void Video::setSize(bool defaultTo1XScaler) { void Video::retrace(bool mouse) { if (mouse) - CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); + CursorMan.showMouse((_vm->_draw->_showCursor & 6) != 0); if (_vm->_global->_primarySurfDesc) { int screenX = _screenDeltaX; -- cgit v1.2.3 From 83896dea3edc3bcfb1e414b61644c7ca266e1cce Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 21:25:54 +0200 Subject: GOB: Add PreGob input/event utility functions --- engines/gob/pregob/pregob.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++ engines/gob/pregob/pregob.h | 9 +++++++++ 2 files changed, 53 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 18aac50352..1c3fb8221c 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -137,4 +137,48 @@ bool PreGob::isCursorVisible() const { return CursorMan.isVisible(); } +void PreGob::endFrame(bool doInput) { + _vm->_draw->blitInvalidated(); + _vm->_util->waitEndFrame(); + + if (doInput) + _vm->_util->processInput(); +} + +int16 PreGob::checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) { + _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons); + _vm->_util->forceMouseUp(); + + return _vm->_util->checkKey(); +} + +int16 PreGob::waitInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons) { + bool finished = false; + + int16 key = 0; + while (!_vm->shouldQuit() && !finished) { + endFrame(true); + + key = checkInput(mouseX, mouseY, mouseButtons); + + finished = (mouseButtons != kMouseButtonsNone) || (key != 0); + } + + return key; +} + +int16 PreGob::waitInput() { + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + return waitInput(mouseX, mouseY, mouseButtons); +} + +bool PreGob::hasInput() { + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + return checkInput(mouseX, mouseY, mouseButtons) || (mouseButtons != kMouseButtonsNone); +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index e0f7ca907d..4cf4a39fdb 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -23,6 +23,8 @@ #ifndef GOB_PREGOB_PREGOB_H #define GOB_PREGOB_PREGOB_H +#include "gob/util.h" + namespace Gob { class GobEngine; @@ -62,6 +64,13 @@ protected: bool isCursorVisible() const; + void endFrame(bool doInput); + + int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + int16 waitInput (int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + int16 waitInput(); + bool hasInput(); + GobEngine *_vm; -- cgit v1.2.3 From 4fc3a88c5f0b053323aeaeac658dafb8e4606662 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 28 Jun 2012 22:54:05 +0200 Subject: GOB: Add support for different methods of handling Endianness The Once Upon A Time games handle endianness different in ANI, DEC and RXY files than Geisha does. We need to support both approaches. --- engines/gob/anifile.cpp | 34 +++++++++++++++++++++------------- engines/gob/cmpfile.cpp | 9 ++++++++- engines/gob/decfile.cpp | 42 +++++++++++++++++++++++++----------------- engines/gob/gob.cpp | 8 ++++++++ engines/gob/gob.h | 10 ++++++++++ engines/gob/rxyfile.cpp | 19 +++++++++++++------ engines/gob/rxyfile.h | 4 +++- 7 files changed, 88 insertions(+), 38 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/anifile.cpp b/engines/gob/anifile.cpp index 2671fe0405..e6bf30f4d7 100644 --- a/engines/gob/anifile.cpp +++ b/engines/gob/anifile.cpp @@ -37,30 +37,38 @@ ANIFile::ANIFile(GobEngine *vm, const Common::String &fileName, uint16 width, uint8 bpp) : _vm(vm), _width(width), _bpp(bpp), _hasPadding(false) { - Common::SeekableReadStream *ani = _vm->_dataIO->getFile(fileName); - if (ani) { - Common::SeekableSubReadStreamEndian sub(ani, 0, ani->size(), false, DisposeAfterUse::YES); + bool bigEndian = false; + Common::String endianFileName = fileName; - load(sub, fileName); - return; - } + if ((_vm->getEndiannessMethod() == kEndiannessMethodAltFile) && + !_vm->_dataIO->hasFile(fileName)) { + // If the game has alternate big-endian files, look if one exist + + Common::String alternateFileName = fileName; + alternateFileName.setChar('_', 0); - // File doesn't exist, try to open the big-endian'd alternate file - Common::String alternateFileName = fileName; - alternateFileName.setChar('_', 0); + if (_vm->_dataIO->hasFile(alternateFileName)) { + bigEndian = true; + endianFileName = alternateFileName; + } + } else if ((_vm->getEndiannessMethod() == kEndiannessMethodBE) || + ((_vm->getEndiannessMethod() == kEndiannessMethodSystem) && + (_vm->getEndianness() == kEndiannessBE))) + // Game always little endian or it follows the system and it is big endian + bigEndian = true; - ani = _vm->_dataIO->getFile(alternateFileName); + Common::SeekableReadStream *ani = _vm->_dataIO->getFile(endianFileName); if (ani) { - Common::SeekableSubReadStreamEndian sub(ani, 0, ani->size(), true, DisposeAfterUse::YES); + Common::SeekableSubReadStreamEndian sub(ani, 0, ani->size(), bigEndian, DisposeAfterUse::YES); // The big endian version pads a few fields to even size - _hasPadding = true; + _hasPadding = bigEndian; load(sub, fileName); return; } - warning("ANIFile::ANIFile(): No such file \"%s\"", fileName.c_str()); + warning("ANIFile::ANIFile(): No such file \"%s\" (\"%s\")", endianFileName.c_str(), fileName.c_str()); } ANIFile::~ANIFile() { diff --git a/engines/gob/cmpfile.cpp b/engines/gob/cmpfile.cpp index 7b21c4c835..1cd1375879 100644 --- a/engines/gob/cmpfile.cpp +++ b/engines/gob/cmpfile.cpp @@ -21,6 +21,7 @@ */ #include "common/stream.h" +#include "common/substream.h" #include "common/str.h" #include "gob/gob.h" @@ -143,7 +144,13 @@ void CMPFile::loadCMP(Common::SeekableReadStream &cmp) { } void CMPFile::loadRXY(Common::SeekableReadStream &rxy) { - _coordinates = new RXYFile(rxy); + bool bigEndian = (_vm->getEndiannessMethod() == kEndiannessMethodBE) || + ((_vm->getEndiannessMethod() == kEndiannessMethodSystem) && + (_vm->getEndianness() == kEndiannessBE)); + + Common::SeekableSubReadStreamEndian sub(&rxy, 0, rxy.size(), bigEndian, DisposeAfterUse::NO); + + _coordinates = new RXYFile(sub); for (uint i = 0; i < _coordinates->size(); i++) { const RXYFile::Coordinates &c = (*_coordinates)[i]; diff --git a/engines/gob/decfile.cpp b/engines/gob/decfile.cpp index fb67c52627..85b4c09ca3 100644 --- a/engines/gob/decfile.cpp +++ b/engines/gob/decfile.cpp @@ -38,30 +38,38 @@ DECFile::DECFile(GobEngine *vm, const Common::String &fileName, uint16 width, uint16 height, uint8 bpp) : _vm(vm), _width(width), _height(height), _bpp(bpp), _hasPadding(false), _backdrop(0) { - Common::SeekableReadStream *dec = _vm->_dataIO->getFile(fileName); - if (dec) { - Common::SeekableSubReadStreamEndian sub(dec, 0, dec->size(), false, DisposeAfterUse::YES); - - load(sub, fileName); - return; - } - - // File doesn't exist, try to open the big-endian'd alternate file - Common::String alternateFileName = fileName; - alternateFileName.setChar('_', 0); - - dec = _vm->_dataIO->getFile(alternateFileName); - if (dec) { - Common::SeekableSubReadStreamEndian sub(dec, 0, dec->size(), true, DisposeAfterUse::YES); + bool bigEndian = false; + Common::String endianFileName = fileName; + + if ((_vm->getEndiannessMethod() == kEndiannessMethodAltFile) && + !_vm->_dataIO->hasFile(fileName)) { + // If the game has alternate big-endian files, look if one exist + + Common::String alternateFileName = fileName; + alternateFileName.setChar('_', 0); + + if (_vm->_dataIO->hasFile(alternateFileName)) { + bigEndian = true; + endianFileName = alternateFileName; + } + } else if ((_vm->getEndiannessMethod() == kEndiannessMethodBE) || + ((_vm->getEndiannessMethod() == kEndiannessMethodSystem) && + (_vm->getEndianness() == kEndiannessBE))) + // Game always little endian or it follows the system and it is big endian + bigEndian = true; + + Common::SeekableReadStream *ani = _vm->_dataIO->getFile(endianFileName); + if (ani) { + Common::SeekableSubReadStreamEndian sub(ani, 0, ani->size(), bigEndian, DisposeAfterUse::YES); // The big endian version pads a few fields to even size - _hasPadding = true; + _hasPadding = bigEndian; load(sub, fileName); return; } - warning("DECFile::DECFile(): No such file \"%s\"", fileName.c_str()); + warning("DECFile::DECFile(): No such file \"%s\" (\"%s\")", endianFileName.c_str(), fileName.c_str()); } DECFile::~DECFile() { diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 02aea63377..fcf98f0355 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -184,6 +184,10 @@ void GobEngine::validateVideoMode(int16 videoMode) { error("Video mode 0x%X is not supported", videoMode); } +EndiannessMethod GobEngine::getEndiannessMethod() const { + return _endiannessMethod; +} + Endianness GobEngine::getEndianness() const { if ((getPlatform() == Common::kPlatformAmiga) || (getPlatform() == Common::kPlatformMacintosh) || @@ -403,6 +407,8 @@ Common::Error GobEngine::initGameParts() { // just detect some devices some of which will be always there if the music is not disabled _noMusic = MidiDriver::getMusicType(MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB)) == MT_NULL ? true : false; + _endiannessMethod = kEndiannessMethodSystem; + _global = new Global(this); _util = new Util(this); _dataIO = new DataIO(); @@ -433,6 +439,8 @@ Common::Error GobEngine::initGameParts() { _goblin = new Goblin_v1(this); _scenery = new Scenery_v1(this); _saveLoad = new SaveLoad_Geisha(this, _targetName.c_str()); + + _endiannessMethod = kEndiannessMethodAltFile; break; case kGameTypeFascination: diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 9b919098d6..df73404596 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -149,6 +149,13 @@ enum Features { kFeaturesTrueColor = 1 << 7 }; +enum EndiannessMethod { + kEndiannessMethodLE, ///< Always little endian. + kEndiannessMethodBE, ///< Always big endian. + kEndiannessMethodSystem, ///< Follows system endianness. + kEndiannessMethodAltFile ///< Different endianness in alternate file. +}; + enum { kDebugFuncOp = 1 << 0, kDebugDrawOp = 1 << 1, @@ -172,6 +179,8 @@ private: int32 _features; Common::Platform _platform; + EndiannessMethod _endiannessMethod; + uint32 _pauseStart; // Engine APIs @@ -232,6 +241,7 @@ public: void pauseGame(); + EndiannessMethod getEndiannessMethod() const; Endianness getEndianness() const; Common::Platform getPlatform() const; GameType getGameType() const; diff --git a/engines/gob/rxyfile.cpp b/engines/gob/rxyfile.cpp index 9702dc8c7f..2ff8c121cd 100644 --- a/engines/gob/rxyfile.cpp +++ b/engines/gob/rxyfile.cpp @@ -21,12 +21,19 @@ */ #include "common/stream.h" +#include "common/substream.h" #include "gob/rxyfile.h" namespace Gob { RXYFile::RXYFile(Common::SeekableReadStream &rxy) : _width(0), _height(0) { + Common::SeekableSubReadStreamEndian sub(&rxy, 0, rxy.size(), false, DisposeAfterUse::NO); + + load(sub); +} + +RXYFile::RXYFile(Common::SeekableSubReadStreamEndian &rxy) : _width(0), _height(0) { load(rxy); } @@ -64,22 +71,22 @@ const RXYFile::Coordinates &RXYFile::operator[](uint i) const { return _coords[i]; } -void RXYFile::load(Common::SeekableReadStream &rxy) { +void RXYFile::load(Common::SeekableSubReadStreamEndian &rxy) { if (rxy.size() < 2) return; rxy.seek(0); - _realCount = rxy.readUint16LE(); + _realCount = rxy.readUint16(); uint16 count = (rxy.size() - 2) / 8; _coords.resize(count); for (CoordArray::iterator c = _coords.begin(); c != _coords.end(); ++c) { - c->left = rxy.readUint16LE(); - c->right = rxy.readUint16LE(); - c->top = rxy.readUint16LE(); - c->bottom = rxy.readUint16LE(); + c->left = rxy.readUint16(); + c->right = rxy.readUint16(); + c->top = rxy.readUint16(); + c->bottom = rxy.readUint16(); if (c->left != 0xFFFF) { _width = MAX(_width , c->right + 1); diff --git a/engines/gob/rxyfile.h b/engines/gob/rxyfile.h index bc9600b5b0..4fd46c5e40 100644 --- a/engines/gob/rxyfile.h +++ b/engines/gob/rxyfile.h @@ -28,6 +28,7 @@ namespace Common { class SeekableReadStream; + class SeekableSubReadStreamEndian; } namespace Gob { @@ -46,6 +47,7 @@ public: }; RXYFile(Common::SeekableReadStream &rxy); + RXYFile(Common::SeekableSubReadStreamEndian &rxy); RXYFile(uint16 width, uint16 height); ~RXYFile(); @@ -71,7 +73,7 @@ private: uint16 _height; - void load(Common::SeekableReadStream &rxy); + void load(Common::SeekableSubReadStreamEndian &rxy); }; } // End of namespace Gob -- cgit v1.2.3 From 734fc767d25d47b5da703dc1b4a3cfb494234155 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 18:25:11 +0200 Subject: GOB: Open the Once Upon A Time archives --- engines/gob/pregob/onceupon/abracadabra.cpp | 4 ++-- engines/gob/pregob/onceupon/babayaga.cpp | 4 ++-- engines/gob/pregob/onceupon/onceupon.cpp | 29 ++++++++++++++++++++++++++++- engines/gob/pregob/onceupon/onceupon.h | 6 ++++++ 4 files changed, 38 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 84d84e89a5..6cfdfa7822 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -35,9 +35,9 @@ Abracadabra::~Abracadabra() { } void Abracadabra::run() { - warning("TODO: Abracadabra::run()"); + init(); - initScreen(); + warning("TODO: Abracadabra::run()"); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 21355ab9ed..9f4f53c4e0 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -35,9 +35,9 @@ BabaYaga::~BabaYaga() { } void BabaYaga::run() { - warning("TODO: BabaYaga::run()"); + init(); - initScreen(); + warning("TODO: BabaYaga::run()"); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 7f7dffa7ec..e3d1a8535f 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -166,10 +166,37 @@ namespace Gob { namespace OnceUpon { -OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm) { +OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _openedArchives(false) { + } OnceUpon::~OnceUpon() { + deinit(); +} + +void OnceUpon::init() { + deinit(); + + bool hasSTK1 = _vm->_dataIO->openArchive("stk1.stk", true); + bool hasSTK2 = _vm->_dataIO->openArchive("stk2.stk", true); + bool hasSTK3 = _vm->_dataIO->openArchive("stk3.stk", true); + + if (!hasSTK1 || !hasSTK2 || !hasSTK3) + error("OnceUpon::OnceUpon(): Failed to open archives"); + + _openedArchives = true; + + initScreen(); +} + +void OnceUpon::deinit() { + if (_openedArchives) { + _vm->_dataIO->closeArchive(true); + _vm->_dataIO->closeArchive(true); + _vm->_dataIO->closeArchive(true); + } + + _openedArchives = false; } void OnceUpon::setCopyProtectionPalette() { diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index c1c4d6fa0d..e5f70855ad 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -39,10 +39,16 @@ public: ~OnceUpon(); protected: + void init(); + void deinit(); + void setGamePalette(uint palette); private: void setCopyProtectionPalette(); + + + bool _openedArchives; }; } // End of namespace OnceUpon -- cgit v1.2.3 From 3313302a157fc08d3965c6cb114e3a3f4d366c4b Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 18:28:57 +0200 Subject: GOB: Load the Once Upon A Time fonts --- engines/gob/pregob/onceupon/onceupon.cpp | 22 +++++++++++++++++++++- engines/gob/pregob/onceupon/onceupon.h | 7 +++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index e3d1a8535f..6b12dd8653 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -166,7 +166,8 @@ namespace Gob { namespace OnceUpon { -OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _openedArchives(false) { +OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _jeudak(0), _lettre(0), _plettre(0), _glettre(0), + _openedArchives(false) { } @@ -186,10 +187,29 @@ void OnceUpon::init() { _openedArchives = true; + _jeudak = _vm->_draw->loadFont("jeudak.let"); + _lettre = _vm->_draw->loadFont("lettre.let"); + _plettre = _vm->_draw->loadFont("plettre.let"); + _glettre = _vm->_draw->loadFont("glettre.let"); + + if (!_jeudak || !_lettre || !_plettre || !_glettre) + error("OnceUpon::OnceUpon(): Failed to fonts (%d, %d, %d, %d)", + _jeudak != 0, _lettre != 0, _plettre != 0, _glettre != 0); + initScreen(); } void OnceUpon::deinit() { + delete _jeudak; + delete _lettre; + delete _plettre; + delete _glettre; + + _jeudak = 0; + _lettre = 0; + _plettre = 0; + _glettre = 0; + if (_openedArchives) { _vm->_dataIO->closeArchive(true); _vm->_dataIO->closeArchive(true); diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index e5f70855ad..cfc12532dd 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -30,6 +30,7 @@ namespace Gob { class Surface; +class Font; namespace OnceUpon { @@ -44,6 +45,12 @@ protected: void setGamePalette(uint palette); + + Font *_jeudak; + Font *_lettre; + Font *_plettre; + Font *_glettre; + private: void setCopyProtectionPalette(); -- cgit v1.2.3 From aae8c607596d9ce228935c01297902381c8b442c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 18:31:09 +0200 Subject: GOB: Verify the language in Once Upon A Time --- engines/gob/pregob/onceupon/onceupon.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 6b12dd8653..adea776297 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -21,6 +21,7 @@ */ #include "gob/gob.h" +#include "gob/global.h" #include "gob/util.h" #include "gob/dataio.h" #include "gob/surface.h" @@ -196,6 +197,15 @@ void OnceUpon::init() { error("OnceUpon::OnceUpon(): Failed to fonts (%d, %d, %d, %d)", _jeudak != 0, _lettre != 0, _plettre != 0, _glettre != 0); + if (_vm->_global->_language == kLanguageAmerican) + _vm->_global->_language = kLanguageBritish; + + if ((_vm->_global->_language >= kLanguageCount)) + error("We do not support the language \"%s\".\n" + "If you are certain that your game copy includes this language,\n" + "please contact the ScummVM team with details about this version.\n" + "Thanks", _vm->getLangDesc(_vm->_global->_language)); + initScreen(); } -- cgit v1.2.3 From 412ae53854dc2ef352a3f3e990f0d2b56d97ad7e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 19:34:14 +0200 Subject: GOB: Add PreGob animation utility functions --- engines/gob/pregob/pregob.cpp | 21 +++++++++++++++++++++ engines/gob/pregob/pregob.h | 6 ++++++ 2 files changed, 27 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 1c3fb8221c..b9c36d7cf8 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -29,6 +29,7 @@ #include "gob/palanim.h" #include "gob/draw.h" #include "gob/video.h" +#include "gob/aniobject.h" #include "gob/pregob/pregob.h" @@ -181,4 +182,24 @@ bool PreGob::hasInput() { return checkInput(mouseX, mouseY, mouseButtons) || (mouseButtons != kMouseButtonsNone); } +void PreGob::clearAnim(ANIObject &ani) { + int16 left, top, right, bottom; + + if (ani.clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); +} + +void PreGob::drawAnim(ANIObject &ani) { + int16 left, top, right, bottom; + + if (ani.draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + ani.advance(); +} + +void PreGob::redrawAnim(ANIObject &ani) { + clearAnim(ani); + drawAnim(ani); +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 4cf4a39fdb..9efdbe8df6 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -30,6 +30,8 @@ namespace Gob { class GobEngine; class Surface; +class ANIObject; + class PreGob { public: PreGob(GobEngine *vm); @@ -71,6 +73,10 @@ protected: int16 waitInput(); bool hasInput(); + void clearAnim(ANIObject &ani); + void drawAnim(ANIObject &ani); + void redrawAnim(ANIObject &ani); + GobEngine *_vm; -- cgit v1.2.3 From ef3b4af9d8d221f52aaed900a2997b486ed2e6e4 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 18:31:45 +0200 Subject: GOB: Implement the copy protection in Once Upon A Time --- engines/gob/pregob/onceupon/abracadabra.cpp | 24 +++ engines/gob/pregob/onceupon/babayaga.cpp | 24 +++ engines/gob/pregob/onceupon/onceupon.cpp | 247 ++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 11 ++ 4 files changed, 306 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 6cfdfa7822..d8dd8b3be0 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -22,8 +22,28 @@ #include "common/textconsole.h" +#include "gob/gob.h" + #include "gob/pregob/onceupon/abracadabra.h" +static const uint8 kCopyProtectionColors[7] = { + 14, 11, 13, 1, 7, 12, 2 +}; + +static const uint8 kCopyProtectionShapes[7 * 20] = { + 3, 4, 3, 0, 1, 2, 0, 2, 2, 0, 2, 4, 0, 3, 4, 1, 1, 4, 1, 3, + 0, 2, 0, 4, 2, 4, 4, 2, 3, 0, 1, 1, 1, 1, 3, 0, 4, 2, 3, 4, + 0, 0, 1, 2, 1, 1, 2, 4, 3, 1, 4, 2, 4, 4, 2, 4, 1, 2, 3, 3, + 1, 0, 2, 3, 4, 2, 3, 2, 2, 0, 0, 0, 4, 2, 3, 4, 4, 0, 4, 1, + 4, 2, 1, 1, 1, 1, 4, 3, 4, 2, 3, 0, 0, 3, 0, 2, 3, 0, 2, 4, + 4, 2, 4, 3, 0, 4, 0, 2, 3, 1, 4, 1, 3, 1, 0, 0, 2, 1, 3, 2, + 3, 1, 0, 3, 1, 3, 4, 2, 4, 4, 3, 2, 0, 2, 0, 1, 2, 0, 1, 4 +}; + +static const uint8 kCopyProtectionObfuscate[4] = { + 1, 0, 2, 3 +}; + namespace Gob { namespace OnceUpon { @@ -37,6 +57,10 @@ Abracadabra::~Abracadabra() { void Abracadabra::run() { init(); + bool correctCP = doCopyProtection(kCopyProtectionColors, kCopyProtectionShapes, kCopyProtectionObfuscate); + if (_vm->shouldQuit() || !correctCP) + return; + warning("TODO: Abracadabra::run()"); } diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 9f4f53c4e0..aad1fc6aca 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -22,8 +22,28 @@ #include "common/textconsole.h" +#include "gob/gob.h" + #include "gob/pregob/onceupon/babayaga.h" +static const uint8 kCopyProtectionColors[7] = { + 14, 11, 13, 1, 7, 12, 2 +}; + +static const uint8 kCopyProtectionShapes[7 * 20] = { + 0, 0, 1, 2, 1, 1, 2, 4, 3, 1, 4, 2, 4, 4, 2, 4, 1, 2, 3, 3, + 3, 1, 0, 3, 1, 3, 4, 2, 4, 4, 3, 2, 0, 2, 0, 1, 2, 0, 1, 4, + 1, 0, 2, 3, 4, 2, 3, 2, 2, 0, 0, 0, 4, 2, 3, 4, 4, 0, 4, 1, + 0, 2, 0, 4, 2, 4, 4, 2, 3, 0, 1, 1, 1, 1, 3, 0, 4, 2, 3, 4, + 3, 4, 3, 0, 1, 2, 0, 2, 2, 0, 2, 4, 0, 3, 4, 1, 1, 4, 1, 3, + 4, 2, 1, 1, 1, 1, 4, 3, 4, 2, 3, 0, 0, 3, 0, 2, 3, 0, 2, 4, + 4, 2, 4, 3, 0, 4, 0, 2, 3, 1, 4, 1, 3, 1, 0, 0, 2, 1, 3, 2 +}; + +static const uint8 kCopyProtectionObfuscate[4] = { + 0, 1, 2, 3 +}; + namespace Gob { namespace OnceUpon { @@ -37,6 +57,10 @@ BabaYaga::~BabaYaga() { void BabaYaga::run() { init(); + bool correctCP = doCopyProtection(kCopyProtectionColors, kCopyProtectionShapes, kCopyProtectionObfuscate); + if (_vm->shouldQuit() || !correctCP) + return; + warning("TODO: BabaYaga::run()"); } diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index adea776297..aa85e1c095 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -27,6 +27,8 @@ #include "gob/surface.h" #include "gob/draw.h" #include "gob/video.h" +#include "gob/anifile.h" +#include "gob/aniobject.h" #include "gob/pregob/onceupon/onceupon.h" @@ -163,6 +165,62 @@ static const byte kGamePalettes[kPaletteCount][3 * kPaletteSize] = { } }; +static const uint kLanguageCount = 5; + +static const uint kCopyProtectionHelpStringCount = 3; + +static const char *kCopyProtectionHelpStrings[kLanguageCount][kCopyProtectionHelpStringCount] = { + { // French + "Consulte le livret des animaux, rep\212re la", + "page correspondant \205 la couleur de l\'\202cran", + "et clique le symbole associ\202 \205 l\'animal affich\202.", + }, + { // German + "Suche im Tieralbum die Seite, die der Farbe auf", + "dem Bildschirm entspricht und klicke auf das", + "Tiersymbol.", + }, + { // English + "Consult the book of animals, find the page", + "corresponding to the colour of screen and click", + "the symbol associated with the animal displayed.", + }, + { // Spanish + "Consulta el libro de los animales, localiza la ", + "p\240gina que corresponde al color de la pantalla.", + "Cliquea el s\241mbolo asociado al animal que aparece.", + }, + { // Italian + "Guarda il libretto degli animali, trova la", + "pagina che corrisponde al colore dello schermo,", + "clicca il simbolo associato all\'animale presentato", + } +}; + +static const char *kCopyProtectionWrongStrings[kLanguageCount] = { + "Tu t\'es tromp\202, dommage...", // French + "Schade, du hast dich geirrt." , // German + "You are wrong, what a pity!" , // English + "Te equivocas, l\240stima..." , // Spanish + "Sei Sbagliato, peccato..." // Italian +}; + +static const uint kCopyProtectionShapeCount = 5; + +static const int16 kCopyProtectionShapeCoords[kCopyProtectionShapeCount][6] = { + { 0, 51, 26, 75, 60, 154}, + { 28, 51, 58, 81, 96, 151}, + { 60, 51, 94, 79, 136, 152}, + { 96, 51, 136, 71, 180, 155}, + {140, 51, 170, 77, 228, 153} +}; + +enum ClownAnimation { + kClownAnimationClownCheer = 0, + kClownAnimationClownStand = 1, + kClownAnimationClownCry = 6 +}; + namespace Gob { namespace OnceUpon { @@ -240,6 +298,195 @@ void OnceUpon::setGamePalette(uint palette) { setPalette(kGamePalettes[palette], kPaletteSize); } +enum CopyProtectionState { + kCPStateSetup, // Set up the screen + kCPStateWaitUser, // Waiting for the user to pick a shape + kCPStateWaitClown, // Waiting for the clown animation to finish + kCPStateFinish // Finishing +}; + +bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]) { + fadeOut(); + setCopyProtectionPalette(); + + Surface sprites[2] = {Surface(320, 200, 1), Surface(320, 200, 1)}; + + _vm->_video->drawPackedSprite("grille1.cmp", sprites[0]); + _vm->_video->drawPackedSprite("grille2.cmp", sprites[1]); + + ANIFile ani (_vm, "grille.ani", 320); + ANIObject clown(ani); + + setCursor(sprites[1], 5, 110, 20, 134, 3, 0); + + CopyProtectionState state = kCPStateSetup; + + uint8 triesLeft = 2; + int8 animalShape = -1; + bool hasCorrect = false; + + while (!_vm->shouldQuit() && (state != kCPStateFinish)) { + clearAnim(clown); + + // Set up the screen + if (state == kCPStateSetup) { + animalShape = cpSetup(colors, shapes, obfuscate, sprites); + + setAnimState(clown, kClownAnimationClownStand, false, false); + state = kCPStateWaitUser; + } + + drawAnim(clown); + + // If we're waiting for the clown and he finished, evaluate if we're finished + if (!clown.isVisible() && (state == kCPStateWaitClown)) + state = (hasCorrect || (--triesLeft == 0)) ? kCPStateFinish : kCPStateSetup; + + showCursor(); + fadeIn(); + + endFrame(true); + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + checkInput(mouseX, mouseY, mouseButtons); + + if (state == kCPStateWaitUser) { + // Look if we clicked a shaped and got it right + + int8 guessedShape = -1; + if (mouseButtons == kMouseButtonsLeft) + guessedShape = cpFindShape(mouseX, mouseY); + + if (guessedShape >= 0) { + hasCorrect = guessedShape == animalShape; + animalShape = -1; + + setAnimState(clown, hasCorrect ? kClownAnimationClownCheer : kClownAnimationClownCry, true, false); + state = kCPStateWaitClown; + } + } + } + + fadeOut(); + hideCursor(); + clearScreen(); + + // Display the "You are wrong" screen + if (!hasCorrect) + cpWrong(); + + return hasCorrect; +} + +int8 OnceUpon::cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4], + const Surface sprites[2]) { + + fadeOut(); + hideCursor(); + + // Get a random animal and animal color + int8 animalColor = _vm->_util->getRandom(7); + while ((colors[animalColor] == 1) || (colors[animalColor] == 7) || (colors[animalColor] == 11)) + animalColor = _vm->_util->getRandom(7); + + int8 animal = _vm->_util->getRandom(20); + + int8 animalShape = shapes[animalColor * 20 + animal]; + if (animal < 4) + animal = obfuscate[animal]; + + // Get the position of the animal sprite + int16 animalLeft = (animal % 4) * 80; + int16 animalTop = (animal / 4) * 50; + + uint8 sprite = 0; + if (animalTop >= 200) { + animalTop -= 200; + sprite = 1; + } + + int16 animalRight = animalLeft + 80 - 1; + int16 animalBottom = animalTop + 50 - 1; + + // Fill with the animal color + _vm->_draw->_backSurface->fill(colors[animalColor]); + + // Print the help line strings + for (uint i = 0; i < kCopyProtectionHelpStringCount; i++) { + const char * const helpString = kCopyProtectionHelpStrings[_vm->_global->_language][i]; + + const int x = 160 - (strlen(helpString) * _plettre->getCharWidth()) / 2; + const int y = i * 10 + 5; + + _plettre->drawString(helpString, x, y, 8, 0, true, *_vm->_draw->_backSurface); + } + + // White rectangle with black border + _vm->_draw->_backSurface->fillRect( 93, 43, 226, 134, 15); + _vm->_draw->_backSurface->drawRect( 92, 42, 227, 135, 0); + + // Draw the animal in the animal color + _vm->_draw->_backSurface->fillRect(120, 63, 199, 112, colors[animalColor]); + _vm->_draw->_backSurface->blit(sprites[sprite], animalLeft, animalTop, animalRight, animalBottom, 120, 63, 0); + + // Draw the shapes + for (uint i = 0; i < kCopyProtectionShapeCount; i++) { + const int16 * const coords = kCopyProtectionShapeCoords[i]; + + _vm->_draw->_backSurface->blit(sprites[1], coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], 0); + } + + _vm->_draw->forceBlit(); + + return animalShape; +} + +int8 OnceUpon::cpFindShape(int16 x, int16 y) const { + // Look through all shapes and check if the coordinates are inside one of them + for (uint i = 0; i < kCopyProtectionShapeCount; i++) { + const int16 * const coords = kCopyProtectionShapeCoords[i]; + + const int16 left = coords[4]; + const int16 top = coords[5]; + const int16 right = coords[4] + (coords[2] - coords[0] + 1) - 1; + const int16 bottom = coords[5] + (coords[3] - coords[1] + 1) - 1; + + if ((x >= left) && (x <= right) && (y >= top) && (y <= bottom)) + return i; + } + + return -1; +} + +void OnceUpon::cpWrong() { + // Display the "You are wrong" string, centered + + const char * const wrongString = kCopyProtectionWrongStrings[_vm->_global->_language]; + const int wrongX = 160 - (strlen(wrongString) * _plettre->getCharWidth()) / 2; + + _vm->_draw->_backSurface->clear(); + _plettre->drawString(wrongString, wrongX, 100, 15, 0, true, *_vm->_draw->_backSurface); + + _vm->_draw->forceBlit(); + + fadeIn(); + + waitInput(); + + fadeOut(); + clearScreen(); +} + +void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { + ani.setAnimation(state); + ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); + ani.setPause(pause); + ani.setVisible(true); + ani.setPosition(); +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index cfc12532dd..abcde68b81 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -32,6 +32,8 @@ namespace Gob { class Surface; class Font; +class ANIObject; + namespace OnceUpon { class OnceUpon : public PreGob { @@ -45,6 +47,8 @@ protected: void setGamePalette(uint palette); + bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + Font *_jeudak; Font *_lettre; @@ -54,6 +58,13 @@ protected: private: void setCopyProtectionPalette(); + void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; + + // Copy protection helpers + int8 cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4], const Surface sprites[2]); + int8 cpFindShape(int16 x, int16 y) const; + void cpWrong(); + bool _openedArchives; }; -- cgit v1.2.3 From 67d7c3f11fdaf697f7f3c3779643121793ba4eb7 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 29 Jun 2012 19:24:54 +0200 Subject: GOB: Show a mock-up of the Once Upon A Time title The actual intro is described in a SEQ file. We don't support those yet. --- engines/gob/pregob/onceupon/abracadabra.cpp | 2 +- engines/gob/pregob/onceupon/babayaga.cpp | 2 +- engines/gob/pregob/onceupon/onceupon.cpp | 87 +++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 7 +++ 4 files changed, 96 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index d8dd8b3be0..8ece3d1c27 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -61,7 +61,7 @@ void Abracadabra::run() { if (_vm->shouldQuit() || !correctCP) return; - warning("TODO: Abracadabra::run()"); + showTitle(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index aad1fc6aca..1eb603492b 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -61,7 +61,7 @@ void BabaYaga::run() { if (_vm->shouldQuit() || !correctCP) return; - warning("TODO: BabaYaga::run()"); + showTitle(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index aa85e1c095..a5d05ce8c3 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -30,6 +30,8 @@ #include "gob/anifile.h" #include "gob/aniobject.h" +#include "gob/sound/sound.h" + #include "gob/pregob/onceupon/onceupon.h" static const int kPaletteSize = 16; @@ -487,6 +489,91 @@ void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) ani.setPosition(); } +void OnceUpon::showTitle() { + // Show the Once Upon A Time title animation + // NOTE: This is currently only a mock-up. The real animation is in "ville.seq". + + fadeOut(); + setGamePalette(10); + + warning("OnceUpon::showTitle(): Actually play the SEQ"); + + clearScreen(); + + _vm->_video->drawPackedSprite("ville.cmp", *_vm->_draw->_backSurface); + _vm->_draw->forceBlit(); + + ANIFile ani (_vm, "pres.ani", 320); + ANIObject title(ani); + + setAnimState(title, 8, false, false); + + playTitleMusic(); + + while (!_vm->shouldQuit()) { + redrawAnim(title); + + fadeIn(); + + endFrame(true); + + if (hasInput()) + break; + } + + fadeOut(); + stopTitleMusic(); +} + +void OnceUpon::playTitleMusic() { + if (_vm->getPlatform() == Common::kPlatformPC) + playTitleMusicDOS(); + else if (_vm->getPlatform() == Common::kPlatformAmiga) + playTitleMusicAmiga(); + else if (_vm->getPlatform() == Common::kPlatformAtariST) + playTitleMusicAtariST(); +} + +void OnceUpon::playTitleMusicDOS() { + // Play an AdLib track + + _vm->_sound->adlibLoadTBR("babayaga.tbr"); + _vm->_sound->adlibLoadMDY("babayaga.mdy"); + _vm->_sound->adlibSetRepeating(-1); + _vm->_sound->adlibPlay(); +} + +void OnceUpon::playTitleMusicAmiga() { + // Play a Protracker track + + _vm->_sound->protrackerPlay("mod.babayaga"); +} + +void OnceUpon::playTitleMusicAtariST() { + // Play a Soundblaster composition + + static const int16 titleMusic[21] = { 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, -1}; + static const char * const titleFiles[ 3] = {"baba1.snd", "baba2.snd", "baba3.snd"}; + + for (uint i = 0; i < ARRAYSIZE(titleFiles); i++) + _vm->_sound->sampleLoad(_vm->_sound->sampleGetBySlot(i), SOUND_SND, titleFiles[i]); + + _vm->_sound->blasterPlayComposition(titleMusic, 0); + _vm->_sound->blasterRepeatComposition(-1); +} + +void OnceUpon::stopTitleMusic() { + _vm->_sound->adlibSetRepeating(0); + _vm->_sound->blasterRepeatComposition(0); + + _vm->_sound->adlibStop(); + _vm->_sound->blasterStopComposition(); + _vm->_sound->protrackerStop(); + + for (int i = 0; i < Sound::kSoundsCount; i++) + _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(i)); +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index abcde68b81..8b454e01f3 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -49,6 +49,8 @@ protected: bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + void showTitle(); + Font *_jeudak; Font *_lettre; @@ -65,6 +67,11 @@ private: int8 cpFindShape(int16 x, int16 y) const; void cpWrong(); + void playTitleMusic(); + void playTitleMusicDOS(); + void playTitleMusicAmiga(); + void playTitleMusicAtariST(); + void stopTitleMusic(); bool _openedArchives; }; -- cgit v1.2.3 From 9af01cd58417e796b82cf6bb36e1bd30b0875f0e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 6 Jul 2012 06:50:04 +0200 Subject: GOB: Move the background saving into its own class BackBuffer --- engines/gob/aniobject.cpp | 73 +++++++++------------------------ engines/gob/aniobject.h | 11 ++--- engines/gob/backbuffer.cpp | 100 +++++++++++++++++++++++++++++++++++++++++++++ engines/gob/backbuffer.h | 59 ++++++++++++++++++++++++++ engines/gob/module.mk | 1 + 5 files changed, 182 insertions(+), 62 deletions(-) create mode 100644 engines/gob/backbuffer.cpp create mode 100644 engines/gob/backbuffer.h (limited to 'engines/gob') diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index 8d739fb3a4..8d3a6897bf 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -28,23 +28,20 @@ namespace Gob { ANIObject::ANIObject(const ANIFile &ani) : _ani(&ani), _cmp(0), - _visible(false), _paused(false), _mode(kModeContinuous), - _x(0), _y(0), _background(0), _drawn(false) { + _visible(false), _paused(false), _mode(kModeContinuous), _x(0), _y(0) { setAnimation(0); setPosition(); } ANIObject::ANIObject(const CMPFile &cmp) : _ani(0), _cmp(&cmp), - _visible(false), _paused(false), _mode(kModeContinuous), - _x(0), _y(0), _background(0), _drawn(false) { + _visible(false), _paused(false), _mode(kModeContinuous), _x(0), _y(0) { setAnimation(0); setPosition(); } ANIObject::~ANIObject() { - delete _background; } void ANIObject::setVisible(bool visible) { @@ -188,46 +185,36 @@ bool ANIObject::draw(Surface &dest, int16 &left, int16 &top, bool ANIObject::drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { - if (!_background) { + if (!hasBuffer()) { uint16 width, height; _cmp->getMaxSize(width, height); - _background = new Surface(width, height, dest.getBPP()); + resizeBuffer(width, height); } - const uint16 cR = _cmp->getWidth (_animation) - 1; - const uint16 cB = _cmp->getHeight(_animation) - 1; + left = _x; + top = _y; + right = _x + _cmp->getWidth (_animation) - 1; + bottom = _y + _cmp->getHeight(_animation) - 1; - _backgroundLeft = CLIP( + _x, 0, dest.getWidth () - 1); - _backgroundTop = CLIP( + _y, 0, dest.getHeight() - 1); - _backgroundRight = CLIP(cR + _x, 0, dest.getWidth () - 1); - _backgroundBottom = CLIP(cB + _y, 0, dest.getHeight() - 1); - - _background->blit(dest, _backgroundLeft , _backgroundTop, - _backgroundRight, _backgroundBottom, 0, 0); + if (!saveScreen(dest, left, top, right, bottom)) + return false; _cmp->draw(dest, _animation, _x, _y, 0); - _drawn = true; - - left = _backgroundLeft; - top = _backgroundTop; - right = _backgroundRight; - bottom = _backgroundBottom; - return true; } bool ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { - if (!_background) { + if (!hasBuffer()) { uint16 width, height; _ani->getMaxSize(width, height); - _background = new Surface(width, height, dest.getBPP()); + resizeBuffer(width, height); } const ANIFile::Animation &animation = _ani->getAnimationInfo(_animation); @@ -236,45 +223,23 @@ bool ANIObject::drawANI(Surface &dest, int16 &left, int16 &top, const ANIFile::FrameArea &area = animation.frameAreas[_frame]; - _backgroundLeft = CLIP(area.left + _x, 0, dest.getWidth () - 1); - _backgroundTop = CLIP(area.top + _y, 0, dest.getHeight() - 1); - _backgroundRight = CLIP(area.right + _x, 0, dest.getWidth () - 1); - _backgroundBottom = CLIP(area.bottom + _y, 0, dest.getHeight() - 1); + left = _x + area.left; + top = _y + area.top; + right = _x + area.right; + bottom = _y + area.bottom; - _background->blit(dest, _backgroundLeft , _backgroundTop, - _backgroundRight, _backgroundBottom, 0, 0); + if (!saveScreen(dest, left, top, right, bottom)) + return false; _ani->draw(dest, _animation, _frame, _x, _y); - _drawn = true; - - left = _backgroundLeft; - top = _backgroundTop; - right = _backgroundRight; - bottom = _backgroundBottom; - return true; } bool ANIObject::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { - if (!_drawn) - return false; - - const int16 bgRight = _backgroundRight - _backgroundLeft; - const int16 bgBottom = _backgroundBottom - _backgroundTop; - - dest.blit(*_background, 0, 0, bgRight, bgBottom, _backgroundLeft, _backgroundTop); - - _drawn = false; - - left = _backgroundLeft; - top = _backgroundTop; - right = _backgroundRight; - bottom = _backgroundBottom; - - return true; + return restoreScreen(dest, left, top, right, bottom); } void ANIObject::advance() { diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index 00f42b43ce..3c374f7b8f 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -25,6 +25,8 @@ #include "common/system.h" +#include "gob/backbuffer.h" + namespace Gob { class ANIFile; @@ -32,7 +34,7 @@ class CMPFile; class Surface; /** An ANI object, controlling an animation within an ANI file. */ -class ANIObject { +class ANIObject : public BackBuffer { public: enum Mode { kModeContinuous, ///< Play the animation continuously. @@ -118,13 +120,6 @@ private: int16 _x; ///< The current X position. int16 _y; ///< The current Y position. - Surface *_background; ///< The saved background. - bool _drawn; ///< Was the animation drawn? - - int16 _backgroundLeft; ///< The left position of the saved background. - int16 _backgroundTop; ///< The top of the saved background. - int16 _backgroundRight; ///< The right position of the saved background. - int16 _backgroundBottom; ///< The bottom position of the saved background. bool drawCMP(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); bool drawANI(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); diff --git a/engines/gob/backbuffer.cpp b/engines/gob/backbuffer.cpp new file mode 100644 index 0000000000..752042d46e --- /dev/null +++ b/engines/gob/backbuffer.cpp @@ -0,0 +1,100 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/util.h" + +#include "gob/backbuffer.h" +#include "gob/surface.h" + +namespace Gob { + +BackBuffer::BackBuffer() : _background(0), _saved(false) { +} + +BackBuffer::~BackBuffer() { + delete _background; +} + +bool BackBuffer::hasBuffer() const { + return _background != 0; +} + +bool BackBuffer::hasSavedBackground() const { + return _saved; +} + +void BackBuffer::trashBuffer() { + _saved = false; +} + +void BackBuffer::resizeBuffer(uint16 width, uint16 height) { + trashBuffer(); + + if (_background && (_background->getWidth() == width) && (_background->getHeight() == height)) + return; + + delete _background; + + _background = new Surface(width, height, 1); +} + +bool BackBuffer::saveScreen(const Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + if (!_background) + return false; + + const int16 width = MIN(right - left + 1, _background->getWidth ()); + const int16 height = MIN(bottom - top + 1, _background->getHeight()); + if ((width <= 0) || (height <= 0)) + return false; + + right = left + width - 1; + bottom = top + height - 1; + + _saveLeft = left; + _saveTop = top; + _saveRight = right; + _saveBottom = bottom; + + _background->blit(dest, _saveLeft, _saveTop, _saveRight, _saveBottom, 0, 0); + + _saved = true; + + return true; +} + +bool BackBuffer::restoreScreen(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + if (!_saved) + return false; + + left = _saveLeft; + top = _saveTop; + right = _saveRight; + bottom = _saveBottom; + + dest.blit(*_background, 0, 0, right - left, bottom - top, left, top); + + _saved = false; + + return true; +} + +} // End of namespace Gob diff --git a/engines/gob/backbuffer.h b/engines/gob/backbuffer.h new file mode 100644 index 0000000000..c978689e9f --- /dev/null +++ b/engines/gob/backbuffer.h @@ -0,0 +1,59 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_BACKBUFFER_H +#define GOB_BACKBUFFER_H + +#include "common/system.h" + +namespace Gob { + +class Surface; + +class BackBuffer { +public: + BackBuffer(); + ~BackBuffer(); + +protected: + void trashBuffer(); + void resizeBuffer(uint16 width, uint16 height); + + bool saveScreen (const Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + bool restoreScreen( Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + + bool hasBuffer() const; + bool hasSavedBackground() const; + +private: + Surface *_background; ///< The saved background. + bool _saved; ///< Was the background saved? + + int16 _saveLeft; ///< The left position of the saved background. + int16 _saveTop; ///< The top of the saved background. + int16 _saveRight; ///< The right position of the saved background. + int16 _saveBottom; ///< The bottom position of the saved background. +}; + +} // End of namespace Gob + +#endif // GOB_BACKBUFFER_H diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 8a792049e8..2169602e1b 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -3,6 +3,7 @@ MODULE := engines/gob MODULE_OBJS := \ anifile.o \ aniobject.o \ + backbuffer.o \ cheater.o \ cheater_geisha.o \ cmpfile.o \ -- cgit v1.2.3 From 4b3aa88c8aaaec4f13435c46a7a3cf4ef00a08df Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 00:41:55 +0200 Subject: GOB: Add a simple class for PreGob TXT files --- engines/gob/module.mk | 1 + engines/gob/pregob/pregob.cpp | 13 +++ engines/gob/pregob/pregob.h | 4 + engines/gob/pregob/txtfile.cpp | 232 +++++++++++++++++++++++++++++++++++++++++ engines/gob/pregob/txtfile.h | 91 ++++++++++++++++ 5 files changed, 341 insertions(+) create mode 100644 engines/gob/pregob/txtfile.cpp create mode 100644 engines/gob/pregob/txtfile.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 2169602e1b..f8b477b92b 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -79,6 +79,7 @@ MODULE_OBJS := \ demos/batplayer.o \ detection/detection.o \ pregob/pregob.o \ + pregob/txtfile.o \ pregob/onceupon/onceupon.o \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index b9c36d7cf8..98b1a2e6b8 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -26,6 +26,7 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/surface.h" +#include "gob/dataio.h" #include "gob/palanim.h" #include "gob/draw.h" #include "gob/video.h" @@ -202,4 +203,16 @@ void PreGob::redrawAnim(ANIObject &ani) { drawAnim(ani); } +TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) const { + Common::SeekableReadStream *txtStream = _vm->_dataIO->getFile(txtFile); + if (!txtStream) + error("PreGob::loadTXT(): Failed to open \"%s\"", txtFile.c_str()); + + TXTFile *txt = new TXTFile(*txtStream, format); + + delete txtStream; + + return txt; +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 9efdbe8df6..d087bb0d0c 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -25,6 +25,8 @@ #include "gob/util.h" +#include "gob/pregob/txtfile.h" + namespace Gob { class GobEngine; @@ -77,6 +79,8 @@ protected: void drawAnim(ANIObject &ani); void redrawAnim(ANIObject &ani); + TXTFile *loadTXT(const Common::String &txtFile, TXTFile::Format format) const; + GobEngine *_vm; diff --git a/engines/gob/pregob/txtfile.cpp b/engines/gob/pregob/txtfile.cpp new file mode 100644 index 0000000000..3ff0d4b039 --- /dev/null +++ b/engines/gob/pregob/txtfile.cpp @@ -0,0 +1,232 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/stream.h" + +#include "gob/draw.h" + +#include "gob/pregob/txtfile.h" + +namespace Gob { + +TXTFile::TXTFile(Common::SeekableReadStream &txt, Format format) { + load(txt, format); +} + +TXTFile::~TXTFile() { +} + +TXTFile::LineArray &TXTFile::getLines() { + return _lines; +} + +void TXTFile::load(Common::SeekableReadStream &txt, Format format) { + if (format == kFormatStringPositionColorFont) { + int numLines = getInt(txt); + + _lines.reserve(numLines); + } + + while (!txt.eos()) { + Line line; + + line.text = getStr(txt); + line.x = (format >= kFormatStringPosition) ? getInt(txt) : 0; + line.y = (format >= kFormatStringPosition) ? getInt(txt) : 0; + line.color = (format >= kFormatStringPositionColor) ? getInt(txt) : 0; + line.font = (format >= kFormatStringPositionColorFont) ? getInt(txt) : 0; + + _lines.push_back(line); + } + + while (!_lines.empty() && _lines.back().text.empty()) + _lines.pop_back(); +} + +bool TXTFile::draw(Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount, int color) { + + trashBuffer(); + + if (!getArea(left, top, right, bottom, fonts, fontCount)) + return false; + + resizeBuffer(right - left + 1, bottom - top + 1); + saveScreen(surface, left, top, right, bottom); + + for (LineArray::const_iterator l = _lines.begin(); l != _lines.end(); ++l) { + if (l->font >= fontCount) + continue; + + fonts[l->font]->drawString(l->text, l->x, l->y, (color < 0) ? l->color : color, 0, true, surface); + } + + return true; +} + +bool TXTFile::draw(uint line, Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount, int color) { + + trashBuffer(); + + if (!getArea(line, left, top, right, bottom, fonts, fontCount)) + return false; + + resizeBuffer(right - left + 1, bottom - top + 1); + saveScreen(surface, left, top, right, bottom); + + const Line &l = _lines[line]; + + fonts[l.font]->drawString(l.text, l.x, l.y, (color < 0) ? l.color : color, 0, true, surface); + + return true; +} + +bool TXTFile::draw(Surface &surface, const Font * const *fonts, uint fontCount, int color) { + int16 left, top, right, bottom; + + return draw(surface, left, top, right, bottom, fonts, fontCount, color); +} + +bool TXTFile::draw(uint line, Surface &surface, const Font * const *fonts, uint fontCount, int color) { + int16 left, top, right, bottom; + + return draw(line, surface, left, top, right, bottom, fonts, fontCount, color); +} + +bool TXTFile::clear(Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom) { + return restoreScreen(surface, left, top, right, bottom); +} + +bool TXTFile::getArea(int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount) const { + + bool hasLine = false; + + left = 0x7FFF; + top = 0x7FFF; + right = 0x0000; + bottom = 0x0000; + + for (uint i = 0; i < _lines.size(); i++) { + int16 lLeft, lTop, lRight, lBottom; + + if (getArea(i, lLeft, lTop, lRight, lBottom, fonts, fontCount)) { + left = MIN(left , lLeft ); + top = MIN(top , lTop ); + right = MAX(right , lRight ); + bottom = MAX(bottom, lBottom); + + hasLine = true; + } + } + + return hasLine; +} + +bool TXTFile::getArea(uint line, int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount) const { + + + if ((line >= _lines.size()) || (_lines[line].font >= fontCount)) + return false; + + const Line &l = _lines[line]; + + left = l.x; + top = l.y; + right = l.x + l.text.size() * fonts[l.font]->getCharWidth() - 1; + bottom = l.y + fonts[l.font]->getCharHeight() - 1; + + return true; +} + +Common::String TXTFile::getStr(Common::SeekableReadStream &txt) { + // Skip all ' ', '\n' and '\r' + while (!txt.eos()) { + char c = txt.readByte(); + if (txt.eos()) + break; + + if ((c != ' ') && (c != '\n') && (c != '\r')) { + txt.seek(-1, SEEK_CUR); + break; + } + } + + if (txt.eos()) + return ""; + + // Read string until ' ', '\n' or '\r' + Common::String string; + while (!txt.eos()) { + char c = txt.readByte(); + if ((c == ' ') || (c == '\n') || (c == '\r')) + break; + + string += c; + } + + // Replace all '#' with ' ' and throw out non-printables + Common::String cleanString; + + for (uint i = 0; i < string.size(); i++) { + if (string[i] == '#') + cleanString += ' '; + else if ((unsigned char)string[i] >= ' ') + cleanString += string[i]; + } + + return cleanString; +} + +int TXTFile::getInt(Common::SeekableReadStream &txt) { + // Skip all [^-0-9] + while (!txt.eos()) { + char c = txt.readByte(); + if (txt.eos()) + break; + + if ((c == '-') || ((c >= '0') && (c <= '9'))) { + txt.seek(-1, SEEK_CUR); + break; + } + } + + if (txt.eos()) + return 0; + + // Read until [^-0-9] + Common::String string; + while (!txt.eos()) { + char c = txt.readByte(); + if ((c != '-') && ((c < '0') || (c > '9'))) + break; + + string += c; + } + + // Convert to integer + return atoi(string.c_str()); +} + +} // End of namespace Gob diff --git a/engines/gob/pregob/txtfile.h b/engines/gob/pregob/txtfile.h new file mode 100644 index 0000000000..c623b58859 --- /dev/null +++ b/engines/gob/pregob/txtfile.h @@ -0,0 +1,91 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_TXTFILE_H +#define GOB_PREGOB_TXTFILE_H + +#include "common/system.h" +#include "common/str.h" +#include "common/array.h" + +#include "gob/backbuffer.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Gob { + +class Surface; +class Font; + +class TXTFile : public BackBuffer { +public: + enum Format { + kFormatString, + kFormatStringPosition, + kFormatStringPositionColor, + kFormatStringPositionColorFont + }; + + struct Line { + Common::String text; + int x, y; + int color; + uint font; + }; + + typedef Common::Array LineArray; + + TXTFile(Common::SeekableReadStream &txt, Format format); + ~TXTFile(); + + LineArray &getLines(); + + bool draw( Surface &surface, const Font * const *fonts, uint fontCount, int color = -1); + bool draw(uint line, Surface &surface, const Font * const *fonts, uint fontCount, int color = -1); + + bool draw( Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount, int color = -1); + bool draw(uint line, Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount, int color = -1); + + bool clear(Surface &surface, int16 &left, int16 &top, int16 &right, int16 &bottom); + +private: + LineArray _lines; + + void load(Common::SeekableReadStream &txt, Format format); + + Common::String getStr(Common::SeekableReadStream &txt); + int getInt(Common::SeekableReadStream &txt); + + + bool getArea( int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount) const; + bool getArea(uint line, int16 &left, int16 &top, int16 &right, int16 &bottom, + const Font * const *fonts, uint fontCount) const; +}; + +} // End of namespace Gob + +#endif // GOB_PREGOB_TXTFILE_H -- cgit v1.2.3 From 139b03c4bcafea260e79e3e83db897c71db41907 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 01:23:21 +0200 Subject: GOB: Add a PreGob method to get a localized file name --- engines/gob/pregob/pregob.cpp | 9 +++++++++ engines/gob/pregob/pregob.h | 3 +++ 2 files changed, 12 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 98b1a2e6b8..582ebc6677 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -34,6 +34,8 @@ #include "gob/pregob/pregob.h" +static char kLanguageSuffix[5] = { 't', 'g', 'a', 'e', 'i' }; + namespace Gob { PreGob::PreGob(GobEngine *vm) : _vm(vm), _fadedOut(false) { @@ -203,6 +205,13 @@ void PreGob::redrawAnim(ANIObject &ani) { drawAnim(ani); } +Common::String PreGob::getLocFile(const Common::String &file) const { + if (_vm->_global->_language >= ARRAYSIZE(kLanguageSuffix)) + return file; + + return file + kLanguageSuffix[_vm->_global->_language]; +} + TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) const { Common::SeekableReadStream *txtStream = _vm->_dataIO->getFile(txtFile); if (!txtStream) diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index d087bb0d0c..902a7c437d 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -23,6 +23,8 @@ #ifndef GOB_PREGOB_PREGOB_H #define GOB_PREGOB_PREGOB_H +#include "common/str.h" + #include "gob/util.h" #include "gob/pregob/txtfile.h" @@ -79,6 +81,7 @@ protected: void drawAnim(ANIObject &ani); void redrawAnim(ANIObject &ani); + Common::String getLocFile(const Common::String &file) const; TXTFile *loadTXT(const Common::String &txtFile, TXTFile::Format format) const; -- cgit v1.2.3 From 60cebba95ca1d30f2926acd2d415d09c75e2bd42 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 02:33:12 +0200 Subject: GOB: Show the Once Upon A Time wait/load screen --- engines/gob/pregob/onceupon/abracadabra.cpp | 4 ++++ engines/gob/pregob/onceupon/babayaga.cpp | 4 ++++ engines/gob/pregob/onceupon/onceupon.cpp | 17 +++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 1 + 4 files changed, 26 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 8ece3d1c27..27845cd1d5 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -61,6 +61,10 @@ void Abracadabra::run() { if (_vm->shouldQuit() || !correctCP) return; + showWait(); + if (_vm->shouldQuit()) + return; + showTitle(); } diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 1eb603492b..1dbda8227b 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -61,6 +61,10 @@ void BabaYaga::run() { if (_vm->shouldQuit() || !correctCP) return; + showWait(); + if (_vm->shouldQuit()) + return; + showTitle(); } diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index a5d05ce8c3..6f5d95b10c 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -489,6 +489,23 @@ void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) ani.setPosition(); } +void OnceUpon::showWait() { + // Show the loading floppy + + fadeOut(); + clearScreen(); + setGamePalette(10); + + Surface wait(320, 43, 1); + + _vm->_video->drawPackedSprite("wait.cmp", wait); + _vm->_draw->_backSurface->blit(wait, 0, 0, 72, 33, 122, 84); + + _vm->_draw->forceBlit(); + + fadeIn(); +} + void OnceUpon::showTitle() { // Show the Once Upon A Time title animation // NOTE: This is currently only a mock-up. The real animation is in "ville.seq". diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 8b454e01f3..99fb51431a 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -49,6 +49,7 @@ protected: bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + void showWait(); void showTitle(); -- cgit v1.2.3 From 2f3aaf0e07a7309b2ba74c7e888b03c24534d4d0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 02:35:26 +0200 Subject: GOB: Show the Once Upon A Time fairytale quote --- engines/gob/pregob/onceupon/abracadabra.cpp | 4 ++++ engines/gob/pregob/onceupon/babayaga.cpp | 4 ++++ engines/gob/pregob/onceupon/onceupon.cpp | 22 ++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 1 + 4 files changed, 31 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 27845cd1d5..abf9fdce61 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -65,6 +65,10 @@ void Abracadabra::run() { if (_vm->shouldQuit()) return; + showQuote(); + if (_vm->shouldQuit()) + return; + showTitle(); } diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 1dbda8227b..9bca0e27d0 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -65,6 +65,10 @@ void BabaYaga::run() { if (_vm->shouldQuit()) return; + showQuote(); + if (_vm->shouldQuit()) + return; + showTitle(); } diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 6f5d95b10c..73322658de 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -506,6 +506,28 @@ void OnceUpon::showWait() { fadeIn(); } +void OnceUpon::showQuote() { + // Show the quote about fairytales + + fadeOut(); + clearScreen(); + setGamePalette(11); + + static const Font *fonts[3] = { _plettre, _glettre, _plettre }; + + TXTFile *quote = loadTXT(getLocFile("gene.tx"), TXTFile::kFormatStringPositionColorFont); + quote->draw(*_vm->_draw->_backSurface, fonts, ARRAYSIZE(fonts)); + delete quote; + + _vm->_draw->forceBlit(); + + fadeIn(); + + waitInput(); + + fadeOut(); +} + void OnceUpon::showTitle() { // Show the Once Upon A Time title animation // NOTE: This is currently only a mock-up. The real animation is in "ville.seq". diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 99fb51431a..97f7e6b77e 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -50,6 +50,7 @@ protected: bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); void showWait(); + void showQuote(); void showTitle(); -- cgit v1.2.3 From 92bd9c864ab5238aa51ad6a327cfb7249bcc934f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 03:04:29 +0200 Subject: GOB: Show the specific game title in Once Upon A Time --- engines/gob/pregob/onceupon/abracadabra.cpp | 14 ++++++++++++++ engines/gob/pregob/onceupon/babayaga.cpp | 14 ++++++++++++++ engines/gob/pregob/onceupon/onceupon.cpp | 27 +++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 1 + 4 files changed, 56 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index abf9fdce61..5c1bd0149b 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -57,19 +57,33 @@ Abracadabra::~Abracadabra() { void Abracadabra::run() { init(); + // Copy protection bool correctCP = doCopyProtection(kCopyProtectionColors, kCopyProtectionShapes, kCopyProtectionObfuscate); if (_vm->shouldQuit() || !correctCP) return; + // "Loading" showWait(); if (_vm->shouldQuit()) return; + // Quote about fairy tales showQuote(); if (_vm->shouldQuit()) return; + // Once Upon A Time title showTitle(); + if (_vm->shouldQuit()) + return; + + // Game title screen + showChapter(0); + if (_vm->shouldQuit()) + return; + + // "Loading" + showWait(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 9bca0e27d0..608d85e977 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -57,19 +57,33 @@ BabaYaga::~BabaYaga() { void BabaYaga::run() { init(); + // Copy protection bool correctCP = doCopyProtection(kCopyProtectionColors, kCopyProtectionShapes, kCopyProtectionObfuscate); if (_vm->shouldQuit() || !correctCP) return; + // "Loading" showWait(); if (_vm->shouldQuit()) return; + // Quote about fairy tales showQuote(); if (_vm->shouldQuit()) return; + // Once Upon A Time title showTitle(); + if (_vm->shouldQuit()) + return; + + // Game title screen + showChapter(0); + if (_vm->shouldQuit()) + return; + + // "Loading" + showWait(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 73322658de..6d185d007d 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -613,6 +613,33 @@ void OnceUpon::stopTitleMusic() { _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(i)); } +void OnceUpon::showChapter(int chapter) { + // Display the intro text to a chapter + + fadeOut(); + clearScreen(); + setGamePalette(11); + + // Parchment background + _vm->_video->drawPackedSprite("parch.cmp", *_vm->_draw->_backSurface); + + static const Font *fonts[3] = { _plettre, _glettre, _plettre }; + + const Common::String chapterFile = getLocFile(Common::String::format("gene%d.tx", chapter)); + + TXTFile *gameTitle = loadTXT(chapterFile, TXTFile::kFormatStringPositionColorFont); + gameTitle->draw(*_vm->_draw->_backSurface, fonts, ARRAYSIZE(fonts)); + delete gameTitle; + + _vm->_draw->forceBlit(); + + fadeIn(); + + waitInput(); + + fadeOut(); +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 97f7e6b77e..96f88cbb5f 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -52,6 +52,7 @@ protected: void showWait(); void showQuote(); void showTitle(); + void showChapter(int chapter); Font *_jeudak; -- cgit v1.2.3 From bccfdb559fccdf3eff86cea22495a50260b3ad90 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 16:30:02 +0200 Subject: GOB: Move the intro parts into OnceUpon::showIntro() --- engines/gob/pregob/onceupon/abracadabra.cpp | 24 ++---------------------- engines/gob/pregob/onceupon/babayaga.cpp | 24 ++---------------------- engines/gob/pregob/onceupon/onceupon.cpp | 27 +++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 15 +++++++++++---- 4 files changed, 42 insertions(+), 48 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 5c1bd0149b..9db018c4aa 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -62,28 +62,8 @@ void Abracadabra::run() { if (_vm->shouldQuit() || !correctCP) return; - // "Loading" - showWait(); - if (_vm->shouldQuit()) - return; - - // Quote about fairy tales - showQuote(); - if (_vm->shouldQuit()) - return; - - // Once Upon A Time title - showTitle(); - if (_vm->shouldQuit()) - return; - - // Game title screen - showChapter(0); - if (_vm->shouldQuit()) - return; - - // "Loading" - showWait(); + // Show the intro + showIntro(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 608d85e977..8b80a38084 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -62,28 +62,8 @@ void BabaYaga::run() { if (_vm->shouldQuit() || !correctCP) return; - // "Loading" - showWait(); - if (_vm->shouldQuit()) - return; - - // Quote about fairy tales - showQuote(); - if (_vm->shouldQuit()) - return; - - // Once Upon A Time title - showTitle(); - if (_vm->shouldQuit()) - return; - - // Game title screen - showChapter(0); - if (_vm->shouldQuit()) - return; - - // "Loading" - showWait(); + // Show the intro + showIntro(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 6d185d007d..f2708b380b 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -506,6 +506,33 @@ void OnceUpon::showWait() { fadeIn(); } +void OnceUpon::showIntro() { + // Show all intro parts + + // "Loading" + showWait(); + if (_vm->shouldQuit()) + return; + + // Quote about fairy tales + showQuote(); + if (_vm->shouldQuit()) + return; + + // Once Upon A Time title + showTitle(); + if (_vm->shouldQuit()) + return; + + // Game title screen + showChapter(0); + if (_vm->shouldQuit()) + return; + + // "Loading" + showWait(); +} + void OnceUpon::showQuote() { // Show the quote about fairytales diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 96f88cbb5f..968c70ef48 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -49,12 +49,13 @@ protected: bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); - void showWait(); - void showQuote(); - void showTitle(); - void showChapter(int chapter); + void showWait(); ///< Show the wait / loading screen. + void showIntro(); ///< Show the whole intro. + void showChapter(int chapter); ///< Show a chapter intro text. + + // Fonts Font *_jeudak; Font *_lettre; Font *_plettre; @@ -70,12 +71,18 @@ private: int8 cpFindShape(int16 x, int16 y) const; void cpWrong(); + // Intro parts + void showQuote(); + void showTitle(); + + // Title music void playTitleMusic(); void playTitleMusicDOS(); void playTitleMusicAmiga(); void playTitleMusicAtariST(); void stopTitleMusic(); + bool _openedArchives; }; -- cgit v1.2.3 From 233a3f54fc3913669fd4c56a6c3a16da5aa5f5b6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 30 Jun 2012 22:12:08 +0200 Subject: GOB: Stubbily implement the Once Upon A Time menus --- engines/gob/pregob/onceupon/abracadabra.cpp | 31 +++ engines/gob/pregob/onceupon/abracadabra.h | 6 + engines/gob/pregob/onceupon/babayaga.cpp | 31 +++ engines/gob/pregob/onceupon/babayaga.h | 6 + engines/gob/pregob/onceupon/onceupon.cpp | 403 +++++++++++++++++++++++++++- engines/gob/pregob/onceupon/onceupon.h | 71 ++++- 6 files changed, 541 insertions(+), 7 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 9db018c4aa..696e4d9594 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -48,7 +48,13 @@ namespace Gob { namespace OnceUpon { +const OnceUpon::MenuButton Abracadabra::kAnimalsButtons = { + true, 131, 127, 183, 164, 193, 0, 243, 35, 132, 128, 0 +}; + + Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) { + setAnimalsButton(&kAnimalsButtons); } Abracadabra::~Abracadabra() { @@ -64,6 +70,31 @@ void Abracadabra::run() { // Show the intro showIntro(); + if (_vm->shouldQuit()) + return; + + mainLoop(); + + if (!_vm->shouldQuit()) + warning("Abracadabra::run(): TODO: Show \"Bye Bye\""); +} + +void Abracadabra::mainLoop() { + clearScreen(); + + MenuType mainMenu = kMenuTypeMainStart; + + while (!_vm->shouldQuit()) { + MenuAction action = doMenu(mainMenu); + if (action == kMenuActionPlay) + warning("Abracadabra::mainLoop(): TODO: Play"); + else if (action == kMenuActionRestart) + warning("Abracadabra::mainLoop(): TODO: Restart"); + else if (action == kMenuActionAnimals) + warning("Abracadabra::mainLoop(): TODO: Animals"); + else if (action == kMenuActionQuit) + break; + } } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h index 855d2bf131..64deaf4389 100644 --- a/engines/gob/pregob/onceupon/abracadabra.h +++ b/engines/gob/pregob/onceupon/abracadabra.h @@ -35,6 +35,12 @@ public: ~Abracadabra(); void run(); + +private: + static const MenuButton kAnimalsButtons; + + + void mainLoop(); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 8b80a38084..b752bb0862 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -48,7 +48,13 @@ namespace Gob { namespace OnceUpon { +const OnceUpon::MenuButton BabaYaga::kAnimalsButtons = { + true, 131, 127, 183, 164, 193, 0, 245, 37, 131, 127, 0 +}; + + BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) { + setAnimalsButton(&kAnimalsButtons); } BabaYaga::~BabaYaga() { @@ -64,6 +70,31 @@ void BabaYaga::run() { // Show the intro showIntro(); + if (_vm->shouldQuit()) + return; + + mainLoop(); + + if (!_vm->shouldQuit()) + warning("BabaYaga::run(): TODO: Show \"Bye Bye\""); +} + +void BabaYaga::mainLoop() { + clearScreen(); + + MenuType mainMenu = kMenuTypeMainStart; + + while (!_vm->shouldQuit()) { + MenuAction action = doMenu(mainMenu); + if (action == kMenuActionPlay) + warning("BabaYaga::mainLoop(): TODO: Play"); + else if (action == kMenuActionRestart) + warning("BabaYaga::mainLoop(): TODO: Restart"); + else if (action == kMenuActionAnimals) + warning("BabaYaga::mainLoop(): TODO: Animals"); + else if (action == kMenuActionQuit) + break; + } } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h index b3339b0ca8..98d452418f 100644 --- a/engines/gob/pregob/onceupon/babayaga.h +++ b/engines/gob/pregob/onceupon/babayaga.h @@ -35,6 +35,12 @@ public: ~BabaYaga(); void run(); + +private: + static const MenuButton kAnimalsButtons; + + + void mainLoop(); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index f2708b380b..67004d2912 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -227,8 +227,28 @@ namespace Gob { namespace OnceUpon { +const OnceUpon::MenuButton OnceUpon::kMainMenuDifficultyButton[3] = { + {false, 29, 18, 77, 57, 0, 0, 0, 0, 0, 0, 0}, + {false, 133, 18, 181, 57, 0, 0, 0, 0, 0, 0, 1}, + {false, 241, 18, 289, 57, 0, 0, 0, 0, 0, 0, 2}, +}; + +const OnceUpon::MenuButton OnceUpon::kSectionButtons[4] = { + {false, 27, 121, 91, 179, 0, 0, 0, 0, 0, 0, 0}, + { true, 95, 121, 159, 179, 4, 1, 56, 49, 100, 126, 2}, + { true, 163, 121, 227, 179, 64, 1, 120, 49, 168, 126, 6}, + { true, 231, 121, 295, 179, 128, 1, 184, 49, 236, 126, 10} +}; + +const OnceUpon::MenuButton OnceUpon::kIngameButtons[3] = { + {true, 108, 83, 139, 116, 0, 0, 31, 34, 108, 83, 0}, + {true, 144, 83, 175, 116, 36, 0, 67, 34, 144, 83, 1}, + {true, 180, 83, 211, 116, 72, 0, 103, 34, 180, 83, 2} +}; + + OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _jeudak(0), _lettre(0), _plettre(0), _glettre(0), - _openedArchives(false) { + _openedArchives(false), _animalsButton(0) { } @@ -267,6 +287,9 @@ void OnceUpon::init() { "Thanks", _vm->getLangDesc(_vm->_global->_language)); initScreen(); + + _difficulty = kDifficultyMAX; + _section = 0; } void OnceUpon::deinit() { @@ -289,6 +312,10 @@ void OnceUpon::deinit() { _openedArchives = false; } +void OnceUpon::setAnimalsButton(const MenuButton *animalsButton) { + _animalsButton = animalsButton; +} + void OnceUpon::setCopyProtectionPalette() { setPalette(kCopyProtectionPalette, kPaletteSize); } @@ -300,6 +327,14 @@ void OnceUpon::setGamePalette(uint palette) { setPalette(kGamePalettes[palette], kPaletteSize); } +void OnceUpon::setGameCursor() { + Surface cursor(320, 16, 1); + + _vm->_video->drawPackedSprite("icon.cmp", cursor); + + setCursor(cursor, 105, 0, 120, 15, 0, 0); +} + enum CopyProtectionState { kCPStateSetup, // Set up the screen kCPStateWaitUser, // Waiting for the user to pick a shape @@ -489,12 +524,12 @@ void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) ani.setPosition(); } -void OnceUpon::showWait() { +void OnceUpon::showWait(uint palette) { // Show the loading floppy fadeOut(); clearScreen(); - setGamePalette(10); + setGamePalette(palette); Surface wait(320, 43, 1); @@ -510,7 +545,7 @@ void OnceUpon::showIntro() { // Show all intro parts // "Loading" - showWait(); + showWait(10); if (_vm->shouldQuit()) return; @@ -530,7 +565,7 @@ void OnceUpon::showIntro() { return; // "Loading" - showWait(); + showWait(17); } void OnceUpon::showQuote() { @@ -667,6 +702,364 @@ void OnceUpon::showChapter(int chapter) { fadeOut(); } +OnceUpon::MenuAction OnceUpon::doMenu(MenuType type) { + bool cursorVisible = isCursorVisible(); + + // Set the cursor + addCursor(); + setGameCursor(); + + // Backup the screen + Surface screenBackup(320, 200, 1); + screenBackup.blit(*_vm->_draw->_backSurface); + + // Handle the specific menu + MenuAction action; + if (type == kMenuTypeMainStart) + action = doMenuMainStart(); + else if (type == kMenuTypeMainIngame) + action = doMenuMainIngame(); + else if (type == kMenuTypeIngame) + action = doMenuIngame(); + else + error("OnceUpon::doMenu(): No such menu %d", type); + + if (_vm->shouldQuit()) + return action; + + // The ingame menu cleans itself up in a special way + if (type == kMenuTypeIngame) + clearMenuIngame(screenBackup); + + // The main menus fade out + if ((type == kMenuTypeMainStart) || (type == kMenuTypeMainIngame)) + fadeOut(); + + // Restore the screen + _vm->_draw->_backSurface->blit(screenBackup); + _vm->_draw->forceBlit(); + + // Restore the cursor + if (!cursorVisible) + hideCursor(); + removeCursor(); + + return action; +} + +OnceUpon::MenuAction OnceUpon::doMenuMainStart() { + fadeOut(); + drawMenuMainStart(); + showCursor(); + fadeIn(); + + MenuAction action = kMenuActionNone; + while (!_vm->shouldQuit() && (action == kMenuActionNone)) { + endFrame(true); + + // Check user input + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + if (key == kKeyEscape) + // ESC -> Quit + return kMenuActionQuit; + + if (mouseButtons != kMouseButtonsLeft) + continue; + + // If we clicked on a difficulty button, show the selected difficulty and start the game + Difficulty difficulty = checkDifficultyButton(mouseX, mouseY); + if (difficulty < kDifficultyMAX) { + _difficulty = difficulty; + action = kMenuActionPlay; + + drawMenuMainStart(); + _vm->_util->longDelay(1000); + } + + if (checkAnimalsButton(mouseX, mouseY)) + action = kMenuActionAnimals; + + } + + return action; +} + +OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { + fadeOut(); + drawMenuMainIngame(); + showCursor(); + fadeIn(); + + MenuAction action = kMenuActionNone; + while (!_vm->shouldQuit() && (action == kMenuActionNone)) { + endFrame(true); + + // Check user input + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + if (key == kKeyEscape) + // ESC -> Quit + return kMenuActionQuit; + + if (mouseButtons != kMouseButtonsLeft) + continue; + + // If we clicked on a difficulty button, change the current difficulty level + Difficulty difficulty = checkDifficultyButton(mouseX, mouseY); + if ((difficulty < kDifficultyMAX) && (_difficulty != difficulty)) { + _difficulty = difficulty; + + drawMenuMainIngame(); + } + + // If we clicked on a section button, restart the game from this section + int8 section = checkSectionButton(mouseX, mouseY); + if (section >= 0) { + _section = section; + action = kMenuActionRestart; + } + + } + + return action; +} + +OnceUpon::MenuAction OnceUpon::doMenuIngame() { + drawMenuIngame(); + showCursor(); + + MenuAction action = kMenuActionNone; + while (!_vm->shouldQuit() && (action == kMenuActionNone)) { + endFrame(true); + + // Check user input + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + if ((key == kKeyEscape) || (mouseButtons == kMouseButtonsRight)) + // ESC or right mouse button -> Dismiss the menu + action = kMenuActionPlay; + + if (mouseButtons != kMouseButtonsLeft) + continue; + + // Check if we've pressed one of the buttons + int8 button = checkIngameButton(mouseX, mouseY); + if (button == 0) + action = kMenuActionQuit; + else if (button == 1) + action = kMenuActionMainMenu; + else if (button == 2) + action = kMenuActionPlay; + + } + + return action; +} + +void OnceUpon::drawMenuMainStart() { + // Draw the background + _vm->_video->drawPackedSprite("menu2.cmp", *_vm->_draw->_backSurface); + + // Draw the "Listen to animal names" button + if (_animalsButton) { + Surface elements(320, 38, 1); + _vm->_video->drawPackedSprite("elemenu.cmp", elements); + _vm->_draw->_backSurface->fillRect(_animalsButton->left , _animalsButton->top, + _animalsButton->right, _animalsButton->bottom, 0); + _vm->_draw->_backSurface->blit(elements, + _animalsButton->srcLeft , _animalsButton->srcTop, + _animalsButton->srcRight, _animalsButton->srcBottom, + _animalsButton->dstX , _animalsButton->dstY); + } + + // Highlight the current difficulty + drawMenuDifficulty(); + + _vm->_draw->forceBlit(); +} + +void OnceUpon::drawMenuMainIngame() { + // Draw the background + _vm->_video->drawPackedSprite("menu.cmp", *_vm->_draw->_backSurface); + + // Highlight the current difficulty + drawMenuDifficulty(); + + // Draw the section buttons + Surface elements(320, 200, 1); + _vm->_video->drawPackedSprite("elemenu.cmp", elements); + + for (uint i = 0; i < ARRAYSIZE(kSectionButtons); i++) { + const MenuButton &button = kSectionButtons[i]; + + if (!button.needDraw) + continue; + + if (_section >= (uint)button.id) + _vm->_draw->_backSurface->blit(elements, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom, + button.dstX, button.dstY); + } + + _vm->_draw->forceBlit(); +} + +void OnceUpon::drawMenuIngame() { + Surface menu(320, 34, 1); + _vm->_video->drawPackedSprite("icon.cmp", menu); + + // Draw the menu in a special way + for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) { + const MenuButton &button = kIngameButtons[i]; + + drawLineByLine(menu, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom, + button.dstX, button.dstY); + } + + _vm->_draw->forceBlit(); + _vm->_video->retrace(); +} + +void OnceUpon::drawMenuDifficulty() { + if (_difficulty == kDifficultyMAX) + return; + + TXTFile *difficulties = loadTXT(getLocFile("diffic.tx"), TXTFile::kFormatStringPositionColor); + + // Draw the difficulty name + difficulties->draw((uint) _difficulty, *_vm->_draw->_backSurface, &_plettre, 1); + + // Draw a border around the current difficulty + _vm->_draw->_backSurface->drawRect(kMainMenuDifficultyButton[_difficulty].left, + kMainMenuDifficultyButton[_difficulty].top, + kMainMenuDifficultyButton[_difficulty].right, + kMainMenuDifficultyButton[_difficulty].bottom, + difficulties->getLines()[_difficulty].color); + + delete difficulties; +} + +void OnceUpon::clearMenuIngame(const Surface &background) { + // Find the area encompassing the whole ingame menu + + int16 left = 0x7FFF; + int16 top = 0x7FFF; + int16 right = 0x0000; + int16 bottom = 0x0000; + + for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) { + const MenuButton &button = kIngameButtons[i]; + + if (!button.needDraw) + continue; + + left = MIN(left , button.dstX); + top = MIN(top , button.dstY); + right = MAX(right , button.dstX + (button.srcRight - button.srcLeft + 1) - 1); + bottom = MAX(bottom, button.dstY + (button.srcBottom - button.srcTop + 1) - 1); + } + + if ((left > right) || (top > bottom)) + return; + + // Clear it line by line + drawLineByLine(background, left, top, right, bottom, left, top); +} + +OnceUpon::Difficulty OnceUpon::checkDifficultyButton(int16 x, int16 y) const { + for (uint i = 0; i < ARRAYSIZE(kMainMenuDifficultyButton); i++) { + const MenuButton &button = kMainMenuDifficultyButton[i]; + + if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom)) + return (Difficulty) button.id; + } + + return kDifficultyMAX; +} + +bool OnceUpon::checkAnimalsButton(int16 x, int16 y) const { + if (!_animalsButton) + return false; + + return (x >= _animalsButton->left) && (x <= _animalsButton->right) && + (y >= _animalsButton->top) && (y <= _animalsButton->bottom); +} + +int8 OnceUpon::checkSectionButton(int16 x, int16 y) const { + for (uint i = 0; i < ARRAYSIZE(kSectionButtons); i++) { + const MenuButton &button = kSectionButtons[i]; + + if ((uint)button.id > _section) + continue; + + if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom)) + return (int8)button.id; + } + + return -1; +} + +int8 OnceUpon::checkIngameButton(int16 x, int16 y) const { + for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) { + const MenuButton &button = kIngameButtons[i]; + + if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom)) + return (int8)button.id; + } + + return -1; +} + +void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y) const { + + // A special way of drawing something: + // Draw every other line "downwards", wait a bit after each line + // Then, draw the remaining lines "upwards" and again wait a bit after each line. + + if (_vm->shouldQuit()) + return; + + const int16 width = right - left + 1; + const int16 height = bottom - top + 1; + + if ((width <= 0) || (height <= 0)) + return; + + for (int16 i = 0; i < height; i += 2) { + if (_vm->shouldQuit()) + return; + + _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); + _vm->_draw->blitInvalidated(); + + _vm->_util->longDelay(1); + } + + for (int16 i = (height & 1) ? height : (height - 1); i >= 0; i -= 2) { + if (_vm->shouldQuit()) + return; + + _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); + _vm->_draw->blitInvalidated(); + + _vm->_util->longDelay(1); + } +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 968c70ef48..640e61383d 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -42,18 +42,59 @@ public: ~OnceUpon(); protected: + enum MenuType { + kMenuTypeMainStart = 0, ///< The big main menu at game start. + kMenuTypeMainIngame, ///< The big main menu during the game. + kMenuTypeIngame ///< The small popup menu during the game. + }; + + enum MenuAction { + kMenuActionNone = 0, ///< No action. + kMenuActionAnimals , ///< Do the animal names. + kMenuActionPlay , ///< Play the game. + kMenuActionRestart , ///< Restart the section. + kMenuActionMainMenu, ///< Go to the main menu. + kMenuActionQuit ///< Quit the game. + }; + + enum Difficulty { + kDifficultyBeginner = 0, + kDifficultyIntermediate = 1, + kDifficultyAdvanced = 2, + kDifficultyMAX + }; + + struct MenuButton { + bool needDraw; + int16 left, top, right, bottom; + int16 srcLeft, srcTop, srcRight, srcBottom; + int16 dstX, dstY; + int id; + }; + + static const uint kSectionCount = 15; + + void init(); void deinit(); + void setAnimalsButton(const MenuButton *animalsButton); + void setGamePalette(uint palette); + void setGameCursor(); bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); - void showWait(); ///< Show the wait / loading screen. - void showIntro(); ///< Show the whole intro. + void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen. + void showIntro(); ///< Show the whole intro. void showChapter(int chapter); ///< Show a chapter intro text. + MenuAction doMenu(MenuType type); + + void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y) const; + // Fonts Font *_jeudak; @@ -61,7 +102,14 @@ protected: Font *_plettre; Font *_glettre; + Difficulty _difficulty; + uint8 _section; + private: + static const MenuButton kMainMenuDifficultyButton[3]; + static const MenuButton kSectionButtons[4]; + static const MenuButton kIngameButtons[3]; + void setCopyProtectionPalette(); void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; @@ -82,8 +130,27 @@ private: void playTitleMusicAtariST(); void stopTitleMusic(); + // Menu helpers + MenuAction doMenuMainStart(); + MenuAction doMenuMainIngame(); + MenuAction doMenuIngame(); + + void drawMenuMainStart(); + void drawMenuMainIngame(); + void drawMenuIngame(); + void drawMenuDifficulty(); + + void clearMenuIngame(const Surface &background); + + Difficulty checkDifficultyButton(int16 x, int16 y) const; + bool checkAnimalsButton (int16 x, int16 y) const; + int8 checkSectionButton (int16 x, int16 y) const; + int8 checkIngameButton (int16 x, int16 y) const; + bool _openedArchives; + + const MenuButton *_animalsButton; }; } // End of namespace OnceUpon -- cgit v1.2.3 From 34cf81a4b614dee5f2657bf24d9f867165e6ced9 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 1 Jul 2012 03:45:09 +0200 Subject: GOB: Add some PreGob sound utility functions --- engines/gob/pregob/onceupon/onceupon.cpp | 10 ++++++++- engines/gob/pregob/onceupon/onceupon.h | 8 ++++++++ engines/gob/pregob/pregob.cpp | 35 ++++++++++++++++++++++++++++++++ engines/gob/pregob/pregob.h | 11 ++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 67004d2912..ad6befaea2 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -246,6 +246,10 @@ const OnceUpon::MenuButton OnceUpon::kIngameButtons[3] = { {true, 180, 83, 211, 116, 72, 0, 103, 34, 180, 83, 2} }; +const char *OnceUpon::kSound[kSoundMAX] = { + "diamant.snd" +}; + OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _jeudak(0), _lettre(0), _plettre(0), _glettre(0), _openedArchives(false), _animalsButton(0) { @@ -286,6 +290,8 @@ void OnceUpon::init() { "please contact the ScummVM team with details about this version.\n" "Thanks", _vm->getLangDesc(_vm->_global->_language)); + loadSounds(kSound, kSoundMAX); + initScreen(); _difficulty = kDifficultyMAX; @@ -293,6 +299,8 @@ void OnceUpon::init() { } void OnceUpon::deinit() { + freeSounds(); + delete _jeudak; delete _lettre; delete _plettre; @@ -671,7 +679,7 @@ void OnceUpon::stopTitleMusic() { _vm->_sound->blasterStopComposition(); _vm->_sound->protrackerStop(); - for (int i = 0; i < Sound::kSoundsCount; i++) + for (int i = 0; i < ::Gob::Sound::kSoundsCount; i++) _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(i)); } diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 640e61383d..9ad563903e 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -64,6 +64,11 @@ protected: kDifficultyMAX }; + enum Sound { + kSoundClick = 0, + kSoundMAX + }; + struct MenuButton { bool needDraw; int16 left, top, right, bottom; @@ -110,6 +115,9 @@ private: static const MenuButton kSectionButtons[4]; static const MenuButton kIngameButtons[3]; + static const char *kSound[kSoundMAX]; + + void setCopyProtectionPalette(); void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 582ebc6677..9c6cfb717a 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -32,6 +32,8 @@ #include "gob/video.h" #include "gob/aniobject.h" +#include "gob/sound/sound.h" + #include "gob/pregob/pregob.h" static char kLanguageSuffix[5] = { 't', 'g', 'a', 'e', 'i' }; @@ -141,6 +143,39 @@ bool PreGob::isCursorVisible() const { return CursorMan.isVisible(); } +void PreGob::loadSounds(const char * const *sounds, uint soundCount) { + freeSounds(); + + _sounds.resize(soundCount); + + for (uint i = 0; i < soundCount; i++) { + int32 size; + byte *data = _vm->_dataIO->getFile(sounds[i], size); + + if (!data || !_sounds[i].load(SOUND_SND, data, size)) { + delete data; + + warning("PreGob::loadSounds(): Failed to load sound \"%s\"", sounds[i]); + continue; + } + } +} + +void PreGob::freeSounds() { + _sounds.clear(); +} + +void PreGob::playSound(uint sound, int16 frequency, int16 repCount) { + if (sound >= _sounds.size()) + return; + + _vm->_sound->blasterPlay(&_sounds[sound], repCount, frequency); +} + +void PreGob::stopSound() { + _vm->_sound->blasterStop(0); +} + void PreGob::endFrame(bool doInput) { _vm->_draw->blitInvalidated(); _vm->_util->waitEndFrame(); diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 902a7c437d..b91758876e 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -24,9 +24,12 @@ #define GOB_PREGOB_PREGOB_H #include "common/str.h" +#include "common/array.h" #include "gob/util.h" +#include "gob/sound/sounddesc.h" + #include "gob/pregob/txtfile.h" namespace Gob { @@ -70,6 +73,12 @@ protected: bool isCursorVisible() const; + void loadSounds(const char * const *sounds, uint soundCount); + void freeSounds(); + + void playSound(uint sound, int16 frequency = 0, int16 repCount = 0); + void stopSound(); + void endFrame(bool doInput); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); @@ -89,6 +98,8 @@ protected: private: bool _fadedOut; ///< Did we fade out? + + Common::Array _sounds; }; } // End of namespace Gob -- cgit v1.2.3 From a98ba5f038c536a2b492b816433f4283e9d1ae26 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 1 Jul 2012 03:47:27 +0200 Subject: GOB: Play a click sound in the Once Upon A Time menus --- engines/gob/pregob/onceupon/onceupon.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index ad6befaea2..49516a55c7 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -778,6 +778,8 @@ OnceUpon::MenuAction OnceUpon::doMenuMainStart() { if (mouseButtons != kMouseButtonsLeft) continue; + playSound(kSoundClick); + // If we clicked on a difficulty button, show the selected difficulty and start the game Difficulty difficulty = checkDifficultyButton(mouseX, mouseY); if (difficulty < kDifficultyMAX) { @@ -819,6 +821,8 @@ OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { if (mouseButtons != kMouseButtonsLeft) continue; + playSound(kSoundClick); + // If we clicked on a difficulty button, change the current difficulty level Difficulty difficulty = checkDifficultyButton(mouseX, mouseY); if ((difficulty < kDifficultyMAX) && (_difficulty != difficulty)) { -- cgit v1.2.3 From e477b7d2b996bb4a93b3d95fb5b08e01d64e3b03 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 1 Jul 2012 14:55:51 +0200 Subject: GOB: Move the Once Upon A Time palettes into their own file --- engines/gob/pregob/onceupon/onceupon.cpp | 134 +--------- engines/gob/pregob/onceupon/palettes.h | 411 +++++++++++++++++++++++++++++++ 2 files changed, 412 insertions(+), 133 deletions(-) create mode 100644 engines/gob/pregob/onceupon/palettes.h (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 49516a55c7..c30421900f 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -33,139 +33,7 @@ #include "gob/sound/sound.h" #include "gob/pregob/onceupon/onceupon.h" - -static const int kPaletteSize = 16; -static const uint kPaletteCount = 20; - -static const byte kCopyProtectionPalette[3 * kPaletteSize] = { - 0x00, 0x00, 0x00, 0x19, 0x00, 0x19, 0x00, 0x3F, 0x00, 0x00, 0x2A, 0x2A, - 0x2A, 0x00, 0x00, 0x2A, 0x00, 0x2A, 0x2A, 0x15, 0x00, 0x00, 0x19, 0x12, - 0x00, 0x00, 0x00, 0x15, 0x15, 0x3F, 0x15, 0x3F, 0x15, 0x00, 0x20, 0x3F, - 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x20, 0x3F, 0x3F, 0x00, 0x3F, 0x3F, 0x3F -}; - -static const byte kGamePalettes[kPaletteCount][3 * kPaletteSize] = { - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3C, - 0x1C, 0x28, 0x00, 0x10, 0x18, 0x00, 0x1C, 0x1C, 0x20, 0x14, 0x14, 0x14, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x14, 0x20, 0x04, - 0x3C, 0x2C, 0x00, 0x02, 0x00, 0x18, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x38, 0x20, 0x3C, 0x2C, 0x10, 0x30, 0x20, 0x08, 0x28, - 0x14, 0x00, 0x1C, 0x20, 0x20, 0x38, 0x18, 0x18, 0x2C, 0x10, 0x10, 0x24, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x3C, 0x20, 0x20, 0x24, 0x14, 0x14, 0x1C, 0x10, 0x10, - 0x14, 0x0C, 0x0C, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x10, 0x10, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x10, 0x28, 0x1C, 0x10, 0x1C, 0x10, 0x10, 0x14, 0x0C, - 0x1C, 0x1C, 0x3C, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x24, 0x10, 0x10, 0x18, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x3F, 0x26, 0x3F, 0x36, 0x1C, 0x36, 0x2C, 0x12, 0x2A, - 0x27, 0x0C, 0x24, 0x22, 0x07, 0x1E, 0x1D, 0x03, 0x18, 0x16, 0x00, 0x10, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x3F, 0x39, 0x26, 0x38, 0x34, 0x1C, 0x30, 0x2F, 0x13, - 0x27, 0x29, 0x0C, 0x1D, 0x22, 0x07, 0x14, 0x1B, 0x03, 0x0C, 0x14, 0x00, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x1C, 0x34, 0x38, 0x14, 0x2C, 0x30, - 0x0C, 0x20, 0x2C, 0x08, 0x18, 0x28, 0x04, 0x10, 0x20, 0x00, 0x08, 0x1C, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x3C, 0x2C, 0x24, 0x38, 0x24, 0x1C, 0x30, 0x1C, 0x14, - 0x28, 0x18, 0x0C, 0x20, 0x10, 0x04, 0x1C, 0x0C, 0x00, 0x14, 0x08, 0x00, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x3C, 0x34, 0x24, 0x38, 0x2C, 0x1C, 0x30, 0x24, 0x14, - 0x2C, 0x1C, 0x10, 0x30, 0x30, 0x3C, 0x1C, 0x1C, 0x38, 0x0C, 0x0C, 0x38, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x03, 0x14, 0x07, 0x07, 0x1D, - 0x0E, 0x0E, 0x25, 0x17, 0x17, 0x2E, 0x21, 0x22, 0x36, 0x2F, 0x2F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3B, 0x0D, 0x3A, 0x31, 0x0A, 0x35, 0x28, 0x07, - 0x30, 0x21, 0x04, 0x2B, 0x19, 0x02, 0x26, 0x12, 0x01, 0x16, 0x0B, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x21, 0x01, 0x00, 0x2A, 0x02, 0x00, - 0x33, 0x03, 0x00, 0x3D, 0x06, 0x00, 0x2A, 0x19, 0x05, 0x15, 0x14, 0x14, - 0x22, 0x1F, 0x1E, 0x2F, 0x2C, 0x28, 0x3F, 0x3C, 0x29, 0x3F, 0x38, 0x0B, - 0x3B, 0x30, 0x0A, 0x37, 0x29, 0x08, 0x33, 0x23, 0x07, 0x2F, 0x1D, 0x06 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x34, 0x30, 0x28, 0x2C, 0x24, 0x1C, - 0x24, 0x18, 0x10, 0x1C, 0x10, 0x08, 0x14, 0x04, 0x04, 0x10, 0x00, 0x00, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x34, 0x30, 0x28, 0x2C, 0x24, 0x1C, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x1A, 0x30, 0x37, 0x14, 0x28, 0x31, 0x10, 0x20, 0x2C, - 0x0C, 0x19, 0x27, 0x08, 0x12, 0x21, 0x05, 0x0C, 0x1C, 0x03, 0x07, 0x16, - 0x01, 0x03, 0x11, 0x00, 0x00, 0x0C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x34, 0x30, 0x34, 0x30, 0x24, 0x30, 0x28, 0x1C, 0x28, - 0x24, 0x14, 0x24, 0x1C, 0x0C, 0x1C, 0x18, 0x08, 0x18, 0x14, 0x04, 0x14, - 0x0C, 0x04, 0x0C, 0x08, 0x00, 0x08, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x2C, 0x24, 0x0C, 0x34, 0x34, 0x28, 0x2C, 0x2C, 0x1C, - 0x24, 0x24, 0x10, 0x1C, 0x18, 0x08, 0x14, 0x14, 0x08, 0x10, 0x10, 0x04, - 0x0C, 0x0C, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x38, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x31, 0x10, 0x20, 0x2C, - 0x0C, 0x19, 0x27, 0x08, 0x12, 0x21, 0x05, 0x0C, 0x1C, 0x03, 0x07, 0x16, - 0x01, 0x03, 0x11, 0x00, 0x3C, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x10, 0x28, 0x1C, 0x10, 0x1C, 0x10, 0x10, 0x14, 0x0C, - 0x1C, 0x1C, 0x3C, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x24, 0x10, 0x10, 0x18, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x10, 0x28, 0x1C, 0x10, 0x1C, 0x10, 0x10, 0x14, 0x0C, - 0x1C, 0x1C, 0x3C, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x24, 0x10, 0x10, 0x18, - 0x14, 0x20, 0x04, 0x00, 0x00, 0x24, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, - 0x3C, 0x2C, 0x00, 0x3C, 0x18, 0x00, 0x3C, 0x04, 0x00, 0x1C, 0x00, 0x00 - } -}; +#include "gob/pregob/onceupon/palettes.h" static const uint kLanguageCount = 5; diff --git a/engines/gob/pregob/onceupon/palettes.h b/engines/gob/pregob/onceupon/palettes.h new file mode 100644 index 0000000000..952581041c --- /dev/null +++ b/engines/gob/pregob/onceupon/palettes.h @@ -0,0 +1,411 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_PALETTES_H +#define GOB_PREGOB_ONCEUPON_PALETTES_H + +static const int kPaletteSize = 16; +static const uint kPaletteCount = 20; + +static const byte kCopyProtectionPalette[3 * kPaletteSize] = { + 0x00, 0x00, 0x00, + 0x19, 0x00, 0x19, + 0x00, 0x3F, 0x00, + 0x00, 0x2A, 0x2A, + 0x2A, 0x00, 0x00, + 0x2A, 0x00, 0x2A, + 0x2A, 0x15, 0x00, + 0x00, 0x19, 0x12, + 0x00, 0x00, 0x00, + 0x15, 0x15, 0x3F, + 0x15, 0x3F, 0x15, + 0x00, 0x20, 0x3F, + 0x3F, 0x00, 0x00, + 0x3F, 0x00, 0x20, + 0x3F, 0x3F, 0x00, + 0x3F, 0x3F, 0x3F +}; + +static const byte kGamePalettes[kPaletteCount][3 * kPaletteSize] = { + { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, + 0x00, 0x00, 0x18, + 0x00, 0x00, 0x3C, + 0x1C, 0x28, 0x00, + 0x10, 0x18, 0x00, + 0x1C, 0x1C, 0x20, + 0x14, 0x14, 0x14, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x14, 0x20, 0x04, + 0x3C, 0x2C, 0x00, + 0x02, 0x00, 0x18, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x38, 0x20, 0x3C, + 0x2C, 0x10, 0x30, + 0x20, 0x08, 0x28, + 0x14, 0x00, 0x1C, + 0x20, 0x20, 0x38, + 0x18, 0x18, 0x2C, + 0x10, 0x10, 0x24, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x3C, 0x20, 0x20, + 0x24, 0x14, 0x14, + 0x1C, 0x10, 0x10, + 0x14, 0x0C, 0x0C, + 0x1C, 0x1C, 0x1C, + 0x18, 0x18, 0x18, + 0x10, 0x10, 0x10, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x10, 0x28, 0x1C, + 0x10, 0x1C, 0x10, + 0x10, 0x14, 0x0C, + 0x1C, 0x1C, 0x3C, + 0x24, 0x24, 0x3C, + 0x18, 0x18, 0x24, + 0x10, 0x10, 0x18, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x3F, 0x26, 0x3F, + 0x36, 0x1C, 0x36, + 0x2C, 0x12, 0x2A, + 0x27, 0x0C, 0x24, + 0x22, 0x07, 0x1E, + 0x1D, 0x03, 0x18, + 0x16, 0x00, 0x10, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3A, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x3F, 0x39, 0x26, + 0x38, 0x34, 0x1C, + 0x30, 0x2F, 0x13, + 0x27, 0x29, 0x0C, + 0x1D, 0x22, 0x07, + 0x14, 0x1B, 0x03, + 0x0C, 0x14, 0x00, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3A, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x24, 0x3C, 0x3C, + 0x1C, 0x34, 0x38, + 0x14, 0x2C, 0x30, + 0x0C, 0x20, 0x2C, + 0x08, 0x18, 0x28, + 0x04, 0x10, 0x20, + 0x00, 0x08, 0x1C, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x38, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x24, + 0x38, 0x24, 0x1C, + 0x30, 0x1C, 0x14, + 0x28, 0x18, 0x0C, + 0x20, 0x10, 0x04, + 0x1C, 0x0C, 0x00, + 0x14, 0x08, 0x00, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x38, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x3C, 0x34, 0x24, + 0x38, 0x2C, 0x1C, + 0x30, 0x24, 0x14, + 0x2C, 0x1C, 0x10, + 0x30, 0x30, 0x3C, + 0x1C, 0x1C, 0x38, + 0x0C, 0x0C, 0x38, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0C, + 0x02, 0x03, 0x14, + 0x07, 0x07, 0x1D, + 0x0E, 0x0E, 0x25, + 0x17, 0x17, 0x2E, + 0x21, 0x22, 0x36, + 0x2F, 0x2F, 0x3F, + 0x3F, 0x3F, 0x3F, + 0x3F, 0x3B, 0x0D, + 0x3A, 0x31, 0x0A, + 0x35, 0x28, 0x07, + 0x30, 0x21, 0x04, + 0x2B, 0x19, 0x02, + 0x26, 0x12, 0x01, + 0x16, 0x0B, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, + 0x21, 0x01, 0x00, + 0x2A, 0x02, 0x00, + 0x33, 0x03, 0x00, + 0x3D, 0x06, 0x00, + 0x2A, 0x19, 0x05, + 0x15, 0x14, 0x14, + 0x22, 0x1F, 0x1E, + 0x2F, 0x2C, 0x28, + 0x3F, 0x3C, 0x29, + 0x3F, 0x38, 0x0B, + 0x3B, 0x30, 0x0A, + 0x37, 0x29, 0x08, + 0x33, 0x23, 0x07, + 0x2F, 0x1D, 0x06 + }, + { + 0x00, 0x00, 0x00, + 0x00, 0x1C, 0x38, + 0x34, 0x30, 0x28, + 0x2C, 0x24, 0x1C, + 0x24, 0x18, 0x10, + 0x1C, 0x10, 0x08, + 0x14, 0x04, 0x04, + 0x10, 0x00, 0x00, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x38, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x00, 0x1C, 0x38, + 0x34, 0x30, 0x28, + 0x2C, 0x24, 0x1C, + 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x38, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x1A, 0x30, 0x37, + 0x14, 0x28, 0x31, + 0x10, 0x20, 0x2C, + 0x0C, 0x19, 0x27, + 0x08, 0x12, 0x21, + 0x05, 0x0C, 0x1C, + 0x03, 0x07, 0x16, + 0x01, 0x03, 0x11, + 0x00, 0x00, 0x0C, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x34, 0x30, 0x34, + 0x30, 0x24, 0x30, + 0x28, 0x1C, 0x28, + 0x24, 0x14, 0x24, + 0x1C, 0x0C, 0x1C, + 0x18, 0x08, 0x18, + 0x14, 0x04, 0x14, + 0x0C, 0x04, 0x0C, + 0x08, 0x00, 0x08, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x2C, 0x24, 0x0C, + 0x34, 0x34, 0x28, + 0x2C, 0x2C, 0x1C, + 0x24, 0x24, 0x10, + 0x1C, 0x18, 0x08, + 0x14, 0x14, 0x08, + 0x10, 0x10, 0x04, + 0x0C, 0x0C, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x38, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + 0x14, 0x28, 0x31, + 0x10, 0x20, 0x2C, + 0x0C, 0x19, 0x27, + 0x08, 0x12, 0x21, + 0x05, 0x0C, 0x1C, + 0x03, 0x07, 0x16, + 0x01, 0x03, 0x11, + 0x00, 0x3C, 0x00, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x10, 0x28, 0x1C, + 0x10, 0x1C, 0x10, + 0x10, 0x14, 0x0C, + 0x1C, 0x1C, 0x3C, + 0x24, 0x24, 0x3C, + 0x18, 0x18, 0x24, + 0x10, 0x10, 0x18, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, + 0x10, 0x28, 0x1C, + 0x10, 0x1C, 0x10, + 0x10, 0x14, 0x0C, + 0x1C, 0x1C, 0x3C, + 0x24, 0x24, 0x3C, + 0x18, 0x18, 0x24, + 0x10, 0x10, 0x18, + 0x14, 0x20, 0x04, + 0x00, 0x00, 0x24, + 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, + 0x3C, 0x2C, 0x00, + 0x3C, 0x18, 0x00, + 0x3C, 0x04, 0x00, + 0x1C, 0x00, 0x00 + } +}; + +#endif // GOB_PREGOB_ONCEUPON_PALETTES_H -- cgit v1.2.3 From 4663ab2373ac3230ccb95cc2accee87ddd1682b8 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 1 Jul 2012 15:55:02 +0200 Subject: GOB: Fix some broken German text in Once Upon A Time --- engines/gob/pregob/onceupon/brokenstrings.h | 51 +++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/onceupon.cpp | 18 ++++++++++ engines/gob/pregob/onceupon/onceupon.h | 3 ++ engines/gob/pregob/pregob.cpp | 5 +++ engines/gob/pregob/pregob.h | 2 ++ 5 files changed, 79 insertions(+) create mode 100644 engines/gob/pregob/onceupon/brokenstrings.h (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/brokenstrings.h b/engines/gob/pregob/onceupon/brokenstrings.h new file mode 100644 index 0000000000..86c0603058 --- /dev/null +++ b/engines/gob/pregob/onceupon/brokenstrings.h @@ -0,0 +1,51 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_BROKENSTRINGS_H +#define GOB_PREGOB_ONCEUPON_BROKENSTRINGS_H + +struct BrokenString { + const char *wrong; + const char *correct; +}; + +struct BrokenStringLanguage { + const BrokenString *strings; + uint count; +}; + +static const BrokenString kBrokenStringsGerman[] = { + { "Zeichungen von Kaki," , "Zeichnungen von Kaki," }, + { "die es in seine Wachtr\204ume", "die es in seine Tagtr\204ume" }, + { " Spielerfahrung" , " Spielerfahren" }, + { " Fortgeschrittene" , " Fortgeschritten" } +}; + +static const BrokenStringLanguage kBrokenStrings[kLanguageCount] = { + { 0, 0 }, // French + { kBrokenStringsGerman, ARRAYSIZE(kBrokenStringsGerman) }, // German + { 0, 0 }, // English + { 0, 0 }, // Spanish + { 0, 0 }, // Italian +}; + +#endif // GOB_PREGOB_ONCEUPON_BROKENSTRINGS_H diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index c30421900f..c20ca2a45f 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -211,6 +211,24 @@ void OnceUpon::setGameCursor() { setCursor(cursor, 105, 0, 120, 15, 0, 0); } +void OnceUpon::fixTXTStrings(TXTFile &txt) const { + TXTFile::LineArray &lines = txt.getLines(); + for (uint i = 0; i < lines.size(); i++) + lines[i].text = fixString(lines[i].text); +} + +#include "gob/pregob/onceupon/brokenstrings.h" +Common::String OnceUpon::fixString(const Common::String &str) const { + const BrokenStringLanguage &broken = kBrokenStrings[_vm->_global->_language]; + + for (uint i = 0; i < broken.count; i++) { + if (str == broken.strings[i].wrong) + return broken.strings[i].correct; + } + + return str; +} + enum CopyProtectionState { kCPStateSetup, // Set up the screen kCPStateWaitUser, // Waiting for the user to pick a shape diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 9ad563903e..efc2710d67 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -88,6 +88,9 @@ protected: void setGamePalette(uint palette); void setGameCursor(); + Common::String fixString(const Common::String &str) const; + void fixTXTStrings(TXTFile &txt) const; + bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen. diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 9c6cfb717a..f94f990f76 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -256,7 +256,12 @@ TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) delete txtStream; + fixTXTStrings(*txt); + return txt; } +void PreGob::fixTXTStrings(TXTFile &txt) const { +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index b91758876e..0a40ed6242 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -93,6 +93,8 @@ protected: Common::String getLocFile(const Common::String &file) const; TXTFile *loadTXT(const Common::String &txtFile, TXTFile::Format format) const; + virtual void fixTXTStrings(TXTFile &txt) const; + GobEngine *_vm; -- cgit v1.2.3 From 9e997fea1be0c3f7cd8af7ee0f145879d5c49882 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 00:09:43 +0200 Subject: GOB: Add "long" PreGob language suffixes --- engines/gob/pregob/pregob.cpp | 9 ++++++--- engines/gob/pregob/pregob.h | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index f94f990f76..f39a7a112e 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -36,10 +36,13 @@ #include "gob/pregob/pregob.h" -static char kLanguageSuffix[5] = { 't', 'g', 'a', 'e', 'i' }; namespace Gob { +const char PreGob::kLanguageSuffixShort[5] = { 't', 'g', 'a', 'e', 'i'}; +const char *PreGob::kLanguageSuffixLong [5] = {"fr", "al", "an", "it", "es"}; + + PreGob::PreGob(GobEngine *vm) : _vm(vm), _fadedOut(false) { } @@ -241,10 +244,10 @@ void PreGob::redrawAnim(ANIObject &ani) { } Common::String PreGob::getLocFile(const Common::String &file) const { - if (_vm->_global->_language >= ARRAYSIZE(kLanguageSuffix)) + if (_vm->_global->_language >= ARRAYSIZE(kLanguageSuffixShort)) return file; - return file + kLanguageSuffix[_vm->_global->_language]; + return file + kLanguageSuffixShort[_vm->_global->_language]; } TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) const { diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 0a40ed6242..477aec6dc8 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -47,6 +47,10 @@ public: virtual void run() = 0; protected: + static const char kLanguageSuffixShort[5]; + static const char *kLanguageSuffixLong [5]; + + void initScreen(); ///< Initialize the game screen. void fadeOut(); ///< Fade to black. -- cgit v1.2.3 From 9d564ecd268781d8b92ca7a5895aa10aea6b4e52 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 00:10:23 +0200 Subject: GOB: Implement the animal names bit Once Upon A Time --- engines/gob/pregob/onceupon/abracadabra.cpp | 28 ++- engines/gob/pregob/onceupon/abracadabra.h | 3 + engines/gob/pregob/onceupon/babayaga.cpp | 28 ++- engines/gob/pregob/onceupon/babayaga.h | 3 + engines/gob/pregob/onceupon/brokenstrings.h | 5 +- engines/gob/pregob/onceupon/onceupon.cpp | 265 +++++++++++++++++++++++----- engines/gob/pregob/onceupon/onceupon.h | 27 ++- engines/gob/pregob/pregob.cpp | 50 ++++-- engines/gob/pregob/pregob.h | 5 + 9 files changed, 343 insertions(+), 71 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 696e4d9594..781d683ef0 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -52,6 +52,32 @@ const OnceUpon::MenuButton Abracadabra::kAnimalsButtons = { true, 131, 127, 183, 164, 193, 0, 243, 35, 132, 128, 0 }; +const OnceUpon::MenuButton Abracadabra::kAnimalButtons[] = { + {false, 37, 89, 95, 127, 37, 89, 95, 127, 131, 25, 0}, + {false, 114, 65, 172, 111, 114, 65, 172, 111, 131, 25, 1}, + {false, 186, 72, 227, 96, 186, 72, 227, 96, 139, 25, 2}, + {false, 249, 87, 282, 112, 249, 87, 282, 112, 143, 25, 3}, + {false, 180, 102, 234, 138, 180, 102, 234, 138, 133, 25, 4}, + {false, 197, 145, 242, 173, 197, 145, 242, 173, 137, 25, 5}, + {false, 113, 151, 171, 176, 113, 151, 171, 176, 131, 25, 6}, + {false, 114, 122, 151, 150, 114, 122, 151, 150, 141, 25, 7}, + {false, 36, 136, 94, 176, 36, 136, 94, 176, 131, 25, 8}, + {false, 243, 123, 295, 155, 243, 123, 295, 155, 136, 25, 9} +}; + +const char *Abracadabra::kAnimalNames[] = { + "loup", + "drag", + "arai", + "crap", + "crab", + "mous", + "saut", + "guep", + "rhin", + "scor" +}; + Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) { setAnimalsButton(&kAnimalsButtons); @@ -91,7 +117,7 @@ void Abracadabra::mainLoop() { else if (action == kMenuActionRestart) warning("Abracadabra::mainLoop(): TODO: Restart"); else if (action == kMenuActionAnimals) - warning("Abracadabra::mainLoop(): TODO: Animals"); + doAnimalNames(ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); else if (action == kMenuActionQuit) break; } diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h index 64deaf4389..5f3a1ba634 100644 --- a/engines/gob/pregob/onceupon/abracadabra.h +++ b/engines/gob/pregob/onceupon/abracadabra.h @@ -39,6 +39,9 @@ public: private: static const MenuButton kAnimalsButtons; + static const MenuButton kAnimalButtons[]; + static const char *kAnimalNames[]; + void mainLoop(); }; diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index b752bb0862..34f674107c 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -52,6 +52,32 @@ const OnceUpon::MenuButton BabaYaga::kAnimalsButtons = { true, 131, 127, 183, 164, 193, 0, 245, 37, 131, 127, 0 }; +const OnceUpon::MenuButton BabaYaga::kAnimalButtons[] = { + {false, 34, 84, 92, 127, 34, 84, 92, 127, 131, 25, 0}, + {false, 114, 65, 172, 111, 114, 65, 172, 111, 131, 25, 1}, + {false, 186, 72, 227, 96, 186, 72, 227, 96, 139, 25, 2}, + {false, 249, 87, 282, 112, 249, 87, 282, 112, 143, 25, 3}, + {false, 180, 97, 234, 138, 180, 97, 234, 138, 133, 25, 4}, + {false, 197, 145, 242, 173, 197, 145, 242, 173, 137, 25, 5}, + {false, 113, 156, 171, 176, 113, 156, 171, 176, 131, 25, 6}, + {false, 114, 127, 151, 150, 114, 127, 151, 150, 141, 25, 7}, + {false, 36, 136, 94, 176, 36, 136, 94, 176, 131, 25, 8}, + {false, 245, 123, 293, 155, 245, 123, 293, 155, 136, 25, 9} +}; + +const char *BabaYaga::kAnimalNames[] = { + "vaut", + "drag", + "arai", + "gren", + "fauc", + "abei", + "serp", + "tort", + "sang", + "rena" +}; + BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) { setAnimalsButton(&kAnimalsButtons); @@ -91,7 +117,7 @@ void BabaYaga::mainLoop() { else if (action == kMenuActionRestart) warning("BabaYaga::mainLoop(): TODO: Restart"); else if (action == kMenuActionAnimals) - warning("BabaYaga::mainLoop(): TODO: Animals"); + doAnimalNames(ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); else if (action == kMenuActionQuit) break; } diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h index 98d452418f..de42f8e8fe 100644 --- a/engines/gob/pregob/onceupon/babayaga.h +++ b/engines/gob/pregob/onceupon/babayaga.h @@ -39,6 +39,9 @@ public: private: static const MenuButton kAnimalsButtons; + static const MenuButton kAnimalButtons[]; + static const char *kAnimalNames[]; + void mainLoop(); }; diff --git a/engines/gob/pregob/onceupon/brokenstrings.h b/engines/gob/pregob/onceupon/brokenstrings.h index 86c0603058..98dcb720fb 100644 --- a/engines/gob/pregob/onceupon/brokenstrings.h +++ b/engines/gob/pregob/onceupon/brokenstrings.h @@ -37,7 +37,10 @@ static const BrokenString kBrokenStringsGerman[] = { { "Zeichungen von Kaki," , "Zeichnungen von Kaki," }, { "die es in seine Wachtr\204ume", "die es in seine Tagtr\204ume" }, { " Spielerfahrung" , " Spielerfahren" }, - { " Fortgeschrittene" , " Fortgeschritten" } + { " Fortgeschrittene" , " Fortgeschritten" }, + { "die Vespe" , "die Wespe" }, + { "das Rhinoceros" , "das Rhinozeros" }, + { "die Heusschrecke" , "die Heuschrecke" } }; static const BrokenStringLanguage kBrokenStrings[kLanguageCount] = { diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index c20ca2a45f..b7bf2c3f5a 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -39,7 +39,7 @@ static const uint kLanguageCount = 5; static const uint kCopyProtectionHelpStringCount = 3; -static const char *kCopyProtectionHelpStrings[kLanguageCount][kCopyProtectionHelpStringCount] = { +static const char *kCopyProtectionHelpStrings[Gob::OnceUpon::OnceUpon::kLanguageCount][kCopyProtectionHelpStringCount] = { { // French "Consulte le livret des animaux, rep\212re la", "page correspondant \205 la couleur de l\'\202cran", @@ -67,7 +67,7 @@ static const char *kCopyProtectionHelpStrings[kLanguageCount][kCopyProtectionHel } }; -static const char *kCopyProtectionWrongStrings[kLanguageCount] = { +static const char *kCopyProtectionWrongStrings[Gob::OnceUpon::OnceUpon::kLanguageCount] = { "Tu t\'es tromp\202, dommage...", // French "Schade, du hast dich geirrt." , // German "You are wrong, what a pity!" , // English @@ -95,25 +95,38 @@ namespace Gob { namespace OnceUpon { -const OnceUpon::MenuButton OnceUpon::kMainMenuDifficultyButton[3] = { - {false, 29, 18, 77, 57, 0, 0, 0, 0, 0, 0, 0}, - {false, 133, 18, 181, 57, 0, 0, 0, 0, 0, 0, 1}, - {false, 241, 18, 289, 57, 0, 0, 0, 0, 0, 0, 2}, +const OnceUpon::MenuButton OnceUpon::kMainMenuDifficultyButton[] = { + {false, 29, 18, 77, 57, 0, 0, 0, 0, 0, 0, (int)kDifficultyBeginner}, + {false, 133, 18, 181, 57, 0, 0, 0, 0, 0, 0, (int)kDifficultyIntermediate}, + {false, 241, 18, 289, 57, 0, 0, 0, 0, 0, 0, (int)kDifficultyAdvanced}, }; -const OnceUpon::MenuButton OnceUpon::kSectionButtons[4] = { +const OnceUpon::MenuButton OnceUpon::kSectionButtons[] = { {false, 27, 121, 91, 179, 0, 0, 0, 0, 0, 0, 0}, { true, 95, 121, 159, 179, 4, 1, 56, 49, 100, 126, 2}, { true, 163, 121, 227, 179, 64, 1, 120, 49, 168, 126, 6}, { true, 231, 121, 295, 179, 128, 1, 184, 49, 236, 126, 10} }; -const OnceUpon::MenuButton OnceUpon::kIngameButtons[3] = { +const OnceUpon::MenuButton OnceUpon::kIngameButtons[] = { {true, 108, 83, 139, 116, 0, 0, 31, 34, 108, 83, 0}, {true, 144, 83, 175, 116, 36, 0, 67, 34, 144, 83, 1}, {true, 180, 83, 211, 116, 72, 0, 103, 34, 180, 83, 2} }; +const OnceUpon::MenuButton OnceUpon::kAnimalNamesBack = { + true, 19, 13, 50, 46, 36, 0, 67, 34, 19, 13, 1 +}; + +const OnceUpon::MenuButton OnceUpon::kLanguageButtons[] = { + {true, 43, 80, 93, 115, 0, 55, 50, 90, 43, 80, 0}, + {true, 132, 80, 182, 115, 53, 55, 103, 90, 132, 80, 1}, + {true, 234, 80, 284, 115, 106, 55, 156, 90, 234, 80, 2}, + {true, 43, 138, 93, 173, 159, 55, 209, 90, 43, 138, 3}, + {true, 132, 138, 182, 173, 212, 55, 262, 90, 132, 138, 4}, + {true, 234, 138, 284, 173, 265, 55, 315, 90, 234, 138, 2} +}; + const char *OnceUpon::kSound[kSoundMAX] = { "diamant.snd" }; @@ -643,6 +656,7 @@ OnceUpon::MenuAction OnceUpon::doMenu(MenuType type) { OnceUpon::MenuAction OnceUpon::doMenuMainStart() { fadeOut(); + setGamePalette(17); drawMenuMainStart(); showCursor(); fadeIn(); @@ -667,16 +681,16 @@ OnceUpon::MenuAction OnceUpon::doMenuMainStart() { playSound(kSoundClick); // If we clicked on a difficulty button, show the selected difficulty and start the game - Difficulty difficulty = checkDifficultyButton(mouseX, mouseY); - if (difficulty < kDifficultyMAX) { - _difficulty = difficulty; + int diff = checkButton(kMainMenuDifficultyButton, ARRAYSIZE(kMainMenuDifficultyButton), mouseX, mouseY); + if (diff >= 0) { + _difficulty = (Difficulty)diff; action = kMenuActionPlay; drawMenuMainStart(); _vm->_util->longDelay(1000); } - if (checkAnimalsButton(mouseX, mouseY)) + if (_animalsButton && (checkButton(_animalsButton, 1, mouseX, mouseY) != -1)) action = kMenuActionAnimals; } @@ -686,6 +700,7 @@ OnceUpon::MenuAction OnceUpon::doMenuMainStart() { OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { fadeOut(); + setGamePalette(17); drawMenuMainIngame(); showCursor(); fadeIn(); @@ -710,16 +725,16 @@ OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { playSound(kSoundClick); // If we clicked on a difficulty button, change the current difficulty level - Difficulty difficulty = checkDifficultyButton(mouseX, mouseY); - if ((difficulty < kDifficultyMAX) && (_difficulty != difficulty)) { - _difficulty = difficulty; + int diff = checkButton(kMainMenuDifficultyButton, ARRAYSIZE(kMainMenuDifficultyButton), mouseX, mouseY); + if ((diff >= 0) && (diff != (int)_difficulty)) { + _difficulty = (Difficulty)diff; drawMenuMainIngame(); } // If we clicked on a section button, restart the game from this section - int8 section = checkSectionButton(mouseX, mouseY); - if (section >= 0) { + int section = checkButton(kSectionButtons, ARRAYSIZE(kSectionButtons), mouseX, mouseY); + if ((section >= 0) && (section <= _section)) { _section = section; action = kMenuActionRestart; } @@ -750,8 +765,7 @@ OnceUpon::MenuAction OnceUpon::doMenuIngame() { if (mouseButtons != kMouseButtonsLeft) continue; - // Check if we've pressed one of the buttons - int8 button = checkIngameButton(mouseX, mouseY); + int button = checkButton(kIngameButtons, ARRAYSIZE(kIngameButtons), mouseX, mouseY); if (button == 0) action = kMenuActionQuit; else if (button == 1) @@ -774,10 +788,7 @@ void OnceUpon::drawMenuMainStart() { _vm->_video->drawPackedSprite("elemenu.cmp", elements); _vm->_draw->_backSurface->fillRect(_animalsButton->left , _animalsButton->top, _animalsButton->right, _animalsButton->bottom, 0); - _vm->_draw->_backSurface->blit(elements, - _animalsButton->srcLeft , _animalsButton->srcTop, - _animalsButton->srcRight, _animalsButton->srcBottom, - _animalsButton->dstX , _animalsButton->dstY); + drawButton(*_vm->_draw->_backSurface, elements, *_animalsButton); } // Highlight the current difficulty @@ -804,8 +815,7 @@ void OnceUpon::drawMenuMainIngame() { continue; if (_section >= (uint)button.id) - _vm->_draw->_backSurface->blit(elements, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom, - button.dstX, button.dstY); + drawButton(*_vm->_draw->_backSurface, elements, button); } _vm->_draw->forceBlit(); @@ -873,48 +883,205 @@ void OnceUpon::clearMenuIngame(const Surface &background) { drawLineByLine(background, left, top, right, bottom, left, top); } -OnceUpon::Difficulty OnceUpon::checkDifficultyButton(int16 x, int16 y) const { - for (uint i = 0; i < ARRAYSIZE(kMainMenuDifficultyButton); i++) { - const MenuButton &button = kMainMenuDifficultyButton[i]; +int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue) const { + for (uint i = 0; i < count; i++) { + const MenuButton &button = buttons[i]; if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom)) - return (Difficulty) button.id; + return (int)button.id; } - return kDifficultyMAX; + return failValue; } -bool OnceUpon::checkAnimalsButton(int16 x, int16 y) const { - if (!_animalsButton) - return false; - - return (x >= _animalsButton->left) && (x <= _animalsButton->right) && - (y >= _animalsButton->top) && (y <= _animalsButton->bottom); +void OnceUpon::drawButton(Surface &dest, const Surface &src, const MenuButton &button) const { + dest.blit(src, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom, button.dstX, button.dstY); } -int8 OnceUpon::checkSectionButton(int16 x, int16 y) const { - for (uint i = 0; i < ARRAYSIZE(kSectionButtons); i++) { - const MenuButton &button = kSectionButtons[i]; +void OnceUpon::drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const { + for (uint i = 0; i < count; i++) { + const MenuButton &button = buttons[i]; - if ((uint)button.id > _section) + if (!button.needDraw) continue; - if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom)) - return (int8)button.id; + drawButton(dest, src, button); } +} - return -1; +void OnceUpon::drawButtonBorder(const MenuButton &button, uint8 color) { + _vm->_draw->_backSurface->drawRect(button.left, button.top, button.right, button.bottom, color); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, button.left, button.top, button.right, button.bottom); } -int8 OnceUpon::checkIngameButton(int16 x, int16 y) const { - for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) { - const MenuButton &button = kIngameButtons[i]; +enum AnimalNamesState { + kANStateChoose, + kANStateNames, + kANStateFinish +}; - if ((x >= button.left) && (x <= button.right) && (y >= button.top) && (y <= button.bottom)) - return (int8)button.id; +void OnceUpon::doAnimalNames(uint count, const MenuButton *buttons, const char * const *names) { + fadeOut(); + clearScreen(); + setGamePalette(19); + + bool cursorVisible = isCursorVisible(); + + // Set the cursor + addCursor(); + setGameCursor(); + + anSetupChooser(); + + int8 _animal = -1; + + AnimalNamesState state = kANStateChoose; + while (!_vm->shouldQuit() && (state != kANStateFinish)) { + showCursor(); + fadeIn(); + + endFrame(true); + + // Check user input + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + checkInput(mouseX, mouseY, mouseButtons); + + // If we moused over an animal button, draw a border around it + int animal = checkButton(buttons, count, mouseX, mouseY); + if ((state == kANStateChoose) && (animal != _animal)) { + // Erase the old border + if (_animal >= 0) + drawButtonBorder(buttons[_animal], 15); + + _animal = animal; + + // Draw the new border + if (_animal >= 0) + drawButtonBorder(buttons[_animal], 10); + } + + if (mouseButtons != kMouseButtonsLeft) + continue; + + playSound(kSoundClick); + + // We clicked on a language button, play the animal name + int language = checkButton(kLanguageButtons, ARRAYSIZE(kLanguageButtons), mouseX, mouseY); + if ((state == kANStateNames) && (language >= 0)) + anPlayAnimalName(names[_animal], language); + + // We clicked on an animal + if ((state == kANStateChoose) && (_animal >= 0)) { + anSetupNames(buttons[_animal]); + + state = kANStateNames; + } + + // If we clicked on the back button, go back + if (checkButton(&kAnimalNamesBack, 1, mouseX, mouseY) != -1) { + if (state == kANStateNames) { + anSetupChooser(); + + state = kANStateChoose; + } else if (state == kANStateChoose) + state = kANStateFinish; + } } - return -1; + fadeOut(); + + // Restore the cursor + if (!cursorVisible) + hideCursor(); + removeCursor(); +} + +void OnceUpon::anSetupChooser() { + fadeOut(); + + _vm->_video->drawPackedSprite("dico.cmp", *_vm->_draw->_backSurface); + + // Draw the back button + Surface menu(320, 34, 1); + _vm->_video->drawPackedSprite("icon.cmp", menu); + drawButton(*_vm->_draw->_backSurface, menu, kAnimalNamesBack); + + // "Choose an animal" + TXTFile *choose = loadTXT(getLocFile("choisi.tx"), TXTFile::kFormatStringPosition); + choose->draw(*_vm->_draw->_backSurface, &_plettre, 1, 14); + delete choose; + + _vm->_draw->forceBlit(); +} + +void OnceUpon::anSetupNames(const MenuButton &animal) { + fadeOut(); + + Surface background(320, 200, 1); + + _vm->_video->drawPackedSprite("dico.cmp", background); + + // Draw the background and clear what we don't need + _vm->_draw->_backSurface->blit(background); + _vm->_draw->_backSurface->fillRect(19, 19, 302, 186, 15); + + // Draw the back button + Surface menu(320, 34, 1); + _vm->_video->drawPackedSprite("icon.cmp", menu); + drawButton(*_vm->_draw->_backSurface, menu, kAnimalNamesBack); + + // Draw the animal + drawButton(*_vm->_draw->_backSurface, background, animal); + + // Draw the language buttons + Surface elements(320, 200, 1); + _vm->_video->drawPackedSprite("elemenu.cmp", elements); + drawButtons(*_vm->_draw->_backSurface, elements, kLanguageButtons, ARRAYSIZE(kLanguageButtons)); + + // Draw the language names + _plettre->drawString("Fran\207ais", 43, 70, 10, 15, true, *_vm->_draw->_backSurface); + _plettre->drawString("Deutsch" , 136, 70, 10, 15, true, *_vm->_draw->_backSurface); + _plettre->drawString("English" , 238, 70, 10, 15, true, *_vm->_draw->_backSurface); + _plettre->drawString("Italiano" , 43, 128, 10, 15, true, *_vm->_draw->_backSurface); + _plettre->drawString("Espa\244ol" , 136, 128, 10, 15, true, *_vm->_draw->_backSurface); + _plettre->drawString("English" , 238, 128, 10, 15, true, *_vm->_draw->_backSurface); + + _vm->_draw->forceBlit(); +} + +void OnceUpon::anPlayAnimalName(const Common::String &animal, uint language) { + // Sound file to play + Common::String soundFile = animal + "_" + kLanguageSuffixLong[language] + ".snd"; + + // Get the name of the animal + TXTFile *names = loadTXT(animal + ".anm", TXTFile::kFormatString); + Common::String name = names->getLines()[language].text; + delete names; + + // It should be centered on the screen + const int nameX = 160 - (name.size() * _plettre->getCharWidth()) / 2; + + // Backup the screen surface + Surface backup(162, 23, 1); + backup.blit(*_vm->_draw->_backSurface, 78, 123, 239, 145, 0, 0); + + // Draw the name border + Surface nameBorder(162, 23, 1); + _vm->_video->drawPackedSprite("mot.cmp", nameBorder); + _vm->_draw->_backSurface->blit(nameBorder, 0, 0, 161, 22, 78, 123); + + // Print the animal name + _plettre->drawString(name, nameX, 129, 10, 0, true, *_vm->_draw->_backSurface); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 78, 123, 239, 145); + + playSoundFile(soundFile); + + // Restore the screen + _vm->_draw->_backSurface->blit(backup, 0, 0, 161, 22, 78, 123); + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 78, 123, 239, 145); } void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index efc2710d67..ff7266e9f3 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -38,6 +38,8 @@ namespace OnceUpon { class OnceUpon : public PreGob { public: + static const uint kLanguageCount = 5; + OnceUpon(GobEngine *vm); ~OnceUpon(); @@ -74,7 +76,7 @@ protected: int16 left, top, right, bottom; int16 srcLeft, srcTop, srcRight, srcBottom; int16 dstX, dstY; - int id; + uint id; }; static const uint kSectionCount = 15; @@ -100,6 +102,8 @@ protected: MenuAction doMenu(MenuType type); + void doAnimalNames(uint count, const MenuButton *buttons, const char * const *names); + void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y) const; @@ -114,9 +118,12 @@ protected: uint8 _section; private: - static const MenuButton kMainMenuDifficultyButton[3]; - static const MenuButton kSectionButtons[4]; - static const MenuButton kIngameButtons[3]; + static const MenuButton kMainMenuDifficultyButton[]; + static const MenuButton kSectionButtons[]; + static const MenuButton kIngameButtons[]; + + static const MenuButton kAnimalNamesBack; + static const MenuButton kLanguageButtons[]; static const char *kSound[kSoundMAX]; @@ -153,11 +160,15 @@ private: void clearMenuIngame(const Surface &background); - Difficulty checkDifficultyButton(int16 x, int16 y) const; - bool checkAnimalsButton (int16 x, int16 y) const; - int8 checkSectionButton (int16 x, int16 y) const; - int8 checkIngameButton (int16 x, int16 y) const; + int checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue = -1) const; + void drawButton(Surface &dest, const Surface &src, const MenuButton &button) const; + void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const; + void drawButtonBorder(const MenuButton &button, uint8 color); + // Animal names helpers + void anSetupChooser(); + void anSetupNames(const MenuButton &animal); + void anPlayAnimalName(const Common::String &animal, uint language); bool _openedArchives; diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index f39a7a112e..675958035d 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -151,23 +151,28 @@ void PreGob::loadSounds(const char * const *sounds, uint soundCount) { _sounds.resize(soundCount); - for (uint i = 0; i < soundCount; i++) { - int32 size; - byte *data = _vm->_dataIO->getFile(sounds[i], size); - - if (!data || !_sounds[i].load(SOUND_SND, data, size)) { - delete data; - - warning("PreGob::loadSounds(): Failed to load sound \"%s\"", sounds[i]); - continue; - } - } + for (uint i = 0; i < soundCount; i++) + loadSound(_sounds[i], sounds[i]); } void PreGob::freeSounds() { _sounds.clear(); } +bool PreGob::loadSound(SoundDesc &sound, const Common::String &file) const { + int32 size; + byte *data = _vm->_dataIO->getFile(file, size); + + if (!data || !sound.load(SOUND_SND, data, size)) { + delete data; + + warning("PreGob::loadSound(): Failed to load sound \"%s\"", file.c_str()); + return false; + } + + return true; +} + void PreGob::playSound(uint sound, int16 frequency, int16 repCount) { if (sound >= _sounds.size()) return; @@ -179,6 +184,29 @@ void PreGob::stopSound() { _vm->_sound->blasterStop(0); } +void PreGob::playSoundFile(const Common::String &file, int16 frequency, int16 repCount, bool interruptible) { + stopSound(); + + SoundDesc sound; + if (!loadSound(sound, file)) + return; + + _vm->_sound->blasterPlay(&sound, repCount, frequency); + + _vm->_util->forceMouseUp(); + + bool finished = false; + while (!_vm->shouldQuit() && !finished && _vm->_sound->blasterPlayingSound()) { + endFrame(true); + + finished = hasInput(); + } + + _vm->_util->forceMouseUp(); + + stopSound(); +} + void PreGob::endFrame(bool doInput) { _vm->_draw->blitInvalidated(); _vm->_util->waitEndFrame(); diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 477aec6dc8..a1a3d65a58 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -83,6 +83,8 @@ protected: void playSound(uint sound, int16 frequency = 0, int16 repCount = 0); void stopSound(); + void playSoundFile(const Common::String &file, int16 frequency = 0, int16 repCount = 0, bool interruptible = true); + void endFrame(bool doInput); int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); @@ -103,6 +105,9 @@ protected: GobEngine *_vm; private: + bool loadSound(SoundDesc &sound, const Common::String &file) const; + + bool _fadedOut; ///< Did we fade out? Common::Array _sounds; -- cgit v1.2.3 From 24644c0012fb46bd77c6c24346f85c984418fb3b Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 04:04:41 +0200 Subject: GOB: Implement the Once Upon A Time "Bye Bye" screen --- engines/gob/pregob/onceupon/abracadabra.cpp | 2 +- engines/gob/pregob/onceupon/babayaga.cpp | 2 +- engines/gob/pregob/onceupon/onceupon.cpp | 16 ++++++++++++++++ engines/gob/pregob/onceupon/onceupon.h | 2 ++ 4 files changed, 20 insertions(+), 2 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 781d683ef0..5a5e407774 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -102,7 +102,7 @@ void Abracadabra::run() { mainLoop(); if (!_vm->shouldQuit()) - warning("Abracadabra::run(): TODO: Show \"Bye Bye\""); + showByeBye(); } void Abracadabra::mainLoop() { diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 34f674107c..9475ac4b05 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -102,7 +102,7 @@ void BabaYaga::run() { mainLoop(); if (!_vm->shouldQuit()) - warning("BabaYaga::run(): TODO: Show \"Bye Bye\""); + showByeBye(); } void BabaYaga::mainLoop() { diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index b7bf2c3f5a..6b90e9ba00 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -609,6 +609,22 @@ void OnceUpon::showChapter(int chapter) { fadeOut(); } +void OnceUpon::showByeBye() { + fadeOut(); + hideCursor(); + clearScreen(); + setGamePalette(1); + + _plettre->drawString("Bye Bye....", 140, 80, 2, 0, true, *_vm->_draw->_backSurface); + _vm->_draw->forceBlit(); + + fadeIn(); + + _vm->_util->longDelay(1000); + + fadeOut(); +} + OnceUpon::MenuAction OnceUpon::doMenu(MenuType type) { bool cursorVisible = isCursorVisible(); diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index ff7266e9f3..6f8b67a627 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -100,6 +100,8 @@ protected: void showChapter(int chapter); ///< Show a chapter intro text. + void showByeBye(); ///< Show the "bye bye" screen + MenuAction doMenu(MenuType type); void doAnimalNames(uint count, const MenuButton *buttons, const char * const *names); -- cgit v1.2.3 From 305ab6847a6c3467ab02ea3f0798e300d82c89ed Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 04:18:12 +0200 Subject: GOB: Reorganize and clean up PreGob / Once Upon A Time --- engines/gob/pregob/onceupon/abracadabra.cpp | 28 +-- engines/gob/pregob/onceupon/abracadabra.h | 6 +- engines/gob/pregob/onceupon/babayaga.cpp | 28 +-- engines/gob/pregob/onceupon/babayaga.h | 6 +- engines/gob/pregob/onceupon/onceupon.cpp | 355 ++++++++++++++++------------ engines/gob/pregob/onceupon/onceupon.h | 221 +++++++++++------ engines/gob/pregob/pregob.h | 50 +++- 7 files changed, 424 insertions(+), 270 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 5a5e407774..2e4b5f21e7 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -80,7 +80,6 @@ const char *Abracadabra::kAnimalNames[] = { Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) { - setAnimalsButton(&kAnimalsButtons); } Abracadabra::~Abracadabra() { @@ -99,28 +98,13 @@ void Abracadabra::run() { if (_vm->shouldQuit()) return; - mainLoop(); - - if (!_vm->shouldQuit()) - showByeBye(); -} + // Handle the start menu + doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); + if (_vm->shouldQuit()) + return; -void Abracadabra::mainLoop() { - clearScreen(); - - MenuType mainMenu = kMenuTypeMainStart; - - while (!_vm->shouldQuit()) { - MenuAction action = doMenu(mainMenu); - if (action == kMenuActionPlay) - warning("Abracadabra::mainLoop(): TODO: Play"); - else if (action == kMenuActionRestart) - warning("Abracadabra::mainLoop(): TODO: Restart"); - else if (action == kMenuActionAnimals) - doAnimalNames(ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); - else if (action == kMenuActionQuit) - break; - } + // Play the actual game + playGame(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h index 5f3a1ba634..f2075fc750 100644 --- a/engines/gob/pregob/onceupon/abracadabra.h +++ b/engines/gob/pregob/onceupon/abracadabra.h @@ -37,13 +37,13 @@ public: void run(); private: + /** Definition of the menu button that leads to the animal names screen. */ static const MenuButton kAnimalsButtons; + /** Definition of the buttons that make up the animals in the animal names screen. */ static const MenuButton kAnimalButtons[]; + /** File prefixes for the name of each animal. */ static const char *kAnimalNames[]; - - - void mainLoop(); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 9475ac4b05..6f27f469e3 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -80,7 +80,6 @@ const char *BabaYaga::kAnimalNames[] = { BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) { - setAnimalsButton(&kAnimalsButtons); } BabaYaga::~BabaYaga() { @@ -99,28 +98,13 @@ void BabaYaga::run() { if (_vm->shouldQuit()) return; - mainLoop(); - - if (!_vm->shouldQuit()) - showByeBye(); -} + // Handle the start menu + doStartMenu(&kAnimalsButtons, ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); + if (_vm->shouldQuit()) + return; -void BabaYaga::mainLoop() { - clearScreen(); - - MenuType mainMenu = kMenuTypeMainStart; - - while (!_vm->shouldQuit()) { - MenuAction action = doMenu(mainMenu); - if (action == kMenuActionPlay) - warning("BabaYaga::mainLoop(): TODO: Play"); - else if (action == kMenuActionRestart) - warning("BabaYaga::mainLoop(): TODO: Restart"); - else if (action == kMenuActionAnimals) - doAnimalNames(ARRAYSIZE(kAnimalButtons), kAnimalButtons, kAnimalNames); - else if (action == kMenuActionQuit) - break; - } + // Play the actual game + playGame(); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h index de42f8e8fe..181b6f4d54 100644 --- a/engines/gob/pregob/onceupon/babayaga.h +++ b/engines/gob/pregob/onceupon/babayaga.h @@ -37,13 +37,13 @@ public: void run(); private: + /** Definition of the menu button that leads to the animal names screen. */ static const MenuButton kAnimalsButtons; + /** Definition of the buttons that make up the animals in the animal names screen. */ static const MenuButton kAnimalButtons[]; + /** File prefixes for the name of each animal. */ static const char *kAnimalNames[]; - - - void mainLoop(); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 6b90e9ba00..785d78b769 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -132,8 +132,17 @@ const char *OnceUpon::kSound[kSoundMAX] = { }; -OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _jeudak(0), _lettre(0), _plettre(0), _glettre(0), - _openedArchives(false), _animalsButton(0) { +OnceUpon::ScreenBackup::ScreenBackup() : palette(-1), changedCursor(false), cursorVisible(false) { + screen = new Surface(320, 200, 1); +} + +OnceUpon::ScreenBackup::~ScreenBackup() { + delete screen; +} + + +OnceUpon::OnceUpon(GobEngine *vm) : PreGob(vm), _openedArchives(false), + _jeudak(0), _lettre(0), _plettre(0), _glettre(0) { } @@ -144,6 +153,8 @@ OnceUpon::~OnceUpon() { void OnceUpon::init() { deinit(); + // Open data files + bool hasSTK1 = _vm->_dataIO->openArchive("stk1.stk", true); bool hasSTK2 = _vm->_dataIO->openArchive("stk2.stk", true); bool hasSTK3 = _vm->_dataIO->openArchive("stk3.stk", true); @@ -153,6 +164,8 @@ void OnceUpon::init() { _openedArchives = true; + // Open fonts + _jeudak = _vm->_draw->loadFont("jeudak.let"); _lettre = _vm->_draw->loadFont("lettre.let"); _plettre = _vm->_draw->loadFont("plettre.let"); @@ -162,6 +175,8 @@ void OnceUpon::init() { error("OnceUpon::OnceUpon(): Failed to fonts (%d, %d, %d, %d)", _jeudak != 0, _lettre != 0, _plettre != 0, _glettre != 0); + // Verify the language + if (_vm->_global->_language == kLanguageAmerican) _vm->_global->_language = kLanguageBritish; @@ -171,17 +186,25 @@ void OnceUpon::init() { "please contact the ScummVM team with details about this version.\n" "Thanks", _vm->getLangDesc(_vm->_global->_language)); - loadSounds(kSound, kSoundMAX); + // Load all our sounds and init the screen + loadSounds(kSound, kSoundMAX); initScreen(); + // We start with an invalid palette + _palette = -1; + + // We start with no selected difficulty and at section 0 _difficulty = kDifficultyMAX; _section = 0; } void OnceUpon::deinit() { + // Free sounds freeSounds(); + // Free fonts + delete _jeudak; delete _lettre; delete _plettre; @@ -192,6 +215,8 @@ void OnceUpon::deinit() { _plettre = 0; _glettre = 0; + // Close archives + if (_openedArchives) { _vm->_dataIO->closeArchive(true); _vm->_dataIO->closeArchive(true); @@ -201,29 +226,115 @@ void OnceUpon::deinit() { _openedArchives = false; } -void OnceUpon::setAnimalsButton(const MenuButton *animalsButton) { - _animalsButton = animalsButton; -} - -void OnceUpon::setCopyProtectionPalette() { - setPalette(kCopyProtectionPalette, kPaletteSize); -} - void OnceUpon::setGamePalette(uint palette) { if (palette >= kPaletteCount) return; + _palette = palette; + setPalette(kGamePalettes[palette], kPaletteSize); } void OnceUpon::setGameCursor() { Surface cursor(320, 16, 1); + // Set the default game cursor _vm->_video->drawPackedSprite("icon.cmp", cursor); - setCursor(cursor, 105, 0, 120, 15, 0, 0); } +void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { + ani.setAnimation(state); + ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); + ani.setPause(pause); + ani.setVisible(true); + ani.setPosition(); +} + +void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, + int16 x, int16 y) const { + + // A special way of drawing something: + // Draw every other line "downwards", wait a bit after each line + // Then, draw the remaining lines "upwards" and again wait a bit after each line. + + if (_vm->shouldQuit()) + return; + + const int16 width = right - left + 1; + const int16 height = bottom - top + 1; + + if ((width <= 0) || (height <= 0)) + return; + + // Draw the even lines downwards + for (int16 i = 0; i < height; i += 2) { + if (_vm->shouldQuit()) + return; + + _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); + _vm->_draw->blitInvalidated(); + + _vm->_util->longDelay(1); + } + + // Draw the odd lines upwards + for (int16 i = (height & 1) ? height : (height - 1); i >= 0; i -= 2) { + if (_vm->shouldQuit()) + return; + + _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); + _vm->_draw->blitInvalidated(); + + _vm->_util->longDelay(1); + } +} + +void OnceUpon::backupScreen(ScreenBackup &backup, bool setDefaultCursor) { + // Backup the screen and palette + backup.screen->blit(*_vm->_draw->_backSurface); + backup.palette = _palette; + + // Backup the cursor + + backup.cursorVisible = isCursorVisible(); + + backup.changedCursor = false; + if (setDefaultCursor) { + backup.changedCursor = true; + + addCursor(); + setGameCursor(); + } +} + +void OnceUpon::restoreScreen(ScreenBackup &backup) { + if (_vm->shouldQuit()) + return; + + // Restore the screen + _vm->_draw->_backSurface->blit(*backup.screen); + _vm->_draw->forceBlit(); + + // Restore the palette + if (backup.palette >= 0) + setGamePalette(backup.palette); + + // Restore the cursor + + if (!backup.cursorVisible) + hideCursor(); + + if (backup.changedCursor) + removeCursor(); + + backup.changedCursor = false; +} + void OnceUpon::fixTXTStrings(TXTFile &txt) const { TXTFile::LineArray &lines = txt.getLines(); for (uint i = 0; i < lines.size(); i++) @@ -251,18 +362,22 @@ enum CopyProtectionState { bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]) { fadeOut(); - setCopyProtectionPalette(); + setPalette(kCopyProtectionPalette, kPaletteSize); + // Load the copy protection sprites Surface sprites[2] = {Surface(320, 200, 1), Surface(320, 200, 1)}; _vm->_video->drawPackedSprite("grille1.cmp", sprites[0]); _vm->_video->drawPackedSprite("grille2.cmp", sprites[1]); + // Load the clown animation ANIFile ani (_vm, "grille.ani", 320); ANIObject clown(ani); + // Set the copy protection cursor setCursor(sprites[1], 5, 110, 20, 134, 3, 0); + // We start with 2 tries left, not having a correct answer and the copy protection not set up yet CopyProtectionState state = kCPStateSetup; uint8 triesLeft = 2; @@ -423,31 +538,6 @@ void OnceUpon::cpWrong() { clearScreen(); } -void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { - ani.setAnimation(state); - ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); - ani.setPause(pause); - ani.setVisible(true); - ani.setPosition(); -} - -void OnceUpon::showWait(uint palette) { - // Show the loading floppy - - fadeOut(); - clearScreen(); - setGamePalette(palette); - - Surface wait(320, 43, 1); - - _vm->_video->drawPackedSprite("wait.cmp", wait); - _vm->_draw->_backSurface->blit(wait, 0, 0, 72, 33, 122, 84); - - _vm->_draw->forceBlit(); - - fadeIn(); -} - void OnceUpon::showIntro() { // Show all intro parts @@ -475,6 +565,23 @@ void OnceUpon::showIntro() { showWait(17); } +void OnceUpon::showWait(uint palette) { + // Show the loading floppy + + fadeOut(); + clearScreen(); + setGamePalette(palette); + + Surface wait(320, 43, 1); + + _vm->_video->drawPackedSprite("wait.cmp", wait); + _vm->_draw->_backSurface->blit(wait, 0, 0, 72, 33, 122, 84); + + _vm->_draw->forceBlit(); + + fadeIn(); +} + void OnceUpon::showQuote() { // Show the quote about fairytales @@ -534,6 +641,8 @@ void OnceUpon::showTitle() { } void OnceUpon::playTitleMusic() { + // Look at what platform this is and play the appropriate music type + if (_vm->getPlatform() == Common::kPlatformPC) playTitleMusicDOS(); else if (_vm->getPlatform() == Common::kPlatformAmiga) @@ -571,6 +680,8 @@ void OnceUpon::playTitleMusicAtariST() { } void OnceUpon::stopTitleMusic() { + // Just stop everything + _vm->_sound->adlibSetRepeating(0); _vm->_sound->blasterRepeatComposition(0); @@ -625,55 +736,29 @@ void OnceUpon::showByeBye() { fadeOut(); } -OnceUpon::MenuAction OnceUpon::doMenu(MenuType type) { - bool cursorVisible = isCursorVisible(); - - // Set the cursor - addCursor(); - setGameCursor(); - - // Backup the screen - Surface screenBackup(320, 200, 1); - screenBackup.blit(*_vm->_draw->_backSurface); - - // Handle the specific menu - MenuAction action; - if (type == kMenuTypeMainStart) - action = doMenuMainStart(); - else if (type == kMenuTypeMainIngame) - action = doMenuMainIngame(); - else if (type == kMenuTypeIngame) - action = doMenuIngame(); - else - error("OnceUpon::doMenu(): No such menu %d", type); - - if (_vm->shouldQuit()) - return action; - - // The ingame menu cleans itself up in a special way - if (type == kMenuTypeIngame) - clearMenuIngame(screenBackup); - - // The main menus fade out - if ((type == kMenuTypeMainStart) || (type == kMenuTypeMainIngame)) - fadeOut(); - - // Restore the screen - _vm->_draw->_backSurface->blit(screenBackup); - _vm->_draw->forceBlit(); +void OnceUpon::doStartMenu(const MenuButton *animalsButton, uint animalCount, + const MenuButton *animalButtons, const char * const *animalNames) { + clearScreen(); - // Restore the cursor - if (!cursorVisible) - hideCursor(); - removeCursor(); + // Wait until we clicked on of the difficulty buttons and are ready to start playing + while (!_vm->shouldQuit()) { + MenuAction action = handleStartMenu(animalsButton); + if (action == kMenuActionPlay) + break; - return action; + // If we pressed the "listen to animal names" button, handle that screen + if (action == kMenuActionAnimals) + handleAnimalNames(animalCount, animalButtons, animalNames); + } } -OnceUpon::MenuAction OnceUpon::doMenuMainStart() { +OnceUpon::MenuAction OnceUpon::handleStartMenu(const MenuButton *animalsButton) { + ScreenBackup screenBackup; + backupScreen(screenBackup, true); + fadeOut(); setGamePalette(17); - drawMenuMainStart(); + drawStartMenu(animalsButton); showCursor(); fadeIn(); @@ -702,22 +787,28 @@ OnceUpon::MenuAction OnceUpon::doMenuMainStart() { _difficulty = (Difficulty)diff; action = kMenuActionPlay; - drawMenuMainStart(); + drawStartMenu(animalsButton); _vm->_util->longDelay(1000); } - if (_animalsButton && (checkButton(_animalsButton, 1, mouseX, mouseY) != -1)) + if (animalsButton && (checkButton(animalsButton, 1, mouseX, mouseY) != -1)) action = kMenuActionAnimals; } + fadeOut(); + restoreScreen(screenBackup); + return action; } -OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { +OnceUpon::MenuAction OnceUpon::handleMainMenu() { + ScreenBackup screenBackup; + backupScreen(screenBackup, true); + fadeOut(); setGamePalette(17); - drawMenuMainIngame(); + drawMainMenu(); showCursor(); fadeIn(); @@ -745,7 +836,7 @@ OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { if ((diff >= 0) && (diff != (int)_difficulty)) { _difficulty = (Difficulty)diff; - drawMenuMainIngame(); + drawMainMenu(); } // If we clicked on a section button, restart the game from this section @@ -757,11 +848,17 @@ OnceUpon::MenuAction OnceUpon::doMenuMainIngame() { } + fadeOut(); + restoreScreen(screenBackup); + return action; } -OnceUpon::MenuAction OnceUpon::doMenuIngame() { - drawMenuIngame(); +OnceUpon::MenuAction OnceUpon::handleIngameMenu() { + ScreenBackup screenBackup; + backupScreen(screenBackup, true); + + drawIngameMenu(); showCursor(); MenuAction action = kMenuActionNone; @@ -791,20 +888,23 @@ OnceUpon::MenuAction OnceUpon::doMenuIngame() { } + clearIngameMenu(*screenBackup.screen); + restoreScreen(screenBackup); + return action; } -void OnceUpon::drawMenuMainStart() { +void OnceUpon::drawStartMenu(const MenuButton *animalsButton) { // Draw the background _vm->_video->drawPackedSprite("menu2.cmp", *_vm->_draw->_backSurface); // Draw the "Listen to animal names" button - if (_animalsButton) { + if (animalsButton) { Surface elements(320, 38, 1); _vm->_video->drawPackedSprite("elemenu.cmp", elements); - _vm->_draw->_backSurface->fillRect(_animalsButton->left , _animalsButton->top, - _animalsButton->right, _animalsButton->bottom, 0); - drawButton(*_vm->_draw->_backSurface, elements, *_animalsButton); + _vm->_draw->_backSurface->fillRect(animalsButton->left , animalsButton->top, + animalsButton->right, animalsButton->bottom, 0); + drawButton(*_vm->_draw->_backSurface, elements, *animalsButton); } // Highlight the current difficulty @@ -813,7 +913,7 @@ void OnceUpon::drawMenuMainStart() { _vm->_draw->forceBlit(); } -void OnceUpon::drawMenuMainIngame() { +void OnceUpon::drawMainMenu() { // Draw the background _vm->_video->drawPackedSprite("menu.cmp", *_vm->_draw->_backSurface); @@ -837,11 +937,11 @@ void OnceUpon::drawMenuMainIngame() { _vm->_draw->forceBlit(); } -void OnceUpon::drawMenuIngame() { +void OnceUpon::drawIngameMenu() { Surface menu(320, 34, 1); _vm->_video->drawPackedSprite("icon.cmp", menu); - // Draw the menu in a special way + // Draw the menu in a special way, button by button for (uint i = 0; i < ARRAYSIZE(kIngameButtons); i++) { const MenuButton &button = kIngameButtons[i]; @@ -863,16 +963,15 @@ void OnceUpon::drawMenuDifficulty() { difficulties->draw((uint) _difficulty, *_vm->_draw->_backSurface, &_plettre, 1); // Draw a border around the current difficulty - _vm->_draw->_backSurface->drawRect(kMainMenuDifficultyButton[_difficulty].left, - kMainMenuDifficultyButton[_difficulty].top, - kMainMenuDifficultyButton[_difficulty].right, - kMainMenuDifficultyButton[_difficulty].bottom, - difficulties->getLines()[_difficulty].color); + drawButtonBorder(kMainMenuDifficultyButton[_difficulty], difficulties->getLines()[_difficulty].color); delete difficulties; } -void OnceUpon::clearMenuIngame(const Surface &background) { +void OnceUpon::clearIngameMenu(const Surface &background) { + if (_vm->shouldQuit()) + return; + // Find the area encompassing the whole ingame menu int16 left = 0x7FFF; @@ -900,6 +999,8 @@ void OnceUpon::clearMenuIngame(const Surface &background) { } int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue) const { + // Look through all buttons, and return the ID of the button we're in + for (uint i = 0; i < count; i++) { const MenuButton &button = buttons[i]; @@ -907,6 +1008,7 @@ int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 return (int)button.id; } + // We're in none of these buttons, return the fail value return failValue; } @@ -931,12 +1033,12 @@ void OnceUpon::drawButtonBorder(const MenuButton &button, uint8 color) { } enum AnimalNamesState { - kANStateChoose, - kANStateNames, - kANStateFinish + kANStateChoose, // We're in the animal chooser + kANStateNames, // We're in the language chooser + kANStateFinish // We're finished }; -void OnceUpon::doAnimalNames(uint count, const MenuButton *buttons, const char * const *names) { +void OnceUpon::handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names) { fadeOut(); clearScreen(); setGamePalette(19); @@ -1100,45 +1202,8 @@ void OnceUpon::anPlayAnimalName(const Common::String &animal, uint language) { _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 78, 123, 239, 145); } -void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, - int16 x, int16 y) const { - - // A special way of drawing something: - // Draw every other line "downwards", wait a bit after each line - // Then, draw the remaining lines "upwards" and again wait a bit after each line. - - if (_vm->shouldQuit()) - return; - - const int16 width = right - left + 1; - const int16 height = bottom - top + 1; - - if ((width <= 0) || (height <= 0)) - return; - - for (int16 i = 0; i < height; i += 2) { - if (_vm->shouldQuit()) - return; - - _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); - - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); - _vm->_draw->blitInvalidated(); - - _vm->_util->longDelay(1); - } - - for (int16 i = (height & 1) ? height : (height - 1); i >= 0; i -= 2) { - if (_vm->shouldQuit()) - return; - - _vm->_draw->_backSurface->blit(src, left, top + i, right, top + i, x, y + i); - - _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, x, y + i, x + width - 1, y + 1); - _vm->_draw->blitInvalidated(); - - _vm->_util->longDelay(1); - } +void OnceUpon::playGame() { + warning("OnceUpon::playGame(): TODO"); } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 6f8b67a627..08c8803c67 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -38,18 +38,67 @@ namespace OnceUpon { class OnceUpon : public PreGob { public: + /** Number of languages we support. */ static const uint kLanguageCount = 5; + OnceUpon(GobEngine *vm); ~OnceUpon(); + protected: - enum MenuType { - kMenuTypeMainStart = 0, ///< The big main menu at game start. - kMenuTypeMainIngame, ///< The big main menu during the game. - kMenuTypeIngame ///< The small popup menu during the game. + /** A description of a menu button. */ + struct MenuButton { + bool needDraw; ///< Does the button need drawing? + + int16 left; ///< Left coordinate of the button. + int16 top; ///< Top coordinate of the button. + int16 right; ///< Right coordinate of the button. + int16 bottom; ///< Bottom coordinate of the button. + + int16 srcLeft; ///< Left coordinate of the button's sprite. + int16 srcTop; ///< Top coordinate of the button's sprite. + int16 srcRight; ///< Right coordinate of the button's sprite. + int16 srcBottom; ///< Right coordinate of the button's sprite. + + int16 dstX; ///< Destination X coordinate of the button's sprite. + int16 dstY; ///< Destination Y coordinate of the button's sprite. + + uint id; ///< The button's ID. }; + + void init(); + void deinit(); + + /** Handle the copy protection. + * + * @param colors Colors the copy protection animals can be. + * @param shapes The shape that's the correct answer for each animal in each color. + * @param obfuscate Extra obfuscate table. correctShape = shapes[colors][obfuscate[animal]]. + * @return true if the user guessed the correct shape, false otherwise. + */ + bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + + /** Show the intro. */ + void showIntro(); + + /** Handle the start menu. + * + * @param animalsButton Definition of the menu button that leads to the animal names screen. Can be 0. + * @param animalCount Number of animals in the animal names screen. + * @param animalButtons Definition of the buttons that make up the animals in the animal names screen. + * @param animalNames File prefixes for the name of each animal. + */ + void doStartMenu(const MenuButton *animalsButton, uint animalCount, + const MenuButton *animalButtons, const char * const *animalNames); + + /** Play the game proper. */ + void playGame(); + + +private: + /** All actions a user can request in a menu. */ enum MenuAction { kMenuActionNone = 0, ///< No action. kMenuActionAnimals , ///< Do the animal names. @@ -59,6 +108,7 @@ protected: kMenuActionQuit ///< Quit the game. }; + /** Difficulty levels. */ enum Difficulty { kDifficultyBeginner = 0, kDifficultyIntermediate = 1, @@ -66,115 +116,148 @@ protected: kDifficultyMAX }; + /** The different sounds common in the game. */ enum Sound { kSoundClick = 0, kSoundMAX }; - struct MenuButton { - bool needDraw; - int16 left, top, right, bottom; - int16 srcLeft, srcTop, srcRight, srcBottom; - int16 dstX, dstY; - uint id; - }; + /** A complete screen backup. */ + struct ScreenBackup { + Surface *screen; ///< Screen contents. + int palette; ///< Screen palette. - static const uint kSectionCount = 15; + bool changedCursor; ///< Did we change the cursor? + bool cursorVisible; ///< Was the cursor visible? + ScreenBackup(); + ~ScreenBackup(); + }; - void init(); - void deinit(); - void setAnimalsButton(const MenuButton *animalsButton); + /** The number of game sections. */ + static const uint kSectionCount = 15; - void setGamePalette(uint palette); - void setGameCursor(); + static const MenuButton kMainMenuDifficultyButton[]; ///< Difficulty buttons. + static const MenuButton kSectionButtons[]; ///< Section buttons. - Common::String fixString(const Common::String &str) const; - void fixTXTStrings(TXTFile &txt) const; + static const MenuButton kIngameButtons[]; ///< Ingame menu buttons. - bool doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4]); + static const MenuButton kAnimalNamesBack; ///< "Back" button in the animal names screens. + static const MenuButton kLanguageButtons[]; ///< Language buttons in the animal names screen. - void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen. - void showIntro(); ///< Show the whole intro. + /** All general game sounds we know about. */ + static const char *kSound[kSoundMAX]; - void showChapter(int chapter); ///< Show a chapter intro text. - void showByeBye(); ///< Show the "bye bye" screen + // -- General helpers -- - MenuAction doMenu(MenuType type); + void setGamePalette(uint palette); ///< Set a game palette. + void setGameCursor(); ///< Set the default game cursor. - void doAnimalNames(uint count, const MenuButton *buttons, const char * const *names); + /** Set the state of an ANIObject. */ + void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; + /** Draw this sprite in a fancy, animated line-by-line way. */ void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y) const; + /** Backup the screen contents. */ + void backupScreen(ScreenBackup &backup, bool setDefaultCursor = false); + /** Restore the screen contents with a previously made backup. */ + void restoreScreen(ScreenBackup &backup); - // Fonts - Font *_jeudak; - Font *_lettre; - Font *_plettre; - Font *_glettre; + Common::String fixString(const Common::String &str) const; ///< Fix a string if necessary. + void fixTXTStrings(TXTFile &txt) const; ///< Fix all strings in a TXT. - Difficulty _difficulty; - uint8 _section; -private: - static const MenuButton kMainMenuDifficultyButton[]; - static const MenuButton kSectionButtons[]; - static const MenuButton kIngameButtons[]; + // -- Copy protection helpers -- - static const MenuButton kAnimalNamesBack; - static const MenuButton kLanguageButtons[]; + /** Set up the copy protection. */ + int8 cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20], + const uint8 obfuscate[4], const Surface sprites[2]); + /** Find the shape under these coordinates. */ + int8 cpFindShape(int16 x, int16 y) const; + /** Display the "You are wrong" screen. */ + void cpWrong(); - static const char *kSound[kSoundMAX]; + // -- Show different game screens -- - void setCopyProtectionPalette(); + void showWait(uint palette = 0xFFFF); ///< Show the wait / loading screen. + void showQuote(); ///< Show the quote about fairytales. + void showTitle(); ///< Show the Once Upon A Time title. + void showChapter(int chapter); ///< Show a chapter intro text. + void showByeBye(); ///< Show the "bye bye" screen. - void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; + /** Handle the "listen to animal names" part. */ + void handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names); - // Copy protection helpers - int8 cpSetup(const uint8 colors[7], const uint8 shapes[7 * 20], const uint8 obfuscate[4], const Surface sprites[2]); - int8 cpFindShape(int16 x, int16 y) const; - void cpWrong(); - // Intro parts - void showQuote(); - void showTitle(); - - // Title music - void playTitleMusic(); - void playTitleMusicDOS(); - void playTitleMusicAmiga(); - void playTitleMusicAtariST(); - void stopTitleMusic(); - - // Menu helpers - MenuAction doMenuMainStart(); - MenuAction doMenuMainIngame(); - MenuAction doMenuIngame(); - - void drawMenuMainStart(); - void drawMenuMainIngame(); - void drawMenuIngame(); + // -- Title music helpers -- + + void playTitleMusic(); ///< Play the title music. + void playTitleMusicDOS(); ///< Play the title music of the DOS version. + void playTitleMusicAmiga(); ///< Play the title music of the Amiga version. + void playTitleMusicAtariST(); ///< Play the title music of the Atari ST version. + void stopTitleMusic(); ///< Stop the title music. + + + // -- Menu helpers -- + + MenuAction handleStartMenu(const MenuButton *animalsButton); ///< Handle the start menu. + MenuAction handleMainMenu(); ///< Handle the main menu. + MenuAction handleIngameMenu(); ///< Handle the ingame menu. + + void drawStartMenu(const MenuButton *animalsButton); ///< Draw the start menu. + void drawMainMenu(); ///< Draw the main menu. + void drawIngameMenu(); ///< Draw the ingame menu. + + /** Draw the difficulty label. */ void drawMenuDifficulty(); - void clearMenuIngame(const Surface &background); + /** Clear the ingame menu in an animated way. */ + void clearIngameMenu(const Surface &background); + + // -- Menu button helpers -- + + /** Find the button under these coordinates. */ int checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue = -1) const; - void drawButton(Surface &dest, const Surface &src, const MenuButton &button) const; + + /** Draw a menu button. */ + void drawButton (Surface &dest, const Surface &src, const MenuButton &button) const; + /** Draw multiple menu buttons. */ void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const; + + /** Draw a border around a button. */ void drawButtonBorder(const MenuButton &button, uint8 color); - // Animal names helpers + + // -- Animal names helpers -- + + /** Set up the animal chooser. */ void anSetupChooser(); + /** Set up the language chooser for one animal. */ void anSetupNames(const MenuButton &animal); + /** Play / Display the name of an animal in one language. */ void anPlayAnimalName(const Common::String &animal, uint language); + + /** Did we open the game archives? */ bool _openedArchives; - const MenuButton *_animalsButton; + // Fonts + Font *_jeudak; + Font *_lettre; + Font *_plettre; + Font *_glettre; + + /** The current palette. */ + int _palette; + + Difficulty _difficulty; ///< The current difficulty. + uint8 _section; ///< The current game section. }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index a1a3d65a58..e62a59042b 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -51,7 +51,10 @@ protected: static const char *kLanguageSuffixLong [5]; - void initScreen(); ///< Initialize the game screen. + // -- Graphics -- + + /** Initialize the game screen. */ + void initScreen(); void fadeOut(); ///< Fade to black. void fadeIn(); ///< Fade to the current palette. @@ -65,51 +68,86 @@ protected: */ void setPalette(const byte *palette, uint16 size); ///< Change the palette + /** Add a new cursor that can be manipulated to the stack. */ void addCursor(); + /** Remove the top-most cursor from the stack. */ void removeCursor(); + /** Set the current cursor. */ void setCursor(Surface &sprite, int16 hotspotX, int16 hotspotY); + /** Set the current cursor. */ void setCursor(Surface &sprite, int16 left, int16 top, int16 right, int16 bottom, int16 hotspotX, int16 hotspotY); + /** Show the cursor. */ void showCursor(); + /** Hide the cursor. */ void hideCursor(); + /** Is the cursor currently visible? */ bool isCursorVisible() const; + /** Remove an animation from the screen. */ + void clearAnim(ANIObject &ani); + /** Draw an animation to the screen, advancing it. */ + void drawAnim(ANIObject &ani); + /** Clear and draw an animation to the screen, advancing it. */ + void redrawAnim(ANIObject &ani); + + /** Wait for the frame to end, handling screen updates and optionally update input. */ + void endFrame(bool doInput); + + + // -- Sound -- + + /** Load all sounds that can be played interactively in the game. */ void loadSounds(const char * const *sounds, uint soundCount); + /** Free all loaded sound. */ void freeSounds(); + /** Play a loaded sound. */ void playSound(uint sound, int16 frequency = 0, int16 repCount = 0); + /** Stop all sound playback. */ void stopSound(); + /** Play a sound until it ends or is interrupted by a keypress. */ void playSoundFile(const Common::String &file, int16 frequency = 0, int16 repCount = 0, bool interruptible = true); - void endFrame(bool doInput); + // -- Input -- + + /** Check mouse and keyboard input. */ int16 checkInput(int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + /** Wait for mouse or keyboard input. */ int16 waitInput (int16 &mouseX, int16 &mouseY, MouseButtons &mouseButtons); + /** Wait for mouse or keyboard input, but don't care about what was done with the mouse. */ int16 waitInput(); + /** Did we have mouse or keyboard input? */ bool hasInput(); - void clearAnim(ANIObject &ani); - void drawAnim(ANIObject &ani); - void redrawAnim(ANIObject &ani); + // -- TXT helpers -- + + /** Get the name of a localized file. */ Common::String getLocFile(const Common::String &file) const; + /** Open a TXT file. */ TXTFile *loadTXT(const Common::String &txtFile, TXTFile::Format format) const; + /** Called by loadTXT() to fix strings within the TXT file. */ virtual void fixTXTStrings(TXTFile &txt) const; GobEngine *_vm; private: + /** Load a sound file. */ bool loadSound(SoundDesc &sound, const Common::String &file) const; - bool _fadedOut; ///< Did we fade out? + /** Did we fade out? */ + bool _fadedOut; + /** All loaded sounds. */ Common::Array _sounds; }; -- cgit v1.2.3 From 60f52ab9a0beccccca4958fbcf4d369e6dd22748 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 18:15:38 +0200 Subject: GOB: Add the frame for normal Once Upon A Time game play --- engines/gob/pregob/onceupon/brokenstrings.h | 7 +- engines/gob/pregob/onceupon/onceupon.cpp | 154 +++++++++++++++++++++++++++- engines/gob/pregob/onceupon/onceupon.h | 35 ++++++- 3 files changed, 191 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/brokenstrings.h b/engines/gob/pregob/onceupon/brokenstrings.h index 98dcb720fb..0a40493cc1 100644 --- a/engines/gob/pregob/onceupon/brokenstrings.h +++ b/engines/gob/pregob/onceupon/brokenstrings.h @@ -40,7 +40,12 @@ static const BrokenString kBrokenStringsGerman[] = { { " Fortgeschrittene" , " Fortgeschritten" }, { "die Vespe" , "die Wespe" }, { "das Rhinoceros" , "das Rhinozeros" }, - { "die Heusschrecke" , "die Heuschrecke" } + { "die Heusschrecke" , "die Heuschrecke" }, + { "Das, von Drachen gebrachte" , "Das vom Drachen gebrachte" }, + { "Am Waldesrand es sieht" , "Am Waldesrand sieht es" }, + { " das Kind den Palast." , "das Kind den Palast." }, + { "Am Waldessaum sieht" , "Am Waldesrand sieht" }, + { "tipp auf ESC!" , "dr\201cke ESC!" } }; static const BrokenStringLanguage kBrokenStrings[kLanguageCount] = { diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 785d78b769..fb9629566c 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -131,6 +131,24 @@ const char *OnceUpon::kSound[kSoundMAX] = { "diamant.snd" }; +const OnceUpon::SectionFunc OnceUpon::kSectionFuncs[kSectionCount] = { + &OnceUpon::sectionStork, + &OnceUpon::sectionChapter1, + &OnceUpon::section02, + &OnceUpon::sectionChapter2, + &OnceUpon::section04, + &OnceUpon::sectionChapter3, + &OnceUpon::section06, + &OnceUpon::sectionChapter4, + &OnceUpon::section08, + &OnceUpon::sectionChapter5, + &OnceUpon::section10, + &OnceUpon::sectionChapter6, + &OnceUpon::section12, + &OnceUpon::sectionChapter7, + &OnceUpon::sectionEnd +}; + OnceUpon::ScreenBackup::ScreenBackup() : palette(-1), changedCursor(false), cursorVisible(false) { screen = new Surface(320, 200, 1); @@ -194,6 +212,9 @@ void OnceUpon::init() { // We start with an invalid palette _palette = -1; + // No quit requested at start + _quit = false; + // We start with no selected difficulty and at section 0 _difficulty = kDifficultyMAX; _section = 0; @@ -930,7 +951,7 @@ void OnceUpon::drawMainMenu() { if (!button.needDraw) continue; - if (_section >= (uint)button.id) + if (_section >= (int)button.id) drawButton(*_vm->_draw->_backSurface, elements, button); } @@ -998,6 +1019,41 @@ void OnceUpon::clearIngameMenu(const Surface &background) { drawLineByLine(background, left, top, right, bottom, left, top); } +OnceUpon::MenuAction OnceUpon::doIngameMenu() { + // Show the ingame menu + MenuAction action = handleIngameMenu(); + + if ((action == kMenuActionQuit) || _vm->shouldQuit()) { + + // User pressed the quit button, or quit ScummVM + _quit = true; + return kMenuActionQuit; + + } else if (action == kMenuActionPlay) { + + // User pressed the return to game button + return kMenuActionPlay; + + } else if (kMenuActionMainMenu) { + + // User pressed the return to main menu button + return handleMainMenu(); + } + + return action; +} + +OnceUpon::MenuAction OnceUpon::doIngameMenu(int16 key, MouseButtons mouseButtons) { + if ((key != kKeyEscape) && (mouseButtons != kMouseButtonsRight)) + return kMenuActionNone; + + MenuAction action = doIngameMenu(); + if (action == kMenuActionPlay) + return kMenuActionNone; + + return action; +} + int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue) const { // Look through all buttons, and return the ID of the button we're in @@ -1203,7 +1259,101 @@ void OnceUpon::anPlayAnimalName(const Common::String &animal, uint language) { } void OnceUpon::playGame() { - warning("OnceUpon::playGame(): TODO"); + while (!_vm->shouldQuit() && !_quit) { + // Play a section and advance to the next section if we finished it + if (playSection()) + _section = MIN(_section + 1, kSectionCount - 1); + } + + // If we quit through the game and not through ScummVM, show the "Bye Bye" screen + if (!_vm->shouldQuit()) + showByeBye(); +} + +bool OnceUpon::playSection() { + if ((_section < 0) || (_section >= ARRAYSIZE(kSectionFuncs))) { + _quit = true; + return false; + } + + return (this->*kSectionFuncs[_section])(); +} + +bool OnceUpon::sectionStork() { + warning("OnceUpon::sectionStork(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter1() { + showChapter(1); + return true; +} + +bool OnceUpon::section02() { + warning("OnceUpon::section02(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter2() { + showChapter(2); + return true; +} + +bool OnceUpon::section04() { + warning("OnceUpon::section04(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter3() { + showChapter(3); + return true; +} + +bool OnceUpon::section06() { + warning("OnceUpon::section06(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter4() { + showChapter(4); + return true; +} + +bool OnceUpon::section08() { + warning("OnceUpon::section08(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter5() { + showChapter(5); + return true; +} + +bool OnceUpon::section10() { + warning("OnceUpon::section10(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter6() { + showChapter(6); + return true; +} + +bool OnceUpon::section12() { + warning("OnceUpon::section12(): TODO"); + return true; +} + +bool OnceUpon::sectionChapter7() { + showChapter(7); + return true; +} + +bool OnceUpon::sectionEnd() { + warning("OnceUpon::sectionEnd(): TODO"); + + _quit = true; + return false; } } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 08c8803c67..0cae369758 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -136,7 +136,7 @@ private: /** The number of game sections. */ - static const uint kSectionCount = 15; + static const int kSectionCount = 15; static const MenuButton kMainMenuDifficultyButton[]; ///< Difficulty buttons. static const MenuButton kSectionButtons[]; ///< Section buttons. @@ -149,6 +149,10 @@ private: /** All general game sounds we know about. */ static const char *kSound[kSoundMAX]; + /** Function pointer type for a section handler. */ + typedef bool (OnceUpon::*SectionFunc)(); + /** Section handler function. */ + static const SectionFunc kSectionFuncs[kSectionCount]; // -- General helpers -- @@ -219,6 +223,11 @@ private: /** Clear the ingame menu in an animated way. */ void clearIngameMenu(const Surface &background); + /** Handle the whole ingame menu. */ + MenuAction doIngameMenu(); + /** Handle the whole ingame menu if ESC or right mouse button was pressed. */ + MenuAction doIngameMenu(int16 key, MouseButtons mouseButtons); + // -- Menu button helpers -- @@ -243,6 +252,26 @@ private: /** Play / Display the name of an animal in one language. */ void anPlayAnimalName(const Common::String &animal, uint language); + // -- Game sections -- + + bool playSection(); + + bool sectionStork(); + bool sectionChapter1(); + bool section02(); + bool sectionChapter2(); + bool section04(); + bool sectionChapter3(); + bool section06(); + bool sectionChapter4(); + bool section08(); + bool sectionChapter5(); + bool section10(); + bool sectionChapter6(); + bool section12(); + bool sectionChapter7(); + bool sectionEnd(); + /** Did we open the game archives? */ bool _openedArchives; @@ -256,8 +285,10 @@ private: /** The current palette. */ int _palette; + bool _quit; ///< Did the user request a normal game quit? + Difficulty _difficulty; ///< The current difficulty. - uint8 _section; ///< The current game section. + int _section; ///< The current game section. }; } // End of namespace OnceUpon -- cgit v1.2.3 From df18bc95834837f1f905bfe5613ffd43dfc908f9 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Mon, 2 Jul 2012 21:31:23 +0200 Subject: GOB: Implement parts of the Once Upon A Time end sequence We don't yet support GCT files, so texts are still missing. --- engines/gob/pregob/onceupon/onceupon.cpp | 103 +++++++++++++++++++++++++------ engines/gob/pregob/onceupon/onceupon.h | 10 ++- engines/gob/pregob/pregob.cpp | 62 ++++++++++++++++--- engines/gob/pregob/pregob.h | 37 +++++++++-- 4 files changed, 176 insertions(+), 36 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index fb9629566c..aed1b45e02 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -264,14 +264,6 @@ void OnceUpon::setGameCursor() { setCursor(cursor, 105, 0, 120, 15, 0, 0); } -void OnceUpon::setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const { - ani.setAnimation(state); - ani.setMode(once ? ANIObject::kModeOnce : ANIObject::kModeContinuous); - ani.setPause(pause); - ani.setVisible(true); - ani.setPosition(); -} - void OnceUpon::drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y) const { @@ -374,6 +366,18 @@ Common::String OnceUpon::fixString(const Common::String &str) const { return str; } +enum ClownAnimation { + kClownAnimationStand = 0, + kClownAnimationCheer = 1, + kClownAnimationCry = 2 +}; + +const PreGob::AnimProperties OnceUpon::kClownAnimations[] = { + { 1, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 0, 0, ANIObject::kModeOnce , true, false, false, 0, 0}, + { 6, 0, ANIObject::kModeOnce , true, false, false, 0, 0} +}; + enum CopyProtectionState { kCPStateSetup, // Set up the screen kCPStateWaitUser, // Waiting for the user to pick a shape @@ -392,8 +396,10 @@ bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20 _vm->_video->drawPackedSprite("grille2.cmp", sprites[1]); // Load the clown animation - ANIFile ani (_vm, "grille.ani", 320); - ANIObject clown(ani); + ANIFile ani (_vm, "grille.ani", 320); + ANIList anims; + + loadAnims(anims, ani, 1, &kClownAnimations[kClownAnimationStand]); // Set the copy protection cursor setCursor(sprites[1], 5, 110, 20, 134, 3, 0); @@ -406,20 +412,20 @@ bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20 bool hasCorrect = false; while (!_vm->shouldQuit() && (state != kCPStateFinish)) { - clearAnim(clown); + clearAnim(anims); // Set up the screen if (state == kCPStateSetup) { animalShape = cpSetup(colors, shapes, obfuscate, sprites); - setAnimState(clown, kClownAnimationClownStand, false, false); + setAnim(*anims[0], kClownAnimations[kClownAnimationStand]); state = kCPStateWaitUser; } - drawAnim(clown); + drawAnim(anims); // If we're waiting for the clown and he finished, evaluate if we're finished - if (!clown.isVisible() && (state == kCPStateWaitClown)) + if (!anims[0]->isVisible() && (state == kCPStateWaitClown)) state = (hasCorrect || (--triesLeft == 0)) ? kCPStateFinish : kCPStateSetup; showCursor(); @@ -443,12 +449,14 @@ bool OnceUpon::doCopyProtection(const uint8 colors[7], const uint8 shapes[7 * 20 hasCorrect = guessedShape == animalShape; animalShape = -1; - setAnimState(clown, hasCorrect ? kClownAnimationClownCheer : kClownAnimationClownCry, true, false); + setAnim(*anims[0], kClownAnimations[hasCorrect ? kClownAnimationCheer : kClownAnimationCry]); state = kCPStateWaitClown; } } } + freeAnims(anims); + fadeOut(); hideCursor(); clearScreen(); @@ -625,6 +633,10 @@ void OnceUpon::showQuote() { fadeOut(); } +const PreGob::AnimProperties OnceUpon::kTitleAnimation = { + 8, 0, ANIObject::kModeContinuous, true, false, false, 0, 0 +}; + void OnceUpon::showTitle() { // Show the Once Upon A Time title animation // NOTE: This is currently only a mock-up. The real animation is in "ville.seq". @@ -639,15 +651,15 @@ void OnceUpon::showTitle() { _vm->_video->drawPackedSprite("ville.cmp", *_vm->_draw->_backSurface); _vm->_draw->forceBlit(); - ANIFile ani (_vm, "pres.ani", 320); - ANIObject title(ani); + ANIFile ani (_vm, "pres.ani", 320); + ANIList anims; - setAnimState(title, 8, false, false); + loadAnims(anims, ani, 1, &kTitleAnimation); playTitleMusic(); while (!_vm->shouldQuit()) { - redrawAnim(title); + redrawAnim(anims); fadeIn(); @@ -657,6 +669,8 @@ void OnceUpon::showTitle() { break; } + freeAnims(anims); + fadeOut(); stopTitleMusic(); } @@ -1349,9 +1363,58 @@ bool OnceUpon::sectionChapter7() { return true; } +const PreGob::AnimProperties OnceUpon::kSectionEndAnimations[] = { + { 0, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 6, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 9, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + {11, 0, ANIObject::kModeContinuous, true, false, false, 0, 0} +}; + bool OnceUpon::sectionEnd() { - warning("OnceUpon::sectionEnd(): TODO"); + fadeOut(); + setGamePalette(9); + + _vm->_video->drawPackedSprite("cadre.cmp", *_vm->_draw->_backSurface); + + Surface endBackground(320, 200, 1); + _vm->_video->drawPackedSprite("fin.cmp", endBackground); + + _vm->_draw->_backSurface->blit(endBackground, 0, 0, 288, 137, 16, 50); + + ANIFile ani(_vm, "fin.ani", 320); + ANIList anims; + + loadAnims(anims, ani, ARRAYSIZE(kSectionEndAnimations), kSectionEndAnimations); + drawAnim(anims); + + _vm->_draw->forceBlit(); + + MenuAction action = kMenuActionNone; + while (!_vm->shouldQuit() && (action == kMenuActionNone)) { + redrawAnim(anims); + + fadeIn(); + + endFrame(true); + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + if ((key != 0) && (key != kKeyEscape)) + // Any key pressed => Quit + action = kMenuActionQuit; + + action = doIngameMenu(key, mouseButtons); + } + + freeAnims(anims); + + // Restart requested + if (action == kMenuActionRestart) + return false; + // Last scene. Even if we didn't explicitly request a quit, the game ends here _quit = true; return false; } diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 0cae369758..caaf155d06 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -149,19 +149,23 @@ private: /** All general game sounds we know about. */ static const char *kSound[kSoundMAX]; + + static const AnimProperties kClownAnimations[]; + static const AnimProperties kTitleAnimation; + static const AnimProperties kSectionEndAnimations[]; + + /** Function pointer type for a section handler. */ typedef bool (OnceUpon::*SectionFunc)(); /** Section handler function. */ static const SectionFunc kSectionFuncs[kSectionCount]; + // -- General helpers -- void setGamePalette(uint palette); ///< Set a game palette. void setGameCursor(); ///< Set the default game cursor. - /** Set the state of an ANIObject. */ - void setAnimState(ANIObject &ani, uint16 state, bool once, bool pause) const; - /** Draw this sprite in a fancy, animated line-by-line way. */ void drawLineByLine(const Surface &src, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y) const; diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 675958035d..4ee5430de7 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -251,24 +251,70 @@ bool PreGob::hasInput() { return checkInput(mouseX, mouseY, mouseButtons) || (mouseButtons != kMouseButtonsNone); } -void PreGob::clearAnim(ANIObject &ani) { +void PreGob::clearAnim(ANIObject &anim) { int16 left, top, right, bottom; - if (ani.clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + if (anim.clear(*_vm->_draw->_backSurface, left, top, right, bottom)) _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } -void PreGob::drawAnim(ANIObject &ani) { +void PreGob::drawAnim(ANIObject &anim) { int16 left, top, right, bottom; - if (ani.draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + if (anim.draw(*_vm->_draw->_backSurface, left, top, right, bottom)) _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); - ani.advance(); + anim.advance(); } -void PreGob::redrawAnim(ANIObject &ani) { - clearAnim(ani); - drawAnim(ani); +void PreGob::redrawAnim(ANIObject &anim) { + clearAnim(anim); + drawAnim(anim); +} + +void PreGob::clearAnim(const ANIList &anims) { + for (int i = (anims.size() - 1); i >= 0; i--) + clearAnim(*anims[i]); +} + +void PreGob::drawAnim(const ANIList &anims) { + for (ANIList::const_iterator a = anims.begin(); a != anims.end(); ++a) + drawAnim(**a); +} + +void PreGob::redrawAnim(const ANIList &anims) { + clearAnim(anims); + drawAnim(anims); +} + +void PreGob::loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const { + freeAnims(anims); + + anims.resize(count); + for (uint i = 0; i < count; i++) { + anims[i] = new ANIObject(ani); + + setAnim(*anims[i], props[i]); + } +} + +void PreGob::freeAnims(ANIList &anims) const { + for (ANIList::iterator a = anims.begin(); a != anims.end(); ++a) + delete *a; + + anims.clear(); +} + +void PreGob::setAnim(ANIObject &anim, const AnimProperties &props) const { + anim.setAnimation(props.animation); + anim.setFrame(props.frame); + anim.setMode(props.mode); + anim.setPause(props.paused); + anim.setVisible(props.visible); + + if (props.hasPosition) + anim.setPosition(props.x, props.y); + else + anim.setPosition(); } Common::String PreGob::getLocFile(const Common::String &file) const { diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index e62a59042b..f1728036ab 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -27,6 +27,7 @@ #include "common/array.h" #include "gob/util.h" +#include "gob/aniobject.h" #include "gob/sound/sounddesc.h" @@ -37,8 +38,6 @@ namespace Gob { class GobEngine; class Surface; -class ANIObject; - class PreGob { public: PreGob(GobEngine *vm); @@ -46,7 +45,23 @@ public: virtual void run() = 0; + struct AnimProperties { + uint16 animation; + uint16 frame; + + ANIObject::Mode mode; + + bool visible; + bool paused; + + bool hasPosition; + int16 x; + int16 y; + }; + protected: + typedef Common::Array ANIList; + static const char kLanguageSuffixShort[5]; static const char *kLanguageSuffixLong [5]; @@ -88,11 +103,23 @@ protected: bool isCursorVisible() const; /** Remove an animation from the screen. */ - void clearAnim(ANIObject &ani); + void clearAnim(ANIObject &anim); /** Draw an animation to the screen, advancing it. */ - void drawAnim(ANIObject &ani); + void drawAnim(ANIObject &anim); /** Clear and draw an animation to the screen, advancing it. */ - void redrawAnim(ANIObject &ani); + void redrawAnim(ANIObject &anim); + + /** Remove animations from the screen. */ + void clearAnim(const ANIList &anims); + /** Draw animations to the screen, advancing them. */ + void drawAnim(const ANIList &anims); + /** Clear and draw animations to the screen, advancing them. */ + void redrawAnim(const ANIList &anims); + + void loadAnims(ANIList &anims, ANIFile &ani, uint count, const AnimProperties *props) const; + void freeAnims(ANIList &anims) const; + + void setAnim(ANIObject &anim, const AnimProperties &props) const; /** Wait for the frame to end, handling screen updates and optionally update input. */ void endFrame(bool doInput); -- cgit v1.2.3 From a547633911afa31964c10ed0222410aa9e66db80 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 5 Jul 2012 06:11:46 +0200 Subject: GOB: ANIObject can now predict the position/size of future frames --- engines/gob/aniobject.cpp | 32 ++++++++++++++++++++++++++------ engines/gob/aniobject.h | 8 ++++---- 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/aniobject.cpp b/engines/gob/aniobject.cpp index 8d3a6897bf..7e3668a0ce 100644 --- a/engines/gob/aniobject.cpp +++ b/engines/gob/aniobject.cpp @@ -101,7 +101,7 @@ void ANIObject::getPosition(int16 &x, int16 &y) const { y = _y; } -void ANIObject::getFramePosition(int16 &x, int16 &y) const { +void ANIObject::getFramePosition(int16 &x, int16 &y, uint16 n) const { // CMP "animations" have no specific frame positions if (_cmp) { getPosition(x, y); @@ -115,11 +115,24 @@ void ANIObject::getFramePosition(int16 &x, int16 &y) const { if (_frame >= animation.frameCount) return; - x = _x + animation.frameAreas[_frame].left; - y = _y + animation.frameAreas[_frame].top; + // If we're paused, we don't advance any frames + if (_paused) + n = 0; + + // Number of cycles run through after n frames + uint16 cycles = (_frame + n) / animation.frameCount; + // Frame position after n frames + uint16 frame = (_frame + n) % animation.frameCount; + + // Only doing one cycle? + if (_mode == kModeOnce) + cycles = MAX(cycles, 1); + + x = _x + animation.frameAreas[frame].left + cycles * animation.deltaX; + y = _y + animation.frameAreas[frame].top + cycles * animation.deltaY; } -void ANIObject::getFrameSize(int16 &width, int16 &height) const { +void ANIObject::getFrameSize(int16 &width, int16 &height, uint16 n) const { if (_cmp) { width = _cmp->getWidth (_animation); height = _cmp->getHeight(_animation); @@ -134,8 +147,15 @@ void ANIObject::getFrameSize(int16 &width, int16 &height) const { if (_frame >= animation.frameCount) return; - width = animation.frameAreas[_frame].right - animation.frameAreas[_frame].left + 1; - height = animation.frameAreas[_frame].bottom - animation.frameAreas[_frame].top + 1; + // If we're paused, we don't advance any frames + if (_paused) + n = 0; + + // Frame position after n frames + uint16 frame = (_frame + n) % animation.frameCount; + + width = animation.frameAreas[frame].right - animation.frameAreas[frame].left + 1; + height = animation.frameAreas[frame].bottom - animation.frameAreas[frame].top + 1; } bool ANIObject::isIn(int16 x, int16 y) const { diff --git a/engines/gob/aniobject.h b/engines/gob/aniobject.h index 3c374f7b8f..d8c8edc2b8 100644 --- a/engines/gob/aniobject.h +++ b/engines/gob/aniobject.h @@ -70,10 +70,10 @@ public: /** Return the current position. */ void getPosition(int16 &x, int16 &y) const; - /** Return the current frame position. */ - void getFramePosition(int16 &x, int16 &y) const; - /** Return the current frame size. */ - void getFrameSize(int16 &width, int16 &height) const; + /** Return the frame position after another n frames. */ + void getFramePosition(int16 &x, int16 &y, uint16 n = 0) const; + /** Return the current frame size after another n frames. */ + void getFrameSize(int16 &width, int16 &height, uint16 n = 0) const; /** Are there coordinates within the animation sprite? */ bool isIn(int16 x, int16 y) const; -- cgit v1.2.3 From 0b030dd341b00007b969805ff6d488a51a1a97c7 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 5 Jul 2012 11:00:26 +0200 Subject: GOB: Implement parts of the Stork section in Once Upon A Time No GCT texts yet ("The stork is bringing a sweet baby to $PLACE where $PEOPLE live"), and the character creator is also still missing. --- engines/gob/module.mk | 1 + engines/gob/pregob/onceupon/abracadabra.cpp | 25 +++ engines/gob/pregob/onceupon/abracadabra.h | 8 + engines/gob/pregob/onceupon/babayaga.cpp | 25 +++ engines/gob/pregob/onceupon/babayaga.h | 8 + engines/gob/pregob/onceupon/brokenstrings.h | 3 +- engines/gob/pregob/onceupon/onceupon.cpp | 124 ++++++++++++++- engines/gob/pregob/onceupon/onceupon.h | 19 +++ engines/gob/pregob/onceupon/stork.cpp | 234 ++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/stork.h | 103 ++++++++++++ 10 files changed, 547 insertions(+), 3 deletions(-) create mode 100644 engines/gob/pregob/onceupon/stork.cpp create mode 100644 engines/gob/pregob/onceupon/stork.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index f8b477b92b..1b3f400684 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -83,6 +83,7 @@ MODULE_OBJS := \ pregob/onceupon/onceupon.o \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ + pregob/onceupon/stork.o \ minigames/geisha/evilfish.o \ minigames/geisha/oko.o \ minigames/geisha/meter.o \ diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 2e4b5f21e7..0d644d9056 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -78,6 +78,27 @@ const char *Abracadabra::kAnimalNames[] = { "scor" }; +// The houses where the stork can drop a bundle +const OnceUpon::MenuButton Abracadabra::kStorkHouses[] = { + {false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, + {false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, + {false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, + {false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} +}; + +// The stork bundle drop parameters +const Stork::BundleDrop Abracadabra::kStorkBundleDrops[] = { + { 14, 65, 127, true }, + { 14, 76, 152, true }, + { 14, 204, 137, true }, + { 11, 275, 179, false } +}; + +// Parameters for the stork section. +const OnceUpon::StorkParam Abracadabra::kStorkParam = { + "present.cmp", ARRAYSIZE(kStorkHouses), kStorkHouses, kStorkBundleDrops +}; + Abracadabra::Abracadabra(GobEngine *vm) : OnceUpon(vm) { } @@ -107,6 +128,10 @@ void Abracadabra::run() { playGame(); } +const OnceUpon::StorkParam &Abracadabra::getStorkParameters() const { + return kStorkParam; +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/abracadabra.h b/engines/gob/pregob/onceupon/abracadabra.h index f2075fc750..8048213f5f 100644 --- a/engines/gob/pregob/onceupon/abracadabra.h +++ b/engines/gob/pregob/onceupon/abracadabra.h @@ -36,6 +36,9 @@ public: void run(); +protected: + const StorkParam &getStorkParameters() const; + private: /** Definition of the menu button that leads to the animal names screen. */ static const MenuButton kAnimalsButtons; @@ -44,6 +47,11 @@ private: static const MenuButton kAnimalButtons[]; /** File prefixes for the name of each animal. */ static const char *kAnimalNames[]; + + // Parameters for the stork section. + static const MenuButton kStorkHouses[]; + static const Stork::BundleDrop kStorkBundleDrops[]; + static const struct StorkParam kStorkParam; }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 6f27f469e3..6aa60310b5 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -78,6 +78,27 @@ const char *BabaYaga::kAnimalNames[] = { "rena" }; +// The houses where the stork can drop a bundle +const OnceUpon::MenuButton BabaYaga::kStorkHouses[] = { + {false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, + {false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, + {false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, + {false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} +}; + +// The stork bundle drop parameters +const Stork::BundleDrop BabaYaga::kStorkBundleDrops[] = { + { 14, 35, 129, true }, + { 14, 70, 148, true }, + { 14, 206, 136, true }, + { 11, 260, 225, false } +}; + +// Parameters for the stork section. +const OnceUpon::StorkParam BabaYaga::kStorkParam = { + "present2.cmp", ARRAYSIZE(kStorkHouses), kStorkHouses, kStorkBundleDrops +}; + BabaYaga::BabaYaga(GobEngine *vm) : OnceUpon(vm) { } @@ -107,6 +128,10 @@ void BabaYaga::run() { playGame(); } +const OnceUpon::StorkParam &BabaYaga::getStorkParameters() const { + return kStorkParam; +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/babayaga.h b/engines/gob/pregob/onceupon/babayaga.h index 181b6f4d54..0241f78f4e 100644 --- a/engines/gob/pregob/onceupon/babayaga.h +++ b/engines/gob/pregob/onceupon/babayaga.h @@ -36,6 +36,9 @@ public: void run(); +protected: + const StorkParam &getStorkParameters() const; + private: /** Definition of the menu button that leads to the animal names screen. */ static const MenuButton kAnimalsButtons; @@ -44,6 +47,11 @@ private: static const MenuButton kAnimalButtons[]; /** File prefixes for the name of each animal. */ static const char *kAnimalNames[]; + + // Parameters for the stork section. + static const MenuButton kStorkHouses[]; + static const Stork::BundleDrop kStorkBundleDrops[]; + static const struct StorkParam kStorkParam; }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/brokenstrings.h b/engines/gob/pregob/onceupon/brokenstrings.h index 0a40493cc1..89acb1c6bd 100644 --- a/engines/gob/pregob/onceupon/brokenstrings.h +++ b/engines/gob/pregob/onceupon/brokenstrings.h @@ -45,7 +45,8 @@ static const BrokenString kBrokenStringsGerman[] = { { "Am Waldesrand es sieht" , "Am Waldesrand sieht es" }, { " das Kind den Palast." , "das Kind den Palast." }, { "Am Waldessaum sieht" , "Am Waldesrand sieht" }, - { "tipp auf ESC!" , "dr\201cke ESC!" } + { "tipp auf ESC!" , "dr\201cke ESC!" }, + { "Wohin fliegt der Drachen?" , "Wohin fliegt der Drache?" } }; static const BrokenStringLanguage kBrokenStrings[kLanguageCount] = { diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index aed1b45e02..aa08f6f1fd 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -128,7 +128,8 @@ const OnceUpon::MenuButton OnceUpon::kLanguageButtons[] = { }; const char *OnceUpon::kSound[kSoundMAX] = { - "diamant.snd" + "diamant.snd", // kSoundClick + "cigogne.snd" // kSoundStork }; const OnceUpon::SectionFunc OnceUpon::kSectionFuncs[kSectionCount] = { @@ -1293,9 +1294,128 @@ bool OnceUpon::playSection() { return (this->*kSectionFuncs[_section])(); } +const PreGob::AnimProperties OnceUpon::kSectionStorkAnimations[] = { + { 0, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 1, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 2, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 3, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 4, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 5, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 6, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 7, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + { 8, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + {17, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + {16, 0, ANIObject::kModeContinuous, true, false, false, 0, 0}, + {15, 0, ANIObject::kModeContinuous, true, false, false, 0, 0} +}; + +enum StorkState { + kStorkStateWaitUser, + kStorkStateWaitBundle, + kStorkStateFinish +}; + bool OnceUpon::sectionStork() { warning("OnceUpon::sectionStork(): TODO"); - return true; + + fadeOut(); + hideCursor(); + setGamePalette(0); + setGameCursor(); + + const StorkParam ¶m = getStorkParameters(); + + Surface backdrop(320, 200, 1); + + // Draw the frame + _vm->_video->drawPackedSprite("cadre.cmp", *_vm->_draw->_backSurface); + + // Draw the backdrop + _vm->_video->drawPackedSprite(param.backdrop, backdrop); + _vm->_draw->_backSurface->blit(backdrop, 0, 0, 288, 175, 16, 12); + + // "Where does the stork go?" + TXTFile *whereStork = loadTXT(getLocFile("ouva.tx"), TXTFile::kFormatStringPositionColor); + whereStork->draw(*_vm->_draw->_backSurface, &_plettre, 1); + + ANIFile ani(_vm, "present.ani", 320); + ANIList anims; + + Stork *stork = new Stork(_vm, ani); + + loadAnims(anims, ani, ARRAYSIZE(kSectionStorkAnimations), kSectionStorkAnimations); + anims.push_back(stork); + + drawAnim(anims); + + _vm->_draw->forceBlit(); + + int8 storkSoundWait = 0; + + StorkState state = kStorkStateWaitUser; + MenuAction action = kMenuActionNone; + while (!_vm->shouldQuit() && (state != kStorkStateFinish)) { + clearAnim(anims); + + // Play the stork sound + if (--storkSoundWait == 0) + playSound(kSoundStork); + if (storkSoundWait <= 0) + storkSoundWait = 50 - _vm->_util->getRandom(30); + + // Check if the bundle landed + if ((state == kStorkStateWaitBundle) && stork->hasBundleLanded()) + state = kStorkStateFinish; + + // Check user input + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + + action = doIngameMenu(key, mouseButtons); + if (action != kMenuActionNone) { + state = kStorkStateFinish; + break; + } + + if (mouseButtons == kMouseButtonsLeft) { + stopSound(); + playSound(kSoundClick); + + int house = checkButton(param.houses, param.houseCount, mouseX, mouseY); + if ((state == kStorkStateWaitUser) && (house >= 0)) { + + stork->dropBundle(param.drops[house]); + state = kStorkStateWaitBundle; + + // Remove the "Where does the stork go?" text + int16 left, top, right, bottom; + if (whereStork->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + } + } + + drawAnim(anims); + showCursor(); + fadeIn(); + + endFrame(true); + } + + freeAnims(anims); + delete whereStork; + + fadeOut(); + hideCursor(); + + // Completed the section => move one + if (action == kMenuActionNone) + return true; + + // Didn't complete the section + return false; } bool OnceUpon::sectionChapter1() { diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index caaf155d06..b9aef04dc2 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -27,6 +27,8 @@ #include "gob/pregob/pregob.h" +#include "gob/pregob/onceupon/stork.h" + namespace Gob { class Surface; @@ -67,6 +69,15 @@ protected: uint id; ///< The button's ID. }; + /** Parameters for the stork section. */ + struct StorkParam { + const char *backdrop; ///< Backdrop image file. + + uint houseCount; ///< Number of houses. + const MenuButton *houses; ///< House button definitions. + + const Stork::BundleDrop *drops; ///< The bundle drop parameters. + }; void init(); void deinit(); @@ -97,6 +108,10 @@ protected: void playGame(); + /** Return the parameters for the stork section. */ + virtual const StorkParam &getStorkParameters() const = 0; + + private: /** All actions a user can request in a menu. */ enum MenuAction { @@ -119,6 +134,7 @@ private: /** The different sounds common in the game. */ enum Sound { kSoundClick = 0, + kSoundStork , kSoundMAX }; @@ -146,12 +162,15 @@ private: static const MenuButton kAnimalNamesBack; ///< "Back" button in the animal names screens. static const MenuButton kLanguageButtons[]; ///< Language buttons in the animal names screen. + static const MenuButton kSectionStorkHouses[]; + /** All general game sounds we know about. */ static const char *kSound[kSoundMAX]; static const AnimProperties kClownAnimations[]; static const AnimProperties kTitleAnimation; + static const AnimProperties kSectionStorkAnimations[]; static const AnimProperties kSectionEndAnimations[]; diff --git a/engines/gob/pregob/onceupon/stork.cpp b/engines/gob/pregob/onceupon/stork.cpp new file mode 100644 index 0000000000..3c38037d08 --- /dev/null +++ b/engines/gob/pregob/onceupon/stork.cpp @@ -0,0 +1,234 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/str.h" + +#include "gob/gob.h" +#include "gob/surface.h" +#include "gob/anifile.h" +#include "gob/video.h" + +#include "gob/pregob/onceupon/stork.h" + +enum Animation { + kAnimFlyNearWithBundle = 9, + kAnimFlyFarWithBundle = 12, + kAnimFlyNearWithoutBundle = 10, + kAnimFlyFarWithoutBundle = 13, + kAnimBundleNear = 11, + kAnimBundleFar = 14 +}; + +namespace Gob { + +namespace OnceUpon { + +Stork::Stork(GobEngine *vm, const ANIFile &ani) : ANIObject(ani), _shouldDrop(false) { + _frame = new Surface(320, 200, 1); + vm->_video->drawPackedSprite("cadre.cmp", *_frame); + + _bundle = new ANIObject(ani); + + _bundle->setVisible(false); + _bundle->setPause(true); + + setState(kStateFlyNearWithBundle, kAnimFlyNearWithBundle, -80); +} + +Stork::~Stork() { + delete _frame; + + delete _bundle; +} + +bool Stork::hasBundleLanded() const { + if (!_shouldDrop || !_bundle->isVisible() || _bundle->isPaused()) + return false; + + int16 x, y, width, height; + _bundle->getFramePosition(x, y); + _bundle->getFrameSize(width, height); + + return (y + height) >= _bundleDrop.landY; +} + +void Stork::dropBundle(const BundleDrop &drop) { + if (_shouldDrop) + return; + + _shouldDrop = true; + _bundleDrop = drop; +} + +bool Stork::draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + left = 0x7FFF; + top = 0x7FFF; + right = 0x0000; + bottom = 0x0000; + + bool drawn = ANIObject::draw(dest, left, top, right, bottom); + if (drawn) { + // Left frame edge + if (left <= 15) + dest.blit(*_frame, left, top, MIN(15, right), bottom, left, top); + + // Right frame edge + if (right >= 304) + dest.blit(*_frame, MAX(304, left), top, right, bottom, MAX(304, left), top); + } + + int16 bLeft, bTop, bRight, bBottom; + if (_bundle->draw(dest, bLeft, bTop, bRight, bBottom)) { + // Bottom frame edge + if (bBottom >= 188) + dest.blit(*_frame, bLeft, MAX(188, bTop), bRight, bBottom, bLeft, MAX(188, bTop)); + + left = MIN(left , bLeft ); + top = MIN(top , bTop ); + right = MAX(right , bRight ); + bottom = MAX(bottom, bBottom); + + drawn = true; + } + + return drawn; +} + +bool Stork::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + left = 0x7FFF; + top = 0x7FFF; + right = 0x0000; + bottom = 0x0000; + + bool cleared = _bundle->clear(dest, left, top, right, bottom); + + int16 sLeft, sTop, sRight, sBottom; + if (ANIObject::clear(dest, sLeft, sTop, sRight, sBottom)) { + left = MIN(left , sLeft ); + top = MIN(top , sTop ); + right = MAX(right , sRight ); + bottom = MAX(bottom, sBottom); + + cleared = true; + } + + return cleared; +} + +void Stork::advance() { + _bundle->advance(); + + ANIObject::advance(); + + int16 curX, curY, curWidth, curHeight; + getFramePosition(curX, curY, 0); + getFrameSize(curWidth, curHeight, 0); + + const int16 curRight = curX + curWidth - 1; + + int16 nextX, nextY, nextWidth, nextHeight; + getFramePosition(nextX, nextY, 1); + getFrameSize(nextWidth, nextHeight, 1); + + const int16 nextRight = nextX + nextWidth - 1; + + switch (_state) { + case kStateFlyNearWithBundle: + if (curX >= 330) + setState(kStateFlyFarWithBundle, kAnimFlyFarWithBundle, 330); + + if ((curRight <= _bundleDrop.dropX) && + (nextRight >= _bundleDrop.dropX) && _shouldDrop && !_bundleDrop.dropWhileFar) + dropBundle(kStateFlyNearWithoutBundle, kAnimFlyNearWithoutBundle); + + break; + + case kStateFlyFarWithBundle: + if (curX <= -80) + setState(kStateFlyNearWithBundle, kAnimFlyNearWithBundle, -80); + + if ((curX >= _bundleDrop.dropX) && + (nextX <= _bundleDrop.dropX) && _shouldDrop && _bundleDrop.dropWhileFar) + dropBundle(kStateFlyFarWithoutBundle, kAnimFlyFarWithoutBundle); + + break; + + case kStateFlyNearWithoutBundle: + if (curX >= 330) + setState(kStateFlyFarWithoutBundle, kAnimFlyFarWithoutBundle, 330); + break; + + case kStateFlyFarWithoutBundle: + if (curX <= -80) + setState(kStateFlyNearWithoutBundle, kAnimFlyNearWithoutBundle, -80); + break; + + default: + break; + } +} + +void Stork::dropBundle(State state, uint16 anim) { + setState(state, anim); + + int16 x, y, width, height; + getFramePosition(x, y); + getFrameSize(width, height); + + _bundle->setAnimation(_bundleDrop.anim); + _bundle->setPause(false); + _bundle->setVisible(true); + + int16 bWidth, bHeight; + _bundle->getFrameSize(bWidth, bHeight); + + // Drop position + x = _bundleDrop.dropX; + y = y + height - bHeight; + + // If the stork is flying near (from left to right), drop the bundle at the right edge + if (!_bundleDrop.dropWhileFar) + x = x - bWidth; + + _bundle->setPosition(x, y); +} + +void Stork::setState(State state, uint16 anim) { + setAnimation(anim); + setVisible(true); + setPause(false); + + _state = state; +} + +void Stork::setState(State state, uint16 anim, int16 x) { + setState(state, anim); + setPosition(); + + int16 pX, pY; + getPosition(pX, pY); + setPosition( x, pY); +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/stork.h b/engines/gob/pregob/onceupon/stork.h new file mode 100644 index 0000000000..d26a887c97 --- /dev/null +++ b/engines/gob/pregob/onceupon/stork.h @@ -0,0 +1,103 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_STORK_H +#define GOB_PREGOB_ONCEUPON_STORK_H + +#include "common/system.h" + +#include "gob/aniobject.h" + +namespace Common { + class String; +} + +namespace Gob { + +class GobEngine; + +class Surface; +class ANIFile; + +namespace OnceUpon { + +/** The stork in Baba Yaga / dragon in Abracadabra. */ +class Stork : public ANIObject { +public: + /** Information on how to drop the bundle. */ + struct BundleDrop { + int16 anim; ///< Animation of the bundle floating down + + int16 dropX; ///< X position the stork drops the bundle + int16 landY; ///< Y position the bundle lands + + bool dropWhileFar; ///< Does the stork drop the bundle while far instead of near? + }; + + Stork(GobEngine *vm, const ANIFile &ani); + ~Stork(); + + /** Has the bundle landed? */ + bool hasBundleLanded() const; + + /** Drop the bundle. */ + void dropBundle(const BundleDrop &drop); + + /** Draw the current frame onto the surface and return the affected rectangle. */ + bool draw(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + /** Draw the current frame from the surface and return the affected rectangle. */ + bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + + /** Advance the animation to the next frame. */ + void advance(); + +private: + enum State { + kStateFlyNearWithBundle = 0, + kStateFlyFarWithBundle , + kStateFlyNearWithoutBundle , + kStateFlyFarWithoutBundle + }; + + + void setState(State state, uint16 anim); + void setState(State state, uint16 anim, int16 x); + + void dropBundle(State state, uint16 anim); + + + GobEngine *_vm; + + Surface *_frame; + ANIObject *_bundle; + + State _state; + + bool _shouldDrop; + BundleDrop _bundleDrop; +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_STORK_H -- cgit v1.2.3 From e17d4a5c0c66b890014efa62d207406fd5b887ef Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 13:21:07 +0200 Subject: GOB: Implement GCT drawing --- engines/gob/module.mk | 1 + engines/gob/pregob/gctfile.cpp | 306 +++++++++++++++++++++++++++++++++++++++++ engines/gob/pregob/gctfile.h | 149 ++++++++++++++++++++ engines/gob/pregob/pregob.cpp | 13 ++ engines/gob/pregob/pregob.h | 7 + 5 files changed, 476 insertions(+) create mode 100644 engines/gob/pregob/gctfile.cpp create mode 100644 engines/gob/pregob/gctfile.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 1b3f400684..15351848de 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -80,6 +80,7 @@ MODULE_OBJS := \ detection/detection.o \ pregob/pregob.o \ pregob/txtfile.o \ + pregob/gctfile.o \ pregob/onceupon/onceupon.o \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ diff --git a/engines/gob/pregob/gctfile.cpp b/engines/gob/pregob/gctfile.cpp new file mode 100644 index 0000000000..08c32cda76 --- /dev/null +++ b/engines/gob/pregob/gctfile.cpp @@ -0,0 +1,306 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/random.h" +#include "common/stream.h" + +#include "gob/surface.h" +#include "gob/video.h" + +#include "gob/pregob/gctfile.h" + +namespace Gob { + +GCTFile::Chunk::Chunk() : type(kChunkTypeNone) { +} + + +GCTFile::GCTFile(Common::SeekableReadStream &gct, Common::RandomSource &rnd) : _rnd(&rnd), + _areaLeft(0), _areaTop(0), _areaRight(0), _areaBottom(0), _currentItem(0xFFFF) { + + load(gct); +} + +GCTFile::~GCTFile() { +} + +void GCTFile::load(Common::SeekableReadStream &gct) { + gct.skip(4); // Required buffer size + gct.skip(2); // Unknown + + // Read the selector and line counts for each item + const uint16 itemCount = gct.readUint16LE(); + _items.resize(itemCount); + + for (Items::iterator i = _items.begin(); i != _items.end(); ++i) { + const uint16 selector = gct.readUint16LE(); + const uint16 lineCount = gct.readUint16LE(); + + i->selector = selector; + i->lines.resize(lineCount); + } + + // Read all item lines + for (Items::iterator i = _items.begin(); i != _items.end(); ++i) { + for (Lines::iterator l = i->lines.begin(); l != i->lines.end(); ++l) { + const uint16 lineSize = gct.readUint16LE(); + + readLine(gct, *l, lineSize); + } + } + + if (gct.err()) + error("GCTFile::load(): Failed reading GCT"); +} + +void GCTFile::readLine(Common::SeekableReadStream &gct, Line &line, uint16 lineSize) const { + line.chunks.push_back(Chunk()); + + while (lineSize > 0) { + byte c = gct.readByte(); + lineSize--; + + if (c == 0) { + // Command byte + + if (lineSize == 0) + break; + + byte cmd = gct.readByte(); + lineSize--; + + // Line end command + if (cmd == 0) + break; + + // Item reference command + if (cmd == 1) { + if (lineSize < 2) { + warning("GCTFile::readLine(): Item reference command is missing parameters"); + break; + } + + const uint32 itemRef = gct.readUint16LE(); + lineSize -= 2; + + line.chunks.push_back(Chunk()); + line.chunks.back().type = kChunkTypeItem; + line.chunks.back().item = itemRef; + + line.chunks.push_back(Chunk()); + continue; + } + + warning("GCTFile::readLine(): Invalid command 0x%02X", cmd); + break; + } + + // Text + line.chunks.back().type = kChunkTypeString; + line.chunks.back().text += (char)c; + } + + // Skip bytes we didn't read (because of errors) + gct.skip(lineSize); + + // Remove empty chunks from the end of the list + while (!line.chunks.empty() && (line.chunks.back().type == kChunkTypeNone)) + line.chunks.pop_back(); +} + +uint16 GCTFile::getLineCount(uint item) const { + if (item >= _items.size()) + return 0; + + return _items[item].lines.size(); +} + +void GCTFile::selectLine(uint item, uint16 line) { + if ((item >= _items.size()) && (item != kSelectorAll) && (item != kSelectorRandom)) + return; + + _items[item].selector = line; +} + +void GCTFile::setText(uint item, uint16 line, const Common::String &text) { + if ((item >= _items.size()) || (line >= _items[item].lines.size())) + return; + + _items[item].lines[line].chunks.clear(); + _items[item].lines[line].chunks.push_back(Chunk()); + + _items[item].lines[line].chunks.back().type = kChunkTypeString; + _items[item].lines[line].chunks.back().text = text; +} + +void GCTFile::setText(uint item, const Common::String &text) { + if (item >= _items.size()) + return; + + _items[item].selector = 0; + + _items[item].lines.resize(1); + + setText(item, 0, text); +} + +void GCTFile::reset() { + _currentItem = 0xFFFF; + _currentText.clear(); +} + +Common::String GCTFile::getLineText(const Line &line) const { + Common::String text; + + // Go over all chunks in this line + for (Chunks::const_iterator c = line.chunks.begin(); c != line.chunks.end(); ++c) { + // A chunk is either a direct string, or a reference to another item + + if (c->type == kChunkTypeItem) { + Common::List lines; + + getItemText(c->item, lines); + if (lines.empty()) + continue; + + if (lines.size() > 1) + warning("GCTFile::getLineText(): Referenced item has multiple lines"); + + text += lines.front(); + } else if (c->type == kChunkTypeString) + text += c->text; + } + + return text; +} + +void GCTFile::getItemText(uint item, Common::List &text) const { + text.clear(); + + if ((item >= _items.size()) || _items[item].lines.empty()) + return; + + uint16 line = _items[item].selector; + + // Draw all lines + if (line == kSelectorAll) { + for (Lines::const_iterator l = _items[item].lines.begin(); l != _items[item].lines.end(); ++l) + text.push_back(getLineText(*l)); + + return; + } + + // Draw random line + if (line == kSelectorRandom) + line = _rnd->getRandomNumber(_items[item].lines.size() - 1); + + if (line >= _items[item].lines.size()) + return; + + text.push_back(getLineText(_items[item].lines[line])); +} + +void GCTFile::setArea(int16 left, int16 top, int16 right, int16 bottom) { + trashBuffer(); + + _hasArea = false; + + const int16 width = right - left + 1; + const int16 height = bottom - top + 1; + if ((width <= 0) || (height <= 0)) + return; + + _areaLeft = left; + _areaTop = top; + _areaRight = right; + _areaBottom = bottom; + + _hasArea = true; + + resizeBuffer(width, height); +} + +bool GCTFile::clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom) { + return restoreScreen(dest, left, top, right, bottom); +} + +bool GCTFile::fill(Surface &dest, uint8 color, int16 &left, int16 &top, int16 &right, int16 &bottom) { + left = _areaLeft; + top = _areaTop; + right = _areaRight; + bottom = _areaBottom; + + if (!hasSavedBackground()) + saveScreen(dest, left, top, right, bottom); + + dest.fillRect(left, top, right, bottom, color); + + return true; +} + +bool GCTFile::finished() const { + return (_currentItem != 0xFFFF) && _currentText.empty(); +} + +bool GCTFile::draw(Surface &dest, uint16 item, const Font &font, uint8 color, + int16 &left, int16 &top, int16 &right, int16 &bottom) { + + if ((item >= _items.size()) || !_hasArea) + return false; + + left = _areaLeft; + top = _areaTop; + right = _areaRight; + bottom = _areaBottom; + + const int16 width = right - left + 1; + const int16 height = bottom - top + 1; + + const uint lineCount = height / font.getCharHeight(); + if (lineCount == 0) + return false; + + if (!hasSavedBackground()) + saveScreen(dest, left, top, right, bottom); + + if (item != _currentItem) { + _currentItem = item; + + getItemText(_currentItem, _currentText); + } + + if (_currentText.empty()) + return false; + + int16 y = top; + for (uint i = 0; (i < lineCount) && !_currentText.empty(); i++, y += font.getCharHeight()) { + const Common::String &line = _currentText.front(); + const int16 x = left + ((width - (line.size() * font.getCharWidth())) / 2); + + font.drawString(line, x, y, color, 0, true, dest); + _currentText.pop_front(); + } + + return true; +} + +} // End of namespace Gob diff --git a/engines/gob/pregob/gctfile.h b/engines/gob/pregob/gctfile.h new file mode 100644 index 0000000000..ed6351b7a8 --- /dev/null +++ b/engines/gob/pregob/gctfile.h @@ -0,0 +1,149 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_GCTFILE_H +#define GOB_PREGOB_GCTFILE_H + +#include "common/str.h" +#include "common/array.h" +#include "common/list.h" + +#include "gob/backbuffer.h" + +namespace Common { + class RandomSource; + class SeekableReadStream; +} + +namespace Gob { + +class Surface; +class Font; + +class GCTFile : public BackBuffer { +public: + static const uint16 kSelectorAll = 0xFFFE; ///< Print all lines. + static const uint16 kSelectorRandom = 0xFFFF; ///< Print a random line. + + + GCTFile(Common::SeekableReadStream &gct, Common::RandomSource &rnd); + ~GCTFile(); + + /** Return the number of lines in an item. */ + uint16 getLineCount(uint item) const; + + /** Set the area the text will be printed in. */ + void setArea(int16 left, int16 top, int16 right, int16 bottom); + + /** Set which line of this item should be printed. */ + void selectLine(uint item, uint16 line); + + /** Change the text of an items' line. */ + void setText(uint item, uint16 line, const Common::String &text); + /** Change the item into one one line and set that line's text. */ + void setText(uint item, const Common::String &text); + + /** Reset the item drawing state. */ + void reset(); + + /** Clear the drawn text, restoring the original content. */ + bool clear(Surface &dest, int16 &left, int16 &top, int16 &right, int16 &bottom); + + /** Fill the text area with a color. */ + bool fill(Surface &dest, uint8 color, int16 &left, int16 &top, int16 &right, int16 &bottom); + + /** Draw an item onto the surface, until all text has been drawn or the area is filled. */ + bool draw(Surface &dest, uint16 item, const Font &font, uint8 color, + int16 &left, int16 &top, int16 &right, int16 &bottom); + + /** Did we draw all text? */ + bool finished() const; + +private: + /** The type of a chunk. */ + enum ChunkType { + kChunkTypeNone = 0, ///< Do nothing. + kChunkTypeString , ///< A direct string. + kChunkTypeItem ///< A reference to an item to print instead. + }; + + /** A chunk in an item text line. */ + struct Chunk { + ChunkType type; ///< The type of the chunk. + + Common::String text; ///< Text to print. + + int item; ///< Item to print instead. + + Chunk(); + }; + + typedef Common::List Chunks; + + /** A line in an item. */ + struct Line { + Chunks chunks; ///< The chunks that make up the line. + }; + + typedef Common::Array Lines; + + /** A GCT item. */ + struct Item { + Lines lines; ///< The text lines in the item + uint16 selector; ///< Which line to print. + }; + + typedef Common::Array Items; + + + Common::RandomSource *_rnd; + + Items _items; ///< All GCT items. + + // The area on which to print + bool _hasArea; + int16 _areaLeft; + int16 _areaTop; + int16 _areaRight; + int16 _areaBottom; + + /** Index of the current item we're drawing. */ + uint16 _currentItem; + /** Text left to draw. */ + Common::List _currentText; + + + // -- Loading helpers -- + + void load(Common::SeekableReadStream &gct); + void readLine(Common::SeekableReadStream &gct, Line &line, uint16 lineSize) const; + + + // -- Draw helpers -- + + Common::String getLineText(const Line &line) const; + void getItemText(uint item, Common::List &text) const; +}; + +} // End of namespace Gob + +#endif // GOB_PREGOB_GCTFILE_H diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 4ee5430de7..033eea89f2 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -35,6 +35,7 @@ #include "gob/sound/sound.h" #include "gob/pregob/pregob.h" +#include "gob/pregob/gctfile.h" namespace Gob { @@ -341,4 +342,16 @@ TXTFile *PreGob::loadTXT(const Common::String &txtFile, TXTFile::Format format) void PreGob::fixTXTStrings(TXTFile &txt) const { } +GCTFile *PreGob::loadGCT(const Common::String &gctFile) const { + Common::SeekableReadStream *gctStream = _vm->_dataIO->getFile(gctFile); + if (!gctStream) + error("PreGob::loadGCT(): Failed to open \"%s\"", gctFile.c_str()); + + GCTFile *gct = new GCTFile(*gctStream, _vm->_rnd); + + delete gctStream; + + return gct; +} + } // End of namespace Gob diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index f1728036ab..686727b08b 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -38,6 +38,8 @@ namespace Gob { class GobEngine; class Surface; +class GCTFile; + class PreGob { public: PreGob(GobEngine *vm); @@ -164,6 +166,11 @@ protected: virtual void fixTXTStrings(TXTFile &txt) const; + // -- GCT helpers -- + + GCTFile *loadGCT(const Common::String &gctFile) const; + + GobEngine *_vm; private: -- cgit v1.2.3 From d7c81c27555ed49c70bb6d8b1e60e6a8b5065c70 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 13:22:47 +0200 Subject: GOB: Implement GCT text drawing in the Stork section The only thing missing in the stork section now is the character creator. --- engines/gob/pregob/onceupon/onceupon.cpp | 39 +++++++++++++++++++++++--------- engines/gob/pregob/onceupon/onceupon.h | 2 +- 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index aa08f6f1fd..f1b24c3353 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -32,6 +32,9 @@ #include "gob/sound/sound.h" +#include "gob/pregob/txtfile.h" +#include "gob/pregob/gctfile.h" + #include "gob/pregob/onceupon/onceupon.h" #include "gob/pregob/onceupon/palettes.h" @@ -1041,30 +1044,33 @@ OnceUpon::MenuAction OnceUpon::doIngameMenu() { if ((action == kMenuActionQuit) || _vm->shouldQuit()) { // User pressed the quit button, or quit ScummVM - _quit = true; - return kMenuActionQuit; + _quit = true; + action = kMenuActionQuit; } else if (action == kMenuActionPlay) { // User pressed the return to game button - return kMenuActionPlay; + action = kMenuActionPlay; } else if (kMenuActionMainMenu) { // User pressed the return to main menu button - return handleMainMenu(); + action = handleMainMenu(); } return action; } -OnceUpon::MenuAction OnceUpon::doIngameMenu(int16 key, MouseButtons mouseButtons) { +OnceUpon::MenuAction OnceUpon::doIngameMenu(int16 &key, MouseButtons &mouseButtons) { if ((key != kKeyEscape) && (mouseButtons != kMouseButtonsRight)) return kMenuActionNone; + key = 0; + mouseButtons = kMouseButtonsNone; + MenuAction action = doIngameMenu(); if (action == kMenuActionPlay) - return kMenuActionNone; + action = kMenuActionNone; return action; } @@ -1316,8 +1322,6 @@ enum StorkState { }; bool OnceUpon::sectionStork() { - warning("OnceUpon::sectionStork(): TODO"); - fadeOut(); hideCursor(); setGamePalette(0); @@ -1338,6 +1342,10 @@ bool OnceUpon::sectionStork() { TXTFile *whereStork = loadTXT(getLocFile("ouva.tx"), TXTFile::kFormatStringPositionColor); whereStork->draw(*_vm->_draw->_backSurface, &_plettre, 1); + // Where the stork actually goes + GCTFile *thereStork = loadGCT(getLocFile("choix.gc")); + thereStork->setArea(17, 18, 303, 41); + ANIFile ani(_vm, "present.ani", 320); ANIList anims; @@ -1355,8 +1363,6 @@ bool OnceUpon::sectionStork() { StorkState state = kStorkStateWaitUser; MenuAction action = kMenuActionNone; while (!_vm->shouldQuit() && (state != kStorkStateFinish)) { - clearAnim(anims); - // Play the stork sound if (--storkSoundWait == 0) playSound(kSoundStork); @@ -1380,6 +1386,8 @@ bool OnceUpon::sectionStork() { break; } + clearAnim(anims); + if (mouseButtons == kMouseButtonsLeft) { stopSound(); playSound(kSoundClick); @@ -1394,6 +1402,12 @@ bool OnceUpon::sectionStork() { int16 left, top, right, bottom; if (whereStork->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + // Print the text where the stork actually goes + thereStork->selectLine(3, house); // The house + thereStork->selectLine(4, house); // The house's inhabitants + if (thereStork->draw(*_vm->_draw->_backSurface, 2, *_plettre, 10, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); } } @@ -1405,14 +1419,17 @@ bool OnceUpon::sectionStork() { } freeAnims(anims); + delete thereStork; delete whereStork; fadeOut(); hideCursor(); // Completed the section => move one - if (action == kMenuActionNone) + if (action == kMenuActionNone) { + warning("OnceUpon::sectionStork(): TODO: Character creator"); return true; + } // Didn't complete the section return false; diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index b9aef04dc2..7ae3a39485 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -249,7 +249,7 @@ private: /** Handle the whole ingame menu. */ MenuAction doIngameMenu(); /** Handle the whole ingame menu if ESC or right mouse button was pressed. */ - MenuAction doIngameMenu(int16 key, MouseButtons mouseButtons); + MenuAction doIngameMenu(int16 &key, MouseButtons &mouseButtons); // -- Menu button helpers -- -- cgit v1.2.3 From 90415cf083d26e593ff05acb3a511c088a533b8b Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 13:23:54 +0200 Subject: GOB: Implement GCT text drawing in the end section The end section is now complete. --- engines/gob/pregob/onceupon/onceupon.cpp | 48 ++++++++++++++++++++++++++------ engines/gob/pregob/onceupon/onceupon.h | 3 ++ 2 files changed, 43 insertions(+), 8 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index f1b24c3353..8c617e2c41 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -94,6 +94,9 @@ enum ClownAnimation { kClownAnimationClownCry = 6 }; +// 12 seconds delay for one area full of GCT text +static const uint32 kGCTDelay = 12000; + namespace Gob { namespace OnceUpon { @@ -222,6 +225,9 @@ void OnceUpon::init() { // We start with no selected difficulty and at section 0 _difficulty = kDifficultyMAX; _section = 0; + + // Default name + _name = "Nemo"; } void OnceUpon::deinit() { @@ -1518,6 +1524,10 @@ bool OnceUpon::sectionEnd() { _vm->_draw->_backSurface->blit(endBackground, 0, 0, 288, 137, 16, 50); + GCTFile *endText = loadGCT(getLocFile("final.gc")); + endText->setArea(17, 18, 303, 41); + endText->setText(1, _name); + ANIFile ani(_vm, "fin.ani", 320); ANIList anims; @@ -1526,26 +1536,48 @@ bool OnceUpon::sectionEnd() { _vm->_draw->forceBlit(); + uint32 textStartTime = 0; + MenuAction action = kMenuActionNone; while (!_vm->shouldQuit() && (action == kMenuActionNone)) { - redrawAnim(anims); - - fadeIn(); - - endFrame(true); + // Check user input int16 mouseX, mouseY; MouseButtons mouseButtons; int16 key = checkInput(mouseX, mouseY, mouseButtons); - if ((key != 0) && (key != kKeyEscape)) - // Any key pressed => Quit - action = kMenuActionQuit; action = doIngameMenu(key, mouseButtons); + if (action != kMenuActionNone) + break; + + clearAnim(anims); + + // Pressed a key or mouse button => Skip to next area-full of text + if ((mouseButtons == kMouseButtonsLeft) || (key != 0)) + textStartTime = 0; + + // Draw the next area-full of text + uint32 now = _vm->_util->getTimeKey(); + if (!endText->finished() && ((textStartTime == 0) || (now >= (textStartTime + kGCTDelay)))) { + textStartTime = now; + + int16 left, top, right, bottom; + if (endText->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + if (endText->draw(*_vm->_draw->_backSurface, 0, *_plettre, 10, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + } + + drawAnim(anims); + fadeIn(); + + endFrame(true); } freeAnims(anims); + delete endText; // Restart requested if (action == kMenuActionRestart) diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 7ae3a39485..386d410c95 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -24,6 +24,7 @@ #define GOB_PREGOB_ONCEUPON_ONCEUPON_H #include "common/system.h" +#include "common/str.h" #include "gob/pregob/pregob.h" @@ -312,6 +313,8 @@ private: Difficulty _difficulty; ///< The current difficulty. int _section; ///< The current game section. + + Common::String _name; ///< The name of the child. }; } // End of namespace OnceUpon -- cgit v1.2.3 From 75e7cca6921ae005cd5c4fa39b9cfa49be2a4cbb Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 18:44:46 +0200 Subject: GOB: Add support for entering non-ASCII CP850 characters --- engines/gob/util.cpp | 29 +++++++++++++++++++++++------ engines/gob/util.h | 1 + 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 5d6ae78872..e1c16c3257 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -189,12 +189,27 @@ bool Util::getKeyFromBuffer(Common::KeyState &key) { return true; } +static const uint16 kLatin1ToCP850[] = { + 0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, + 0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, + 0xB7, 0xB5, 0xB6, 0xC7, 0x8E, 0x8F, 0x92, 0x80, 0xD4, 0x90, 0xD2, 0xD3, 0xDE, 0xD6, 0xD7, 0xD8, + 0xD1, 0xA5, 0xE3, 0xE0, 0xE2, 0xE5, 0x99, 0x9E, 0x9D, 0xEB, 0xE9, 0xEA, 0x9A, 0xED, 0xE8, 0xE1, + 0x85, 0xA0, 0x83, 0xC6, 0x84, 0x86, 0x91, 0x87, 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, + 0xD0, 0xA4, 0x95, 0xA2, 0x93, 0xE4, 0x94, 0xF6, 0x9B, 0x97, 0xA3, 0x96, 0x81, 0xEC, 0xE7, 0x98 +}; + +int16 Util::toCP850(uint16 latin1) { + if ((latin1 < 0xA0) || ((latin1 - 0xA0) >= ARRAYSIZE(kLatin1ToCP850))) + return 0; + + return kLatin1ToCP850[latin1 - 0xA0]; +} + int16 Util::translateKey(const Common::KeyState &key) { static struct keyS { int16 from; int16 to; } keys[] = { - {Common::KEYCODE_INVALID, kKeyNone }, {Common::KEYCODE_BACKSPACE, kKeyBackspace}, {Common::KEYCODE_SPACE, kKeySpace }, {Common::KEYCODE_RETURN, kKeyReturn }, @@ -216,16 +231,18 @@ int16 Util::translateKey(const Common::KeyState &key) { {Common::KEYCODE_F10, kKeyF10 } }; + // Translate special keys for (int i = 0; i < ARRAYSIZE(keys); i++) if (key.keycode == keys[i].from) return keys[i].to; - if ((key.keycode >= Common::KEYCODE_SPACE) && - (key.keycode <= Common::KEYCODE_DELETE)) { - - // Used as a user input in Gobliins 2 notepad, in the save dialog, ... + // Return the ascii value, for text input + if ((key.ascii >= 32) && (key.ascii <= 127)) return key.ascii; - } + + // Translate international characters into CP850 characters + if ((key.ascii >= 160) && (key.ascii <= 255)) + return toCP850(key.ascii); return 0; } diff --git a/engines/gob/util.h b/engines/gob/util.h index 30bff72325..2e568ad169 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -166,6 +166,7 @@ protected: void addKeyToBuffer(const Common::KeyState &key); bool getKeyFromBuffer(Common::KeyState &key); int16 translateKey(const Common::KeyState &key); + int16 toCP850(uint16 latin1); void checkJoystick(); void keyDown(const Common::Event &event); -- cgit v1.2.3 From 5b02192477cbdc9e8251bd48cac764d6fa61d024 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 18:45:15 +0200 Subject: GOB: Add Font::hasChar() --- engines/gob/video.cpp | 4 ++++ engines/gob/video.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 62bb210a8e..64af34cf62 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -84,6 +84,10 @@ uint16 Font::getCharCount() const { return _endItem - _startItem + 1; } +bool Font::hasChar(uint8 c) const { + return (c >= _startItem) && (c <= _endItem); +} + bool Font::isMonospaced() const { return _charWidths == 0; } diff --git a/engines/gob/video.h b/engines/gob/video.h index a8c1480a6b..122c1e47d5 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -41,6 +41,8 @@ public: uint8 getCharWidth () const; uint8 getCharHeight() const; + bool hasChar(uint8 c) const; + bool isMonospaced() const; void drawLetter(Surface &surf, uint8 c, uint16 x, uint16 y, -- cgit v1.2.3 From 10b9be285149dd21bc38710c1a685800fab75e01 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 19:14:06 +0200 Subject: GOB: Add Util::toCP850Lower() / toCP850Upper() --- engines/gob/util.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ engines/gob/util.h | 5 ++++ 2 files changed, 71 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index e1c16c3257..5ac4ef024e 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -247,6 +247,72 @@ int16 Util::translateKey(const Common::KeyState &key) { return 0; } +static const uint8 kLowerToUpper[][2] = { + {0x81, 0x9A}, + {0x82, 0x90}, + {0x83, 0xB6}, + {0x84, 0x8E}, + {0x85, 0xB7}, + {0x86, 0x8F}, + {0x87, 0x80}, + {0x88, 0xD2}, + {0x89, 0xD3}, + {0x8A, 0xD4}, + {0x8B, 0xD8}, + {0x8C, 0xD7}, + {0x8D, 0xDE}, + {0x91, 0x92}, + {0x93, 0xE2}, + {0x94, 0x99}, + {0x95, 0xE3}, + {0x96, 0xEA}, + {0x97, 0xEB}, + {0x95, 0xE3}, + {0x96, 0xEA}, + {0x97, 0xEB}, + {0x9B, 0x9D}, + {0xA0, 0xB5}, + {0xA1, 0xD6}, + {0xA2, 0xE0}, + {0xA3, 0xE9}, + {0xA4, 0xA5}, + {0xC6, 0xC7}, + {0xD0, 0xD1}, + {0xE4, 0xE5}, + {0xE7, 0xE8}, + {0xEC, 0xED} +}; + +char Util::toCP850Lower(char cp850) { + const uint8 cp = (unsigned char)cp850; + if (cp <= 32) + return cp850; + + if (cp <= 127) + return tolower(cp850); + + for (uint i = 0; i < ARRAYSIZE(kLowerToUpper); i++) + if (cp == kLowerToUpper[i][1]) + return (char)kLowerToUpper[i][0]; + + return cp850; +} + +char Util::toCP850Upper(char cp850) { + const uint8 cp = (unsigned char)cp850; + if (cp <= 32) + return cp850; + + if (cp <= 127) + return toupper(cp850); + + for (uint i = 0; i < ARRAYSIZE(kLowerToUpper); i++) + if (cp == kLowerToUpper[i][0]) + return (char)kLowerToUpper[i][1]; + + return cp850; +} + int16 Util::getKey() { Common::KeyState key; diff --git a/engines/gob/util.h b/engines/gob/util.h index 2e568ad169..a4984c6207 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -143,6 +143,11 @@ public: /** Read a constant-length string out of a stream. */ static Common::String readString(Common::SeekableReadStream &stream, int n); + /** Convert a character in CP850 encoding to the equivalent lower case character. */ + static char toCP850Lower(char cp850); + /** Convert a character in CP850 encoding to the equivalent upper case character. */ + static char toCP850Upper(char cp850); + Util(GobEngine *vm); protected: -- cgit v1.2.3 From 57b1b7ad2496be6f6c2545877576e3c818dc6ef6 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sat, 7 Jul 2012 19:20:07 +0200 Subject: GOB: Implement the Once Upon A Time character generator Still missing the little sprite bouncing around, though. --- engines/gob/pregob/onceupon/onceupon.cpp | 355 ++++++++++++++++++++++++++++++- engines/gob/pregob/onceupon/onceupon.h | 30 ++- 2 files changed, 375 insertions(+), 10 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 8c617e2c41..1d1bfd4629 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -1095,18 +1095,18 @@ int OnceUpon::checkButton(const MenuButton *buttons, uint count, int16 x, int16 return failValue; } -void OnceUpon::drawButton(Surface &dest, const Surface &src, const MenuButton &button) const { - dest.blit(src, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom, button.dstX, button.dstY); +void OnceUpon::drawButton(Surface &dest, const Surface &src, const MenuButton &button, int transp) const { + dest.blit(src, button.srcLeft, button.srcTop, button.srcRight, button.srcBottom, button.dstX, button.dstY, transp); } -void OnceUpon::drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const { +void OnceUpon::drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count, int transp) const { for (uint i = 0; i < count; i++) { const MenuButton &button = buttons[i]; if (!button.needDraw) continue; - drawButton(dest, src, button); + drawButton(dest, src, button, transp); } } @@ -1431,16 +1431,355 @@ bool OnceUpon::sectionStork() { fadeOut(); hideCursor(); - // Completed the section => move one - if (action == kMenuActionNone) { - warning("OnceUpon::sectionStork(): TODO: Character creator"); + // Didn't complete the section + if (action != kMenuActionNone) + return false; + + // Move on to the character generator + + CharGenAction charGenAction = kCharGenRestart; + while (charGenAction == kCharGenRestart) + charGenAction = characterGenerator(); + + // Did we successfully create a character? + return charGenAction == kCharGenDone; +} + +const OnceUpon::MenuButton OnceUpon::kCharGenHeadButtons[] = { + {true, 106, 146, 152, 180, 0, 0, 47, 34, 106, 146, 0}, + {true, 155, 146, 201, 180, 49, 0, 96, 34, 155, 146, 1}, + {true, 204, 146, 250, 180, 98, 0, 145, 34, 204, 146, 2}, + {true, 253, 146, 299, 180, 147, 0, 194, 34, 253, 146, 3} +}; + +const OnceUpon::MenuButton OnceUpon::kCharGenHeads[] = { + {true, 0, 0, 0, 0, 29, 4, 68, 31, 40, 51, 0}, + {true, 0, 0, 0, 0, 83, 4, 113, 31, 45, 51, 1}, + {true, 0, 0, 0, 0, 132, 4, 162, 31, 45, 51, 2}, + {true, 0, 0, 0, 0, 182, 4, 211, 31, 45, 51, 3} +}; + +const OnceUpon::MenuButton OnceUpon::kCharGenHairButtons[] = { + {true, 105, 55, 124, 70, 271, 1, 289, 15, 105, 55, 0x04}, + {true, 105, 74, 124, 89, 271, 20, 289, 34, 105, 74, 0x07} +}; + +const OnceUpon::MenuButton OnceUpon::kCharGenJacketButtons[] = { + {true, 105, 90, 124, 105, 271, 39, 289, 53, 105, 90, 0x06}, + {true, 105, 109, 124, 124, 271, 58, 289, 72, 105, 109, 0x02} +}; + +const OnceUpon::MenuButton OnceUpon::kCharGenTrousersButtons[] = { + {true, 105, 140, 124, 155, 271, 77, 289, 91, 105, 140, 0x01}, + {true, 105, 159, 124, 174, 271, 96, 289, 110, 105, 159, 0x03} +}; + +const OnceUpon::MenuButton OnceUpon::kCharGenNameEntry[] = { + {true, 0, 0, 0, 0, 0, 38, 54, 48, 140, 145, 0}, + {true, 0, 0, 0, 0, 106, 38, 159, 48, 195, 145, 0}, + {true, 0, 0, 0, 0, 0, 105, 54, 121, 140, 156, 0}, + {true, 0, 0, 0, 0, 106, 105, 159, 121, 195, 156, 0} +}; + +enum CharGenState { + kCharGenStateHead = 0, // Choose a head + kCharGenStateHair , // Choose hair color + kCharGenStateJacket , // Choose jacket color + kCharGenStateTrousers , // Choose trousers color + kCharGenStateName , // Choose name + kCharGenStateSure , // "Are you sure?" + kCharGenStateStoryName , // "We're going to tell the story of $NAME" + kCharGenStateFinish // Finished +}; + +void OnceUpon::recolor(Surface &surface, uint8 from, uint8 to) { + for (Pixel p = surface.get(); p.isValid(); ++p) + if (p.get() == from) + p.set(to); +} + +void OnceUpon::charGenSetup(uint stage) { + Surface choix(320, 200, 1), elchoix(320, 200, 1), paperDoll(65, 137, 1); + + _vm->_video->drawPackedSprite("choix.cmp" , choix); + _vm->_video->drawPackedSprite("elchoix.cmp", elchoix); + + paperDoll.blit(choix, 200, 0, 264, 136, 0, 0); + + GCTFile *text = loadGCT(getLocFile("choix.gc")); + text->setArea(17, 18, 303, 41); + text->setText(9, _name); + + // Background + _vm->_video->drawPackedSprite("cadre.cmp", *_vm->_draw->_backSurface); + _vm->_draw->_backSurface->fillRect(16, 50, 303, 187, 5); + + // Character sprite frame + _vm->_draw->_backSurface->blit(choix, 0, 38, 159, 121, 140, 54); + + // Recolor the paper doll parts + if (_colorHair != 0xFF) + recolor(elchoix , 0x0C, _colorHair); + if (_colorJacket != 0xFF) + recolor(paperDoll, 0x0A, _colorJacket); + if (_colorTrousers != 0xFF) + recolor(paperDoll, 0x09, _colorTrousers); + + _vm->_draw->_backSurface->blit(paperDoll, 32, 51); + + // Paper doll head + if (_head != 0xFF) + drawButton(*_vm->_draw->_backSurface, elchoix, kCharGenHeads[_head], 0); + + if (stage == kCharGenStateHead) { + // Head buttons + drawButtons(*_vm->_draw->_backSurface, choix, kCharGenHeadButtons, ARRAYSIZE(kCharGenHeadButtons)); + + // "Choose a head" + int16 left, top, right, bottom; + text->draw(*_vm->_draw->_backSurface, 5, *_plettre, 10, left, top, right, bottom); + + } else if (stage == kCharGenStateHair) { + // Hair color buttons + drawButtons(*_vm->_draw->_backSurface, choix, kCharGenHairButtons, ARRAYSIZE(kCharGenHairButtons)); + + // "What color is the hair?" + int16 left, top, right, bottom; + text->draw(*_vm->_draw->_backSurface, 6, *_plettre, 10, left, top, right, bottom); + + } else if (stage == kCharGenStateJacket) { + // Jacket color buttons + drawButtons(*_vm->_draw->_backSurface, choix, kCharGenJacketButtons, ARRAYSIZE(kCharGenJacketButtons)); + + // "What color is the jacket?" + int16 left, top, right, bottom; + text->draw(*_vm->_draw->_backSurface, 7, *_plettre, 10, left, top, right, bottom); + + } else if (stage == kCharGenStateTrousers) { + // Trousers color buttons + drawButtons(*_vm->_draw->_backSurface, choix, kCharGenTrousersButtons, ARRAYSIZE(kCharGenTrousersButtons)); + + // "What color are the trousers?" + int16 left, top, right, bottom; + text->draw(*_vm->_draw->_backSurface, 8, *_plettre, 10, left, top, right, bottom); + + } else if (stage == kCharGenStateName) { + // Name entry field + drawButtons(*_vm->_draw->_backSurface, choix, kCharGenNameEntry, ARRAYSIZE(kCharGenNameEntry)); + + // "Enter name" + int16 left, top, right, bottom; + text->draw(*_vm->_draw->_backSurface, 10, *_plettre, 10, left, top, right, bottom); + + charGenDrawName(); + } else if (stage == kCharGenStateSure) { + // Name entry field + drawButtons(*_vm->_draw->_backSurface, choix, kCharGenNameEntry, ARRAYSIZE(kCharGenNameEntry)); + + // "Are you sure?" + TXTFile *sure = loadTXT(getLocFile("estu.tx"), TXTFile::kFormatStringPositionColor); + sure->draw(*_vm->_draw->_backSurface, &_plettre, 1); + delete sure; + + charGenDrawName(); + } else if (stage == kCharGenStateStoryName) { + + // "We're going to tell the story of $NAME" + int16 left, top, right, bottom; + text->draw(*_vm->_draw->_backSurface, 11, *_plettre, 10, left, top, right, bottom); + } + + delete text; +} + +bool OnceUpon::enterString(Common::String &name, int16 key, uint maxLength, const Font &font) { + if (key == 0) + return true; + + if (key == kKeyBackspace) { + name.deleteLastChar(); + return true; + } + + if ((key >= ' ') && (key <= 0xFF)) { + if (name.size() >= maxLength) + return false; + + if (!font.hasChar(key)) + return false; + + name += (char) key; return true; } - // Didn't complete the section return false; } +void OnceUpon::charGenDrawName() { + _vm->_draw->_backSurface->fillRect(147, 151, 243, 166, 1); + + const int16 nameY = 151 + ((166 - 151 + 1 - _plettre->getCharHeight()) / 2); + const int16 nameX = 147 + ((243 - 147 + 1 - (15 * _plettre->getCharWidth ())) / 2); + + _plettre->drawString(_name, nameX, nameY, 10, 0, true, *_vm->_draw->_backSurface); + + const int16 cursorLeft = nameX + _name.size() * _plettre->getCharWidth(); + const int16 cursorTop = nameY; + const int16 cursorRight = cursorLeft + _plettre->getCharWidth() - 1; + const int16 cursorBottom = cursorTop + _plettre->getCharHeight() - 1; + + _vm->_draw->_backSurface->fillRect(cursorLeft, cursorTop, cursorRight, cursorBottom, 10); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 147, 151, 243, 166); +} + +OnceUpon::CharGenAction OnceUpon::characterGenerator() { + fadeOut(); + hideCursor(); + setGameCursor(); + + showWait(1); + + _name.clear(); + + _head = 0xFF; + _colorHair = 0xFF; + _colorJacket = 0xFF; + _colorTrousers = 0xFF; + + CharGenState state = kCharGenStateHead; + charGenSetup(state); + + fadeOut(); + _vm->_draw->forceBlit(); + + CharGenAction action = kCharGenRestart; + while (!_vm->shouldQuit() && (state != kCharGenStateFinish)) { + // Check user input + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + + int16 key = checkInput(mouseX, mouseY, mouseButtons); + + MenuAction menuAction = doIngameMenu(key, mouseButtons); + if (menuAction != kMenuActionNone) { + state = kCharGenStateFinish; + action = kCharGenAbort; + break; + } + + // clearAnim(anims); + + if (state == kCharGenStateStoryName) { + if ((mouseButtons != kMouseButtonsNone) || (key != 0)) { + state = kCharGenStateFinish; + action = kCharGenDone; + break; + } + } + + if (state == kCharGenStateSure) { + // Not sure => restart + if ((key == 'N') || (key == 'n')) { // No / Nein / Non + state = kCharGenStateFinish; + action = kCharGenRestart; + break; + } + + if ((key == 'Y') || (key == 'y') || // Yes + (key == 'J') || (key == 'j') || // Ja + (key == 'S') || (key == 's') || // Si + (key == 'O') || (key == 'o')) { // Oui + + state = kCharGenStateStoryName; + charGenSetup(state); + _vm->_draw->forceBlit(); + } + } + + if (state == kCharGenStateName) { + if (enterString(_name, key, 14, *_plettre)) { + _vm->_draw->_backSurface->fillRect(147, 151, 243, 166, 1); + + const int16 nameY = 151 + ((166 - 151 + 1 - _plettre->getCharHeight()) / 2); + const int16 nameX = 147 + ((243 - 147 + 1 - (15 * _plettre->getCharWidth ())) / 2); + + _plettre->drawString(_name, nameX, nameY, 10, 0, true, *_vm->_draw->_backSurface); + + const int16 cursorLeft = nameX + _name.size() * _plettre->getCharWidth(); + const int16 cursorTop = nameY; + const int16 cursorRight = cursorLeft + _plettre->getCharWidth() - 1; + const int16 cursorBottom = cursorTop + _plettre->getCharHeight() - 1; + + _vm->_draw->_backSurface->fillRect(cursorLeft, cursorTop, cursorRight, cursorBottom, 10); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 147, 151, 243, 166); + } + + if ((key == kKeyReturn) && !_name.empty()) { + _name.setChar(Util::toCP850Upper(_name[0]), 0); + + state = kCharGenStateSure; + charGenSetup(state); + _vm->_draw->forceBlit(); + } + } + + if (mouseButtons == kMouseButtonsLeft) { + int trousers = checkButton(kCharGenTrousersButtons, ARRAYSIZE(kCharGenTrousersButtons), mouseX, mouseY); + if ((state == kCharGenStateTrousers) && (trousers >= 0)) { + _colorTrousers = trousers; + + state = kCharGenStateName; + charGenSetup(state); + _vm->_draw->forceBlit(); + } + + int jacket = checkButton(kCharGenJacketButtons, ARRAYSIZE(kCharGenJacketButtons), mouseX, mouseY); + if ((state == kCharGenStateJacket) && (jacket >= 0)) { + _colorJacket = jacket; + + state = kCharGenStateTrousers; + charGenSetup(state); + _vm->_draw->forceBlit(); + } + + int hair = checkButton(kCharGenHairButtons, ARRAYSIZE(kCharGenHairButtons), mouseX, mouseY); + if ((state == kCharGenStateHair) && (hair >= 0)) { + _colorHair = hair; + + state = kCharGenStateJacket; + charGenSetup(state); + _vm->_draw->forceBlit(); + } + + int head = checkButton(kCharGenHeadButtons, ARRAYSIZE(kCharGenHeadButtons), mouseX, mouseY); + if ((state == kCharGenStateHead) && (head >= 0)) { + _head = head; + + state = kCharGenStateHair; + charGenSetup(state); + _vm->_draw->forceBlit(); + } + } + + //drawAnim(anims); + showCursor(); + fadeIn(); + + endFrame(true); + } + + fadeOut(); + hideCursor(); + + if (_vm->shouldQuit()) + return kCharGenAbort; + + return action; +} + bool OnceUpon::sectionChapter1() { showChapter(1); return true; diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 386d410c95..3b924a11e6 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -139,6 +139,13 @@ private: kSoundMAX }; + /** Action the character generation wants us to take. */ + enum CharGenAction { + kCharGenDone = 0, ///< Created a character, move on. + kCharGenAbort , ///< Aborted the character generation. + kCharGenRestart ///< Restart the character generation. + }; + /** A complete screen backup. */ struct ScreenBackup { Surface *screen; ///< Screen contents. @@ -165,6 +172,13 @@ private: static const MenuButton kSectionStorkHouses[]; + static const MenuButton kCharGenHeadButtons[]; + static const MenuButton kCharGenHeads[]; + static const MenuButton kCharGenHairButtons[]; + static const MenuButton kCharGenJacketButtons[]; + static const MenuButton kCharGenTrousersButtons[]; + static const MenuButton kCharGenNameEntry[]; + /** All general game sounds we know about. */ static const char *kSound[kSoundMAX]; @@ -259,9 +273,9 @@ private: int checkButton(const MenuButton *buttons, uint count, int16 x, int16 y, int failValue = -1) const; /** Draw a menu button. */ - void drawButton (Surface &dest, const Surface &src, const MenuButton &button) const; + void drawButton (Surface &dest, const Surface &src, const MenuButton &button, int transp = -1) const; /** Draw multiple menu buttons. */ - void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count) const; + void drawButtons(Surface &dest, const Surface &src, const MenuButton *buttons, uint count, int transp = -1) const; /** Draw a border around a button. */ void drawButtonBorder(const MenuButton &button, uint8 color); @@ -296,6 +310,13 @@ private: bool sectionChapter7(); bool sectionEnd(); + CharGenAction characterGenerator(); + void charGenSetup(uint stage); + void charGenDrawName(); + + static void recolor(Surface &surface, uint8 from, uint8 to); + static bool enterString(Common::String &name, int16 key, uint maxLength, const Font &font); + /** Did we open the game archives? */ bool _openedArchives; @@ -315,6 +336,11 @@ private: int _section; ///< The current game section. Common::String _name; ///< The name of the child. + + uint8 _head; + uint8 _colorHair; + uint8 _colorJacket; + uint8 _colorTrousers; }; } // End of namespace OnceUpon -- cgit v1.2.3 From baec4d87781d24786f0b76e83efee3bca7f9afea Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 00:19:24 +0200 Subject: GOB: Move recolor() into class Surface --- engines/gob/pregob/onceupon/onceupon.cpp | 18 +++++++----------- engines/gob/pregob/onceupon/onceupon.h | 1 - engines/gob/surface.cpp | 6 ++++++ engines/gob/surface.h | 2 ++ 4 files changed, 15 insertions(+), 12 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 1d1bfd4629..53fa3bcece 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -1492,12 +1492,6 @@ enum CharGenState { kCharGenStateFinish // Finished }; -void OnceUpon::recolor(Surface &surface, uint8 from, uint8 to) { - for (Pixel p = surface.get(); p.isValid(); ++p) - if (p.get() == from) - p.set(to); -} - void OnceUpon::charGenSetup(uint stage) { Surface choix(320, 200, 1), elchoix(320, 200, 1), paperDoll(65, 137, 1); @@ -1518,12 +1512,14 @@ void OnceUpon::charGenSetup(uint stage) { _vm->_draw->_backSurface->blit(choix, 0, 38, 159, 121, 140, 54); // Recolor the paper doll parts - if (_colorHair != 0xFF) - recolor(elchoix , 0x0C, _colorHair); - if (_colorJacket != 0xFF) - recolor(paperDoll, 0x0A, _colorJacket); + if (_colorHair != 0xFF) + elchoix.recolor(0x0C, _colorHair); + + if (_colorJacket != 0xFF) + paperDoll.recolor(0x0A, _colorJacket); + if (_colorTrousers != 0xFF) - recolor(paperDoll, 0x09, _colorTrousers); + paperDoll.recolor(0x09, _colorTrousers); _vm->_draw->_backSurface->blit(paperDoll, 32, 51); diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 3b924a11e6..80fcba35bd 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -314,7 +314,6 @@ private: void charGenSetup(uint stage); void charGenDrawName(); - static void recolor(Surface &surface, uint8 from, uint8 to); static bool enterString(Common::String &name, int16 key, uint maxLength, const Font &font); diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index 3eaf741be2..afbb7c3bae 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -684,6 +684,12 @@ void Surface::shadeRect(uint16 left, uint16 top, uint16 right, uint16 bottom, } +void Surface::recolor(uint8 from, uint8 to) { + for (Pixel p = get(); p.isValid(); ++p) + if (p.get() == from) + p.set(to); +} + void Surface::putPixel(uint16 x, uint16 y, uint32 color) { if ((x >= _width) || (y >= _height)) return; diff --git a/engines/gob/surface.h b/engines/gob/surface.h index 09be8d1a49..8f895a7910 100644 --- a/engines/gob/surface.h +++ b/engines/gob/surface.h @@ -156,6 +156,8 @@ public: void shadeRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color, uint8 strength); + void recolor(uint8 from, uint8 to); + void putPixel(uint16 x, uint16 y, uint32 color); void drawLine(uint16 x0, uint16 y0, uint16 x1, uint16 y1, uint32 color); void drawRect(uint16 left, uint16 top, uint16 right, uint16 bottom, uint32 color); -- cgit v1.2.3 From 20a96733a5f982e427a9143ded14e2af418ac6df Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 00:19:48 +0200 Subject: GOB: Add CMPFile::recolor() and ANIFile::recolor() --- engines/gob/anifile.cpp | 5 +++++ engines/gob/anifile.h | 3 +++ engines/gob/cmpfile.cpp | 5 +++++ engines/gob/cmpfile.h | 2 ++ 4 files changed, 15 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/anifile.cpp b/engines/gob/anifile.cpp index e6bf30f4d7..085ac800cd 100644 --- a/engines/gob/anifile.cpp +++ b/engines/gob/anifile.cpp @@ -289,4 +289,9 @@ void ANIFile::drawLayer(Surface &dest, uint16 layer, uint16 part, _layers[layer]->draw(dest, part, x, y, transp); } +void ANIFile::recolor(uint8 from, uint8 to) { + for (LayerArray::iterator l = _layers.begin(); l != _layers.end(); ++l) + (*l)->recolor(from, to); +} + } // End of namespace Gob diff --git a/engines/gob/anifile.h b/engines/gob/anifile.h index b6d9c735b5..c930aafc6b 100644 --- a/engines/gob/anifile.h +++ b/engines/gob/anifile.h @@ -92,6 +92,9 @@ public: /** Draw an animation frame. */ void draw(Surface &dest, uint16 animation, uint16 frame, int16 x, int16 y) const; + /** Recolor the animation sprites. */ + void recolor(uint8 from, uint8 to); + private: typedef Common::Array LayerArray; typedef Common::Array AnimationArray; diff --git a/engines/gob/cmpfile.cpp b/engines/gob/cmpfile.cpp index 1cd1375879..d304958f76 100644 --- a/engines/gob/cmpfile.cpp +++ b/engines/gob/cmpfile.cpp @@ -250,4 +250,9 @@ uint16 CMPFile::addSprite(uint16 left, uint16 top, uint16 right, uint16 bottom) return _coordinates->add(left, top, right, bottom); } +void CMPFile::recolor(uint8 from, uint8 to) { + if (_surface) + _surface->recolor(from, to); +} + } // End of namespace Gob diff --git a/engines/gob/cmpfile.h b/engines/gob/cmpfile.h index 2b669e4d38..9c858238af 100644 --- a/engines/gob/cmpfile.h +++ b/engines/gob/cmpfile.h @@ -70,6 +70,8 @@ public: uint16 addSprite(uint16 left, uint16 top, uint16 right, uint16 bottom); + void recolor(uint8 from, uint8 to); + private: GobEngine *_vm; -- cgit v1.2.3 From 6533047514d0ab1cc7273a0c071fa24b6c2f7b71 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 00:20:36 +0200 Subject: GOB: Add the walking child in the character generator --- engines/gob/module.mk | 1 + engines/gob/pregob/onceupon/chargenchild.cpp | 104 +++++++++++++++++++++++++++ engines/gob/pregob/onceupon/chargenchild.h | 51 +++++++++++++ engines/gob/pregob/onceupon/onceupon.cpp | 22 +++++- 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 engines/gob/pregob/onceupon/chargenchild.cpp create mode 100644 engines/gob/pregob/onceupon/chargenchild.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 15351848de..4858e97c60 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -85,6 +85,7 @@ MODULE_OBJS := \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ pregob/onceupon/stork.o \ + pregob/onceupon/chargenchild.o \ minigames/geisha/evilfish.o \ minigames/geisha/oko.o \ minigames/geisha/meter.o \ diff --git a/engines/gob/pregob/onceupon/chargenchild.cpp b/engines/gob/pregob/onceupon/chargenchild.cpp new file mode 100644 index 0000000000..7150c69b5f --- /dev/null +++ b/engines/gob/pregob/onceupon/chargenchild.cpp @@ -0,0 +1,104 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/surface.h" +#include "gob/anifile.h" + +#include "gob/pregob/onceupon/chargenchild.h" + +enum Animation { + kAnimWalkLeft = 0, + kAnimWalkRight = 1, + kAnimJumpLeft = 2, + kAnimJumpRight = 3, + kAnimTapFoot = 14 +}; + +namespace Gob { + +namespace OnceUpon { + +CharGenChild::CharGenChild(const ANIFile &ani) : ANIObject(ani) { + setPosition(265, 110); + setAnimation(kAnimWalkLeft); + setVisible(true); + setPause(false); +} + +CharGenChild::~CharGenChild() { +} + +void CharGenChild::advance() { + bool wasLastFrame = lastFrame(); + + ANIObject::advance(); + + int16 x, y, left, top, width, height; + getPosition(x, y); + getFramePosition(left, top); + getFrameSize(width, height); + + const int16 right = left + width - 1; + + switch (getAnimation()) { + case kAnimWalkLeft: + if (left <= 147) + setAnimation(kAnimWalkRight); + break; + + case kAnimWalkRight: + if (right >= 290) { + setAnimation(kAnimJumpLeft); + + setPosition(x, y - 14); + } + break; + + case kAnimJumpLeft: + if (wasLastFrame) { + setAnimation(kAnimTapFoot); + + setPosition(x, y - 10); + } + break; + + case kAnimTapFoot: + if (wasLastFrame) { + setAnimation(kAnimJumpRight); + + setPosition(x, y + 10); + } + break; + + case kAnimJumpRight: + if (wasLastFrame) { + setAnimation(kAnimWalkLeft); + + setPosition(x, y + 14); + } + break; + } +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/chargenchild.h b/engines/gob/pregob/onceupon/chargenchild.h new file mode 100644 index 0000000000..afbe3fd2fe --- /dev/null +++ b/engines/gob/pregob/onceupon/chargenchild.h @@ -0,0 +1,51 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_CHARGENCHILD_H +#define GOB_PREGOB_ONCEUPON_CHARGENCHILD_H + +#include "common/system.h" + +#include "gob/aniobject.h" + +namespace Gob { + +class Surface; +class ANIFile; + +namespace OnceUpon { + +/** The child running around on the character generator screen. */ +class CharGenChild : public ANIObject { +public: + CharGenChild(const ANIFile &ani); + ~CharGenChild(); + + /** Advance the animation to the next frame. */ + void advance(); +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_CHARGENCHILD_H diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 53fa3bcece..7eef740139 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -37,6 +37,7 @@ #include "gob/pregob/onceupon/onceupon.h" #include "gob/pregob/onceupon/palettes.h" +#include "gob/pregob/onceupon/chargenchild.h" static const uint kLanguageCount = 5; @@ -1646,6 +1647,15 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { CharGenState state = kCharGenStateHead; charGenSetup(state); + ANIFile ani(_vm, "ba.ani", 320); + ANIList anims; + + anims.push_back(new CharGenChild(ani)); + + ani.recolor(0x0F, 0x0C); + ani.recolor(0x0E, 0x0A); + ani.recolor(0x08, 0x09); + fadeOut(); _vm->_draw->forceBlit(); @@ -1665,7 +1675,7 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { break; } - // clearAnim(anims); + clearAnim(anims); if (state == kCharGenStateStoryName) { if ((mouseButtons != kMouseButtonsNone) || (key != 0)) { @@ -1727,6 +1737,8 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { if ((state == kCharGenStateTrousers) && (trousers >= 0)) { _colorTrousers = trousers; + ani.recolor(0x09, _colorTrousers); + state = kCharGenStateName; charGenSetup(state); _vm->_draw->forceBlit(); @@ -1736,6 +1748,8 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { if ((state == kCharGenStateJacket) && (jacket >= 0)) { _colorJacket = jacket; + ani.recolor(0x0A, _colorJacket); + state = kCharGenStateTrousers; charGenSetup(state); _vm->_draw->forceBlit(); @@ -1745,6 +1759,8 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { if ((state == kCharGenStateHair) && (hair >= 0)) { _colorHair = hair; + ani.recolor(0x0C, _colorHair); + state = kCharGenStateJacket; charGenSetup(state); _vm->_draw->forceBlit(); @@ -1760,7 +1776,7 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { } } - //drawAnim(anims); + drawAnim(anims); showCursor(); fadeIn(); @@ -1770,6 +1786,8 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { fadeOut(); hideCursor(); + freeAnims(anims); + if (_vm->shouldQuit()) return kCharGenAbort; -- cgit v1.2.3 From 9c32fd2360d9fa18ceac6fefc571c6610965d361 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 00:46:24 +0200 Subject: GOB: Add PreGob::beep() --- engines/gob/pregob/pregob.cpp | 4 ++++ engines/gob/pregob/pregob.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 033eea89f2..42b5a8fb9c 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -208,6 +208,10 @@ void PreGob::playSoundFile(const Common::String &file, int16 frequency, int16 re stopSound(); } +void PreGob::beep(int16 frequency, int32 length) { + _vm->_sound->speakerOn(frequency, length); +} + void PreGob::endFrame(bool doInput) { _vm->_draw->blitInvalidated(); _vm->_util->waitEndFrame(); diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index 686727b08b..da0de60dd8 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -142,6 +142,9 @@ protected: /** Play a sound until it ends or is interrupted by a keypress. */ void playSoundFile(const Common::String &file, int16 frequency = 0, int16 repCount = 0, bool interruptible = true); + /** Beep the PC speaker. */ + void beep(int16 frequency, int32 length); + // -- Input -- -- cgit v1.2.3 From 943c6af82af9e14062c1aa1940aea2f625121368 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 00:47:03 +0200 Subject: GOB: Add the sounds in the Once Upon A Time character generator --- engines/gob/pregob/onceupon/chargenchild.cpp | 13 +++++++++++++ engines/gob/pregob/onceupon/chargenchild.h | 9 +++++++++ engines/gob/pregob/onceupon/onceupon.cpp | 24 ++++++++++++++++++++---- engines/gob/pregob/onceupon/onceupon.h | 1 + 4 files changed, 43 insertions(+), 4 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/chargenchild.cpp b/engines/gob/pregob/onceupon/chargenchild.cpp index 7150c69b5f..ba099e4937 100644 --- a/engines/gob/pregob/onceupon/chargenchild.cpp +++ b/engines/gob/pregob/onceupon/chargenchild.cpp @@ -99,6 +99,19 @@ void CharGenChild::advance() { } } +CharGenChild::Sound CharGenChild::shouldPlaySound() const { + const uint16 anim = getAnimation(); + const uint16 frame = getFrame(); + + if (((anim == kAnimWalkLeft) || (anim == kAnimWalkRight)) && ((frame == 1) || (frame == 6))) + return kSoundWalk; + + if (((anim == kAnimJumpLeft) || (anim == kAnimJumpRight)) && (frame == 0)) + return kSoundJump; + + return kSoundNone; +} + } // End of namespace OnceUpon } // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/chargenchild.h b/engines/gob/pregob/onceupon/chargenchild.h index afbe3fd2fe..3b09ef112a 100644 --- a/engines/gob/pregob/onceupon/chargenchild.h +++ b/engines/gob/pregob/onceupon/chargenchild.h @@ -37,11 +37,20 @@ namespace OnceUpon { /** The child running around on the character generator screen. */ class CharGenChild : public ANIObject { public: + enum Sound { + kSoundNone = 0, + kSoundWalk , + kSoundJump + }; + CharGenChild(const ANIFile &ani); ~CharGenChild(); /** Advance the animation to the next frame. */ void advance(); + + /** Should we play a sound right now? */ + Sound shouldPlaySound() const; }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 7eef740139..f9e093374b 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -136,7 +136,8 @@ const OnceUpon::MenuButton OnceUpon::kLanguageButtons[] = { const char *OnceUpon::kSound[kSoundMAX] = { "diamant.snd", // kSoundClick - "cigogne.snd" // kSoundStork + "cigogne.snd", // kSoundStork + "saute.snd" // kSoundJump }; const OnceUpon::SectionFunc OnceUpon::kSectionFuncs[kSectionCount] = { @@ -1648,14 +1649,16 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { charGenSetup(state); ANIFile ani(_vm, "ba.ani", 320); - ANIList anims; - - anims.push_back(new CharGenChild(ani)); ani.recolor(0x0F, 0x0C); ani.recolor(0x0E, 0x0A); ani.recolor(0x08, 0x09); + CharGenChild *child = new CharGenChild(ani); + + ANIList anims; + anims.push_back(child); + fadeOut(); _vm->_draw->forceBlit(); @@ -1733,6 +1736,9 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { } if (mouseButtons == kMouseButtonsLeft) { + stopSound(); + playSound(kSoundClick); + int trousers = checkButton(kCharGenTrousersButtons, ARRAYSIZE(kCharGenTrousersButtons), mouseX, mouseY); if ((state == kCharGenStateTrousers) && (trousers >= 0)) { _colorTrousers = trousers; @@ -1777,6 +1783,16 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { } drawAnim(anims); + + // Play the child sounds + CharGenChild::Sound childSound = child->shouldPlaySound(); + if (childSound == CharGenChild::kSoundWalk) { + beep(50, 10); + } else if (childSound == CharGenChild::kSoundJump) { + stopSound(); + playSound(kSoundJump); + } + showCursor(); fadeIn(); diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 80fcba35bd..d2e1feb604 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -136,6 +136,7 @@ private: enum Sound { kSoundClick = 0, kSoundStork , + kSoundJump , kSoundMAX }; -- cgit v1.2.3 From 4bc80cd8810b4d328103e8bac75055a841b22d82 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 01:00:48 +0200 Subject: GOB: Allow spaces in the Once Upon A Time character generator --- engines/gob/pregob/onceupon/onceupon.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index f9e093374b..abee238d34 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -1599,6 +1599,9 @@ bool OnceUpon::enterString(Common::String &name, int16 key, uint maxLength, cons return true; } + if (key == kKeySpace) + key = ' '; + if ((key >= ' ') && (key <= 0xFF)) { if (name.size() >= maxLength) return false; @@ -1727,6 +1730,7 @@ OnceUpon::CharGenAction OnceUpon::characterGenerator() { } if ((key == kKeyReturn) && !_name.empty()) { + _name.trim(); _name.setChar(Util::toCP850Upper(_name[0]), 0); state = kCharGenStateSure; -- cgit v1.2.3 From 734329dcc10e5d22da716484034c78f8bea927c5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 15:37:24 +0200 Subject: GOB: Name the Once Upon A Time frame a bit more --- engines/gob/pregob/onceupon/onceupon.cpp | 45 +++++++++++++++++++------------- engines/gob/pregob/onceupon/onceupon.h | 14 +++++----- 2 files changed, 35 insertions(+), 24 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index abee238d34..7f59790d1d 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -143,17 +143,17 @@ const char *OnceUpon::kSound[kSoundMAX] = { const OnceUpon::SectionFunc OnceUpon::kSectionFuncs[kSectionCount] = { &OnceUpon::sectionStork, &OnceUpon::sectionChapter1, - &OnceUpon::section02, + &OnceUpon::sectionParents, &OnceUpon::sectionChapter2, - &OnceUpon::section04, + &OnceUpon::sectionForest0, &OnceUpon::sectionChapter3, - &OnceUpon::section06, + &OnceUpon::sectionEvilCastle, &OnceUpon::sectionChapter4, - &OnceUpon::section08, + &OnceUpon::sectionForest1, &OnceUpon::sectionChapter5, - &OnceUpon::section10, + &OnceUpon::sectionBossFight, &OnceUpon::sectionChapter6, - &OnceUpon::section12, + &OnceUpon::sectionForest2, &OnceUpon::sectionChapter7, &OnceUpon::sectionEnd }; @@ -230,6 +230,13 @@ void OnceUpon::init() { // Default name _name = "Nemo"; + + // Default character properties + _house = 0; + _head = 0; + _colorHair = 0; + _colorJacket = 0; + _colorTrousers = 0; } void OnceUpon::deinit() { @@ -1403,6 +1410,8 @@ bool OnceUpon::sectionStork() { int house = checkButton(param.houses, param.houseCount, mouseX, mouseY); if ((state == kStorkStateWaitUser) && (house >= 0)) { + _house = house; + stork->dropBundle(param.drops[house]); state = kStorkStateWaitBundle; @@ -1819,8 +1828,8 @@ bool OnceUpon::sectionChapter1() { return true; } -bool OnceUpon::section02() { - warning("OnceUpon::section02(): TODO"); +bool OnceUpon::sectionParents() { + warning("OnceUpon::sectionParents(): TODO"); return true; } @@ -1829,8 +1838,8 @@ bool OnceUpon::sectionChapter2() { return true; } -bool OnceUpon::section04() { - warning("OnceUpon::section04(): TODO"); +bool OnceUpon::sectionForest0() { + warning("OnceUpon::sectionForest0(): TODO"); return true; } @@ -1839,8 +1848,8 @@ bool OnceUpon::sectionChapter3() { return true; } -bool OnceUpon::section06() { - warning("OnceUpon::section06(): TODO"); +bool OnceUpon::sectionEvilCastle() { + warning("OnceUpon::sectionEvilCastle(): TODO"); return true; } @@ -1849,8 +1858,8 @@ bool OnceUpon::sectionChapter4() { return true; } -bool OnceUpon::section08() { - warning("OnceUpon::section08(): TODO"); +bool OnceUpon::sectionForest1() { + warning("OnceUpon::sectionForest1(): TODO"); return true; } @@ -1859,8 +1868,8 @@ bool OnceUpon::sectionChapter5() { return true; } -bool OnceUpon::section10() { - warning("OnceUpon::section10(): TODO"); +bool OnceUpon::sectionBossFight() { + warning("OnceUpon::sectionBossFight(): TODO"); return true; } @@ -1869,8 +1878,8 @@ bool OnceUpon::sectionChapter6() { return true; } -bool OnceUpon::section12() { - warning("OnceUpon::section12(): TODO"); +bool OnceUpon::sectionForest2() { + warning("OnceUpon::sectionForest2(): TODO"); return true; } diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index d2e1feb604..2f25060a37 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -297,17 +297,17 @@ private: bool sectionStork(); bool sectionChapter1(); - bool section02(); + bool sectionParents(); bool sectionChapter2(); - bool section04(); + bool sectionForest0(); bool sectionChapter3(); - bool section06(); + bool sectionEvilCastle(); bool sectionChapter4(); - bool section08(); + bool sectionForest1(); bool sectionChapter5(); - bool section10(); + bool sectionBossFight(); bool sectionChapter6(); - bool section12(); + bool sectionForest2(); bool sectionChapter7(); bool sectionEnd(); @@ -337,6 +337,8 @@ private: Common::String _name; ///< The name of the child. + uint8 _house; + uint8 _head; uint8 _colorHair; uint8 _colorJacket; -- cgit v1.2.3 From f4cd726802732f7f0990eb213c2c9d16da217eec Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 20:08:24 +0200 Subject: GOB: Add a class handling simple SEQ files --- engines/gob/module.mk | 1 + engines/gob/pregob/seqfile.cpp | 384 +++++++++++++++++++++++++++++++++++++++++ engines/gob/pregob/seqfile.h | 193 +++++++++++++++++++++ 3 files changed, 578 insertions(+) create mode 100644 engines/gob/pregob/seqfile.cpp create mode 100644 engines/gob/pregob/seqfile.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 4858e97c60..04e55dcf16 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -81,6 +81,7 @@ MODULE_OBJS := \ pregob/pregob.o \ pregob/txtfile.o \ pregob/gctfile.o \ + pregob/seqfile.o \ pregob/onceupon/onceupon.o \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ diff --git a/engines/gob/pregob/seqfile.cpp b/engines/gob/pregob/seqfile.cpp new file mode 100644 index 0000000000..91973bbb85 --- /dev/null +++ b/engines/gob/pregob/seqfile.cpp @@ -0,0 +1,384 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/str.h" +#include "common/stream.h" + +#include "gob/gob.h" +#include "gob/dataio.h" +#include "gob/draw.h" +#include "gob/decfile.h" +#include "gob/anifile.h" +#include "gob/aniobject.h" + +#include "gob/pregob/seqfile.h" + +namespace Gob { + +SEQFile::SEQFile(GobEngine *vm, const Common::String &fileName) : _vm(vm) { + for (uint i = 0; i < kObjectCount; i++) + _objects[i].object = 0; + + Common::SeekableReadStream *seq = _vm->_dataIO->getFile(Util::setExtension(fileName, ".SEQ")); + if (!seq) { + warning("SEQFile::SEQFile(): No such file \"%s\"", fileName.c_str()); + return; + } + + load(*seq); + + delete seq; +} + +SEQFile::~SEQFile() { + for (uint i = 0; i < kObjectCount; i++) + delete _objects[i].object; + + for (Backgrounds::iterator b = _backgrounds.begin(); b != _backgrounds.end(); ++b) + delete *b; + + for (Animations::iterator a = _animations.begin(); a != _animations.end(); ++a) + delete *a; +} + +void SEQFile::load(Common::SeekableReadStream &seq) { + const uint16 decCount = (uint16)seq.readByte() + 1; + const uint16 aniCount = (uint16)seq.readByte() + 1; + + // Load backgrounds + _backgrounds.reserve(decCount); + for (uint i = 0; i < decCount; i++) { + const Common::String dec = Util::readString(seq, 13); + + if (!_vm->_dataIO->hasFile(dec)) { + warning("SEQFile::load(): No such background \"%s\"", dec.c_str()); + return; + } + + _backgrounds.push_back(new DECFile(_vm, dec, 320, 200)); + } + + // Load animations + _animations.reserve(aniCount); + for (uint i = 0; i < aniCount; i++) { + const Common::String ani = Util::readString(seq, 13); + + if (!_vm->_dataIO->hasFile(ani)) { + warning("SEQFile::load(): No such animation \"%s\"", ani.c_str()); + return; + } + + _animations.push_back(new ANIFile(_vm, ani)); + } + + _frameRate = seq.readUint16LE(); + + // Load background change keys + + const uint16 bgKeyCount = seq.readUint16LE(); + _bgKeys.resize(bgKeyCount); + + for (uint16 i = 0; i < bgKeyCount; i++) { + const uint16 frame = seq.readUint16LE(); + const uint16 index = seq.readUint16LE(); + + _bgKeys[i].frame = frame; + _bgKeys[i].background = index < _backgrounds.size() ? _backgrounds[index] : 0; + } + + // Load animation keys for all 4 objects + + for (uint i = 0; i < kObjectCount; i++) { + const uint16 animKeyCount = seq.readUint16LE(); + _animKeys.reserve(_animKeys.size() + animKeyCount); + + for (uint16 j = 0; j < animKeyCount; j++) { + _animKeys.push_back(AnimationKey()); + + const uint16 frame = seq.readUint16LE(); + const uint16 index = seq.readUint16LE(); + + uint16 animation; + const ANIFile *ani = findANI(index, animation); + + _animKeys.back().object = i; + _animKeys.back().frame = frame; + _animKeys.back().ani = ani; + _animKeys.back().animation = animation; + _animKeys.back().x = seq.readSint16LE(); + _animKeys.back().y = seq.readSint16LE(); + _animKeys.back().order = seq.readSint16LE(); + } + } + +} + +const ANIFile *SEQFile::findANI(uint16 index, uint16 &animation) { + animation = 0xFFFF; + + // 0xFFFF = remove animation + if (index == 0xFFFF) + return 0; + + for (Animations::const_iterator a = _animations.begin(); a != _animations.end(); ++a) { + if (index < (*a)->getAnimationCount()) { + animation = index; + return *a; + } + + index -= (*a)->getAnimationCount(); + } + + return 0; +} + +void SEQFile::play(bool abortable, uint16 endFrame, uint16 frameRate) { + if (_bgKeys.empty() && _animKeys.empty()) + // Nothing to do + return; + + // Init + + _frame = 0; + _abortPlay = false; + + for (uint i = 0; i < kObjectCount; i++) { + delete _objects[i].object; + + _objects[i].object = 0; + _objects[i].order = 0; + } + + for (Loops::iterator l = _loops.begin(); l != _loops.end(); ++l) + l->currentLoop = 0; + + // Set the frame rate + + int16 frameRateBack = _vm->_util->getFrameRate(); + + if (frameRate == 0) + frameRate = _frameRate; + + _vm->_util->setFrameRate(frameRate); + + _abortable = abortable; + + while (!_vm->shouldQuit() && !_abortPlay) { + // Handle the frame contents + playFrame(); + + // Handle extra frame events + handleFrameEvent(); + + // Wait for the frame to end + _vm->_draw->blitInvalidated(); + _vm->_util->waitEndFrame(); + + // Handle input + + _vm->_util->processInput(); + + int16 key = _vm->_util->checkKey(); + + int16 mouseX, mouseY; + MouseButtons mouseButtons; + _vm->_util->getMouseState(&mouseX, &mouseY, &mouseButtons); + _vm->_util->forceMouseUp(); + + handleInput(key, mouseX, mouseY, mouseButtons); + + // Loop + + bool looped = false; + for (Loops::iterator l = _loops.begin(); l != _loops.end(); ++l) { + if ((l->endFrame == _frame) && (l->currentLoop < l->loopCount)) { + _frame = l->startFrame; + + l->currentLoop++; + looped = true; + } + } + + // If we didn't loop, advance the frame and look if we should end here + + if (!looped) { + _frame++; + if (_frame >= endFrame) + break; + } + } + + // Restore the frame rate + _vm->_util->setFrameRate(frameRateBack); +} + +void SEQFile::playFrame() { + // Remove the current animation frames + clearAnims(); + + // Handle background keys, directly updating the background + for (BackgroundKeys::const_iterator b = _bgKeys.begin(); b != _bgKeys.end(); ++b) { + if (!b->background || (b->frame != _frame)) + continue; + + b->background->draw(*_vm->_draw->_backSurface); + + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, 0, 0, 319, 199); + } + + // Handle the animation keys, updating the objects + for (AnimationKeys::const_iterator a = _animKeys.begin(); a != _animKeys.end(); ++a) { + if (a->frame != _frame) + continue; + + Object &object = _objects[a->object]; + + delete object.object; + object.object = 0; + + // No valid animation => remove + if ((a->animation == 0xFFFF) || !a->ani) + continue; + + // Change the animation + + object.object = new ANIObject(*a->ani); + + object.object->setAnimation(a->animation); + object.object->setPosition(a->x, a->y); + object.object->setVisible(true); + object.object->setPause(false); + + object.order = a->order; + } + + // Draw the animations + drawAnims(); +} + +// NOTE: This is really not at all efficient. However, since there's only a +// small number of objects, it should matter. We really do need a stable +// sort, though, so Common::sort() is out. +SEQFile::Objects SEQFile::getOrderedObjects() { + int16 minOrder = (int16)0x7FFF; + int16 maxOrder = (int16)0x8000; + + Objects objects; + + // Find the span of order values + for (uint i = 0; i < kObjectCount; i++) { + if (!_objects[i].object) + continue; + + minOrder = MIN(minOrder, _objects[i].order); + maxOrder = MAX(maxOrder, _objects[i].order); + } + + // Stably sort the objects by order value + for (int16 o = minOrder; o <= maxOrder; o++) + for (uint i = 0; i < kObjectCount; i++) + if (_objects[i].object && (_objects[i].order == o)) + objects.push_back(_objects[i]); + + return objects; +} + +void SEQFile::clearAnims() { + Objects objects = getOrderedObjects(); + + // Remove the animation frames, in reverse drawing order + for (Objects::iterator o = objects.reverse_begin(); o != objects.end(); --o) { + int16 left, top, right, bottom; + + if (o->object->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + } +} + +void SEQFile::drawAnims() { + Objects objects = getOrderedObjects(); + + // Draw the animation frames and advance the animation + for (Objects::iterator o = objects.begin(); o != objects.end(); ++o) { + int16 left, top, right, bottom; + + if (o->object->draw(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + o->object->advance(); + } +} + +uint16 SEQFile::getFrame() const { + return _frame; +} + +void SEQFile::seekFrame(uint16 frame) { + _frame = frame; +} + +uint SEQFile::addLoop(uint16 startFrame, uint16 endFrame, uint16 loopCount) { + _loops.resize(_loops.size() + 1); + + _loops.back().startFrame = startFrame; + _loops.back().endFrame = endFrame; + _loops.back().loopCount = loopCount; + _loops.back().currentLoop = 0; + _loops.back().empty = false; + + return _loops.size() - 1; +} + +void SEQFile::skipLoop(uint loopID) { + if (loopID >= _loops.size()) + return; + + _loops[loopID].currentLoop = 0xFFFF; +} + +void SEQFile::delLoop(uint loopID) { + if (loopID >= _loops.size()) + return; + + _loops[loopID].empty = true; + + cleanLoops(); +} + +void SEQFile::cleanLoops() { + while (!_loops.empty() && _loops.back().empty) + _loops.pop_back(); +} + +void SEQFile::abortPlay() { + _abortPlay = true; +} + +void SEQFile::handleFrameEvent() { +} + +void SEQFile::handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons) { + if (_abortable && ((key != 0) || (mouseButtons != kMouseButtonsNone))) + abortPlay(); +} + +} // End of namespace Gob diff --git a/engines/gob/pregob/seqfile.h b/engines/gob/pregob/seqfile.h new file mode 100644 index 0000000000..5e12962ef9 --- /dev/null +++ b/engines/gob/pregob/seqfile.h @@ -0,0 +1,193 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_SEQFILE_H +#define GOB_PREGOB_SEQFILE_H + +#include "common/system.h" +#include "common/array.h" +#include "common/list.h" + +#include "gob/util.h" + +namespace Common { + class String; + class SeekableReadStream; +} + +namespace Gob { + +class GobEngine; + +class DECFile; +class ANIFile; +class ANIObject; + +/** A SEQ file, describing a complex animation sequence. + * + * Used in early hardcoded gob games. + * The principle is similar to the Mult class (see mult.h), but instead + * of depending on all the externally loaded animations, backgrounds and + * objects, a SEQ file references animation and background directly by + * filename. + */ +class SEQFile { +public: + SEQFile(GobEngine *vm, const Common::String &fileName); + virtual ~SEQFile(); + + /** Play the SEQ. + * + * @param abortable If true, end playback on any user input. + * @param endFrame The frame on where to end, or 0xFFFF for infinite playback. + * @param frameRate The frame rate at which to play the SEQ, or 0 for playing at + * the speed the SEQ itself wants to. + */ + void play(bool abortable = true, uint16 endFrame = 0xFFFF, uint16 frameRate = 0); + + +protected: + GobEngine *_vm; + + + /** Returns the current frame number. */ + uint16 getFrame() const; + + /** Seek to a specific frame. */ + void seekFrame(uint16 frame); + + /** Add a frame loop. */ + uint addLoop(uint16 startFrame, uint16 endFrame, uint16 loopCount); + + /** Skip a frame loop. */ + void skipLoop(uint loopID); + + /** Delete a frame loop. */ + void delLoop(uint loopID); + + /** Ends SEQ playback. */ + void abortPlay(); + + /** Callback for special frame events. */ + virtual void handleFrameEvent(); + /** Callback for special user input handling. */ + virtual void handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons); + + +private: + /** Number of animation objects that are visible at the same time. */ + static const uint kObjectCount = 4; + + /** A key for changing the background. */ + struct BackgroundKey { + uint16 frame; ///< Frame the change is to happen. + + const DECFile *background; ///< The background to use. + }; + + /** A key for playing an object animation. */ + struct AnimationKey { + uint object; ///< The object this key belongs to. + + uint16 frame; ///< Frame the change is to happen. + + const ANIFile *ani; ///< The ANI to use. + + uint16 animation; ///< The animation to use. + + int16 x; ///< X position of the animation. + int16 y; ///< Y position of the animation. + + int16 order; ///< Used to determine in which order to draw the objects. + }; + + /** A managed animation object. */ + struct Object { + ANIObject *object; ///< The actual animation object. + + int16 order; ///< The current drawing order. + }; + + /** A frame loop. */ + struct Loop { + uint16 startFrame; + uint16 endFrame; + + uint16 loopCount; + uint16 currentLoop; + + bool empty; + }; + + typedef Common::Array Backgrounds; + typedef Common::Array Animations; + + typedef Common::Array BackgroundKeys; + typedef Common::Array AnimationKeys; + + typedef Common::List Objects; + + typedef Common::Array Loops; + + + uint16 _frame; ///< The current frame. + bool _abortPlay; ///< Was the end of the playback requested? + + uint16 _frameRate; + + Backgrounds _backgrounds; ///< All backgrounds in this SEQ. + Animations _animations; ///< All animations in this SEQ. + + BackgroundKeys _bgKeys; ///< The background change keyframes. + AnimationKeys _animKeys; ///< The animation change keyframes. + + Object _objects[kObjectCount]; ///< The managed animation objects. + + Loops _loops; + + /** Whether the playback should be abortable by user input. */ + bool _abortable; + + + // -- Loading helpers -- + + void load(Common::SeekableReadStream &seq); + + const ANIFile *findANI(uint16 index, uint16 &animation); + + // -- Playback helpers -- + + void playFrame(); + + /** Get a list of objects ordered by drawing order. */ + Objects getOrderedObjects(); + + void clearAnims(); ///< Remove all animation frames. + void drawAnims(); ///< Draw the animation frames. + + /** Look if we can compact the loop array. */ + void cleanLoops(); +}; + +} // End of namespace Gob + +#endif // GOB_PREGOB_SEQFILE_H -- cgit v1.2.3 From 850472f21e73280c0bf35c76163419a7e280fea2 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 20:11:06 +0200 Subject: GOB: Implement the proper Once Upon A Time title sequence --- engines/gob/module.mk | 1 + engines/gob/pregob/onceupon/onceupon.cpp | 88 +---------------------- engines/gob/pregob/onceupon/onceupon.h | 10 +-- engines/gob/pregob/onceupon/title.cpp | 117 +++++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/title.h | 55 +++++++++++++++ 5 files changed, 177 insertions(+), 94 deletions(-) create mode 100644 engines/gob/pregob/onceupon/title.cpp create mode 100644 engines/gob/pregob/onceupon/title.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 04e55dcf16..489afe509e 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -85,6 +85,7 @@ MODULE_OBJS := \ pregob/onceupon/onceupon.o \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ + pregob/onceupon/title.o \ pregob/onceupon/stork.o \ pregob/onceupon/chargenchild.o \ minigames/geisha/evilfish.o \ diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 7f59790d1d..6ee391ea7f 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -37,6 +37,7 @@ #include "gob/pregob/onceupon/onceupon.h" #include "gob/pregob/onceupon/palettes.h" +#include "gob/pregob/onceupon/title.h" #include "gob/pregob/onceupon/chargenchild.h" static const uint kLanguageCount = 5; @@ -657,94 +658,11 @@ const PreGob::AnimProperties OnceUpon::kTitleAnimation = { }; void OnceUpon::showTitle() { - // Show the Once Upon A Time title animation - // NOTE: This is currently only a mock-up. The real animation is in "ville.seq". - fadeOut(); setGamePalette(10); - warning("OnceUpon::showTitle(): Actually play the SEQ"); - - clearScreen(); - - _vm->_video->drawPackedSprite("ville.cmp", *_vm->_draw->_backSurface); - _vm->_draw->forceBlit(); - - ANIFile ani (_vm, "pres.ani", 320); - ANIList anims; - - loadAnims(anims, ani, 1, &kTitleAnimation); - - playTitleMusic(); - - while (!_vm->shouldQuit()) { - redrawAnim(anims); - - fadeIn(); - - endFrame(true); - - if (hasInput()) - break; - } - - freeAnims(anims); - - fadeOut(); - stopTitleMusic(); -} - -void OnceUpon::playTitleMusic() { - // Look at what platform this is and play the appropriate music type - - if (_vm->getPlatform() == Common::kPlatformPC) - playTitleMusicDOS(); - else if (_vm->getPlatform() == Common::kPlatformAmiga) - playTitleMusicAmiga(); - else if (_vm->getPlatform() == Common::kPlatformAtariST) - playTitleMusicAtariST(); -} - -void OnceUpon::playTitleMusicDOS() { - // Play an AdLib track - - _vm->_sound->adlibLoadTBR("babayaga.tbr"); - _vm->_sound->adlibLoadMDY("babayaga.mdy"); - _vm->_sound->adlibSetRepeating(-1); - _vm->_sound->adlibPlay(); -} - -void OnceUpon::playTitleMusicAmiga() { - // Play a Protracker track - - _vm->_sound->protrackerPlay("mod.babayaga"); -} - -void OnceUpon::playTitleMusicAtariST() { - // Play a Soundblaster composition - - static const int16 titleMusic[21] = { 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, -1}; - static const char * const titleFiles[ 3] = {"baba1.snd", "baba2.snd", "baba3.snd"}; - - for (uint i = 0; i < ARRAYSIZE(titleFiles); i++) - _vm->_sound->sampleLoad(_vm->_sound->sampleGetBySlot(i), SOUND_SND, titleFiles[i]); - - _vm->_sound->blasterPlayComposition(titleMusic, 0); - _vm->_sound->blasterRepeatComposition(-1); -} - -void OnceUpon::stopTitleMusic() { - // Just stop everything - - _vm->_sound->adlibSetRepeating(0); - _vm->_sound->blasterRepeatComposition(0); - - _vm->_sound->adlibStop(); - _vm->_sound->blasterStopComposition(); - _vm->_sound->protrackerStop(); - - for (int i = 0; i < ::Gob::Sound::kSoundsCount; i++) - _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(i)); + Title title(_vm); + title.play(); } void OnceUpon::showChapter(int chapter) { diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 2f25060a37..41a2f5668d 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -237,15 +237,6 @@ private: void handleAnimalNames(uint count, const MenuButton *buttons, const char * const *names); - // -- Title music helpers -- - - void playTitleMusic(); ///< Play the title music. - void playTitleMusicDOS(); ///< Play the title music of the DOS version. - void playTitleMusicAmiga(); ///< Play the title music of the Amiga version. - void playTitleMusicAtariST(); ///< Play the title music of the Atari ST version. - void stopTitleMusic(); ///< Stop the title music. - - // -- Menu helpers -- MenuAction handleStartMenu(const MenuButton *animalsButton); ///< Handle the start menu. @@ -291,6 +282,7 @@ private: /** Play / Display the name of an animal in one language. */ void anPlayAnimalName(const Common::String &animal, uint language); + // -- Game sections -- bool playSection(); diff --git a/engines/gob/pregob/onceupon/title.cpp b/engines/gob/pregob/onceupon/title.cpp new file mode 100644 index 0000000000..5163ff6822 --- /dev/null +++ b/engines/gob/pregob/onceupon/title.cpp @@ -0,0 +1,117 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/gob.h" +#include "gob/global.h" +#include "gob/palanim.h" +#include "gob/draw.h" + +#include "gob/sound/sound.h" + +#include "gob/pregob/onceupon/title.h" + +namespace Gob { + +namespace OnceUpon { + +Title::Title(GobEngine *vm) : SEQFile(vm, "ville.seq") { +} + +Title::~Title() { +} + +void Title::play() { + SEQFile::play(true, 0xFFFF, 15); + + // After playback, fade out and stop the music + if (!_vm->shouldQuit()) + _vm->_palAnim->fade(0, 0, 0); + + stopMusic(); +} + +void Title::handleFrameEvent() { + // On fame 0, start the music and fade in + if (getFrame() == 0) { + playMusic(); + + _vm->_draw->forceBlit(); + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + } +} + +void Title::playMusic() { + // Look at what platform this is and play the appropriate music type + + if (_vm->getPlatform() == Common::kPlatformPC) + playMusicDOS(); + else if (_vm->getPlatform() == Common::kPlatformAmiga) + playMusicAmiga(); + else if (_vm->getPlatform() == Common::kPlatformAtariST) + playMusicAtariST(); +} + +void Title::playMusicDOS() { + // Play an AdLib track + + _vm->_sound->adlibLoadTBR("babayaga.tbr"); + _vm->_sound->adlibLoadMDY("babayaga.mdy"); + _vm->_sound->adlibSetRepeating(-1); + _vm->_sound->adlibPlay(); +} + +void Title::playMusicAmiga() { + // Play a Protracker track + + _vm->_sound->protrackerPlay("mod.babayaga"); +} + +void Title::playMusicAtariST() { + // Play a Soundblaster composition + + static const int16 titleMusic[21] = { 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, -1}; + static const char * const titleFiles[ 3] = {"baba1.snd", "baba2.snd", "baba3.snd"}; + + for (uint i = 0; i < ARRAYSIZE(titleFiles); i++) + _vm->_sound->sampleLoad(_vm->_sound->sampleGetBySlot(i), SOUND_SND, titleFiles[i]); + + _vm->_sound->blasterPlayComposition(titleMusic, 0); + _vm->_sound->blasterRepeatComposition(-1); +} + +void Title::stopMusic() { + // Just stop everything + + _vm->_sound->adlibSetRepeating(0); + _vm->_sound->blasterRepeatComposition(0); + + _vm->_sound->adlibStop(); + _vm->_sound->blasterStopComposition(); + _vm->_sound->protrackerStop(); + + for (int i = 0; i < ::Gob::Sound::kSoundsCount; i++) + _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(i)); +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/title.h b/engines/gob/pregob/onceupon/title.h new file mode 100644 index 0000000000..5e7ef76d40 --- /dev/null +++ b/engines/gob/pregob/onceupon/title.h @@ -0,0 +1,55 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_TITLE_H +#define GOB_PREGOB_ONCEUPON_TITLE_H + +#include "gob/pregob/seqfile.h" + +namespace Gob { + +namespace OnceUpon { + +/** The Once Upon A Time title animation sequence. */ +class Title : public SEQFile { +public: + Title(GobEngine *vm); + ~Title(); + + void play(); + +protected: + void handleFrameEvent(); + +private: + void playMusic(); ///< Play the title music. + void playMusicDOS(); ///< Play the title music of the DOS version. + void playMusicAmiga(); ///< Play the title music of the Amiga version. + void playMusicAtariST(); ///< Play the title music of the Atari ST version. + void stopMusic(); ///< Stop the title music. +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_TITLE_H -- cgit v1.2.3 From 3189729c972b5da1356497e82e08a21c94c8fbec Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 22:15:40 +0200 Subject: GOB: Don't leak in sampleLoad() when loading fails --- engines/gob/sound/sound.cpp | 11 +++++++---- engines/gob/sound/sound.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index 69a668e5fb..63af6aeef4 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -109,7 +109,7 @@ int Sound::sampleGetNextFreeSlot() const { return -1; } -bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName, bool tryExist) { +bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName) { if (!sndDesc) return false; @@ -117,12 +117,15 @@ bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName, int32 size; byte *data = _vm->_dataIO->getFile(fileName, size); - if (!data) { - warning("Can't open sample file \"%s\"", fileName); + + if (!data || !sndDesc->load(type, data, size)) { + delete data; + + warning("Sound::sampleLoad(): Failed to load sound \"%s\"", fileName); return false; } - return sndDesc->load(type, data, size); + return true; } void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdLib, int index) { diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index 7beffb5dc7..bbc182d172 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -51,7 +51,7 @@ public: const SoundDesc *sampleGetBySlot(int slot) const; int sampleGetNextFreeSlot() const; - bool sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName, bool tryExist = true); + bool sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName); void sampleFree(SoundDesc *sndDesc, bool noteAdLib = false, int index = -1); -- cgit v1.2.3 From 25bc7467b444d78c64300af9786f08842de81313 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 8 Jul 2012 22:25:51 +0200 Subject: GOB: Use Sound::sampleLoad in PreGob --- engines/gob/pregob/pregob.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/pregob.cpp b/engines/gob/pregob/pregob.cpp index 42b5a8fb9c..54eb3c6795 100644 --- a/engines/gob/pregob/pregob.cpp +++ b/engines/gob/pregob/pregob.cpp @@ -161,17 +161,7 @@ void PreGob::freeSounds() { } bool PreGob::loadSound(SoundDesc &sound, const Common::String &file) const { - int32 size; - byte *data = _vm->_dataIO->getFile(file, size); - - if (!data || !sound.load(SOUND_SND, data, size)) { - delete data; - - warning("PreGob::loadSound(): Failed to load sound \"%s\"", file.c_str()); - return false; - } - - return true; + return _vm->_sound->sampleLoad(&sound, SOUND_SND, file.c_str()); } void PreGob::playSound(uint sound, int16 frequency, int16 repCount) { -- cgit v1.2.3 From dd2768a2e47dd54f055cf65b2212ee9dca395c18 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 15 Jul 2012 17:06:56 +0200 Subject: GOB: Reorder a few things --- engines/gob/pregob/onceupon/onceupon.cpp | 8 ++--- engines/gob/pregob/onceupon/onceupon.h | 60 ++++++++++++++++---------------- engines/gob/pregob/onceupon/stork.h | 12 +++---- engines/gob/pregob/pregob.h | 13 +++---- 4 files changed, 47 insertions(+), 46 deletions(-) (limited to 'engines/gob') diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 6ee391ea7f..9d32eaa356 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -135,7 +135,7 @@ const OnceUpon::MenuButton OnceUpon::kLanguageButtons[] = { {true, 234, 138, 284, 173, 265, 55, 315, 90, 234, 138, 2} }; -const char *OnceUpon::kSound[kSoundMAX] = { +const char *OnceUpon::kSound[kSoundCount] = { "diamant.snd", // kSoundClick "cigogne.snd", // kSoundStork "saute.snd" // kSoundJump @@ -216,7 +216,7 @@ void OnceUpon::init() { // Load all our sounds and init the screen - loadSounds(kSound, kSoundMAX); + loadSounds(kSound, kSoundCount); initScreen(); // We start with an invalid palette @@ -226,7 +226,7 @@ void OnceUpon::init() { _quit = false; // We start with no selected difficulty and at section 0 - _difficulty = kDifficultyMAX; + _difficulty = kDifficultyCount; _section = 0; // Default name @@ -926,7 +926,7 @@ void OnceUpon::drawIngameMenu() { } void OnceUpon::drawMenuDifficulty() { - if (_difficulty == kDifficultyMAX) + if (_difficulty == kDifficultyCount) return; TXTFile *difficulties = loadTXT(getLocFile("diffic.tx"), TXTFile::kFormatStringPositionColor); diff --git a/engines/gob/pregob/onceupon/onceupon.h b/engines/gob/pregob/onceupon/onceupon.h index 41a2f5668d..66ef877618 100644 --- a/engines/gob/pregob/onceupon/onceupon.h +++ b/engines/gob/pregob/onceupon/onceupon.h @@ -129,7 +129,7 @@ private: kDifficultyBeginner = 0, kDifficultyIntermediate = 1, kDifficultyAdvanced = 2, - kDifficultyMAX + kDifficultyCount }; /** The different sounds common in the game. */ @@ -137,7 +137,7 @@ private: kSoundClick = 0, kSoundStork , kSoundJump , - kSoundMAX + kSoundCount }; /** Action the character generation wants us to take. */ @@ -181,7 +181,7 @@ private: static const MenuButton kCharGenNameEntry[]; /** All general game sounds we know about. */ - static const char *kSound[kSoundMAX]; + static const char *kSound[kSoundCount]; static const AnimProperties kClownAnimations[]; @@ -196,6 +196,33 @@ private: static const SectionFunc kSectionFuncs[kSectionCount]; + /** Did we open the game archives? */ + bool _openedArchives; + + // Fonts + Font *_jeudak; + Font *_lettre; + Font *_plettre; + Font *_glettre; + + /** The current palette. */ + int _palette; + + bool _quit; ///< Did the user request a normal game quit? + + Difficulty _difficulty; ///< The current difficulty. + int _section; ///< The current game section. + + Common::String _name; ///< The name of the child. + + uint8 _house; + + uint8 _head; + uint8 _colorHair; + uint8 _colorJacket; + uint8 _colorTrousers; + + // -- General helpers -- void setGamePalette(uint palette); ///< Set a game palette. @@ -308,33 +335,6 @@ private: void charGenDrawName(); static bool enterString(Common::String &name, int16 key, uint maxLength, const Font &font); - - - /** Did we open the game archives? */ - bool _openedArchives; - - // Fonts - Font *_jeudak; - Font *_lettre; - Font *_plettre; - Font *_glettre; - - /** The current palette. */ - int _palette; - - bool _quit; ///< Did the user request a normal game quit? - - Difficulty _difficulty; ///< The current difficulty. - int _section; ///< The current game section. - - Common::String _name; ///< The name of the child. - - uint8 _house; - - uint8 _head; - uint8 _colorHair; - uint8 _colorJacket; - uint8 _colorTrousers; }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/onceupon/stork.h b/engines/gob/pregob/onceupon/stork.h index d26a887c97..756f5258c7 100644 --- a/engines/gob/pregob/onceupon/stork.h +++ b/engines/gob/pregob/onceupon/stork.h @@ -79,12 +79,6 @@ private: }; - void setState(State state, uint16 anim); - void setState(State state, uint16 anim, int16 x); - - void dropBundle(State state, uint16 anim); - - GobEngine *_vm; Surface *_frame; @@ -94,6 +88,12 @@ private: bool _shouldDrop; BundleDrop _bundleDrop; + + + void setState(State state, uint16 anim); + void setState(State state, uint16 anim, int16 x); + + void dropBundle(State state, uint16 anim); }; } // End of namespace OnceUpon diff --git a/engines/gob/pregob/pregob.h b/engines/gob/pregob/pregob.h index da0de60dd8..632f85b88e 100644 --- a/engines/gob/pregob/pregob.h +++ b/engines/gob/pregob/pregob.h @@ -68,6 +68,9 @@ protected: static const char *kLanguageSuffixLong [5]; + GobEngine *_vm; + + // -- Graphics -- /** Initialize the game screen. */ @@ -174,18 +177,16 @@ protected: GCTFile *loadGCT(const Common::String &gctFile) const; - GobEngine *_vm; - private: - /** Load a sound file. */ - bool loadSound(SoundDesc &sound, const Common::String &file) const; - - /** Did we fade out? */ bool _fadedOut; /** All loaded sounds. */ Common::Array _sounds; + + + /** Load a sound file. */ + bool loadSound(SoundDesc &sound, const Common::String &file) const; }; } // End of namespace Gob -- cgit v1.2.3 From b001168658f57b845bae81df0ca85240c796e74e Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 15 Jul 2012 21:12:34 +0200 Subject: GOB: Implement the parents section in Once Upon A Time The text lines are not drawn completely correct yet, because apparently, GCTFile needs to wrap long lines. --- engines/gob/module.mk | 1 + engines/gob/pregob/onceupon/abracadabra.cpp | 8 +- engines/gob/pregob/onceupon/babayaga.cpp | 8 +- engines/gob/pregob/onceupon/onceupon.cpp | 13 +- engines/gob/pregob/onceupon/parents.cpp | 217 ++++++++++++++++++++++++++++ engines/gob/pregob/onceupon/parents.h | 94 ++++++++++++ 6 files changed, 332 insertions(+), 9 deletions(-) create mode 100644 engines/gob/pregob/onceupon/parents.cpp create mode 100644 engines/gob/pregob/onceupon/parents.h (limited to 'engines/gob') diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 489afe509e..d5ee6478be 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -86,6 +86,7 @@ MODULE_OBJS := \ pregob/onceupon/abracadabra.o \ pregob/onceupon/babayaga.o \ pregob/onceupon/title.o \ + pregob/onceupon/parents.o \ pregob/onceupon/stork.o \ pregob/onceupon/chargenchild.o \ minigames/geisha/evilfish.o \ diff --git a/engines/gob/pregob/onceupon/abracadabra.cpp b/engines/gob/pregob/onceupon/abracadabra.cpp index 0d644d9056..2cf6855ef8 100644 --- a/engines/gob/pregob/onceupon/abracadabra.cpp +++ b/engines/gob/pregob/onceupon/abracadabra.cpp @@ -80,10 +80,10 @@ const char *Abracadabra::kAnimalNames[] = { // The houses where the stork can drop a bundle const OnceUpon::MenuButton Abracadabra::kStorkHouses[] = { - {false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, - {false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, - {false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, - {false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} + {false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, // Castle , Lord & Lady + {false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, // Cottage, Farmers + {false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, // Hut , Woodcutters + {false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} // Palace , King & Queen }; // The stork bundle drop parameters diff --git a/engines/gob/pregob/onceupon/babayaga.cpp b/engines/gob/pregob/onceupon/babayaga.cpp index 6aa60310b5..ef56b9dd0b 100644 --- a/engines/gob/pregob/onceupon/babayaga.cpp +++ b/engines/gob/pregob/onceupon/babayaga.cpp @@ -80,10 +80,10 @@ const char *BabaYaga::kAnimalNames[] = { // The houses where the stork can drop a bundle const OnceUpon::MenuButton BabaYaga::kStorkHouses[] = { - {false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, - {false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, - {false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, - {false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} + {false, 16, 80, 87, 125, 0, 0, 0, 0, 0, 0, 0}, // Castle , Lord & Lady + {false, 61, 123, 96, 149, 0, 0, 0, 0, 0, 0, 1}, // Cottage, Farmers + {false, 199, 118, 226, 137, 0, 0, 0, 0, 0, 0, 2}, // Hut , Woodcutters + {false, 229, 91, 304, 188, 0, 0, 0, 0, 0, 0, 3} // Palace , King & Queen }; // The stork bundle drop parameters diff --git a/engines/gob/pregob/onceupon/onceupon.cpp b/engines/gob/pregob/onceupon/onceupon.cpp index 9d32eaa356..e4c2df34c0 100644 --- a/engines/gob/pregob/onceupon/onceupon.cpp +++ b/engines/gob/pregob/onceupon/onceupon.cpp @@ -38,6 +38,7 @@ #include "gob/pregob/onceupon/onceupon.h" #include "gob/pregob/onceupon/palettes.h" #include "gob/pregob/onceupon/title.h" +#include "gob/pregob/onceupon/parents.h" #include "gob/pregob/onceupon/chargenchild.h" static const uint kLanguageCount = 5; @@ -1747,7 +1748,17 @@ bool OnceUpon::sectionChapter1() { } bool OnceUpon::sectionParents() { - warning("OnceUpon::sectionParents(): TODO"); + fadeOut(); + setGamePalette(14); + clearScreen(); + + const Common::String seq = ((_house == 1) || (_house == 2)) ? "parents.seq" : "parents2.seq"; + const Common::String gct = getLocFile("mefait.gc"); + + Parents parents(_vm, seq, gct, _name, _house, *_plettre, kGamePalettes[14], kGamePalettes[13], kPaletteSize); + parents.play(); + + warning("OnceUpon::sectionParents(): TODO: Item search"); return true; } diff --git a/engines/gob/pregob/onceupon/parents.cpp b/engines/gob/pregob/onceupon/parents.cpp new file mode 100644 index 0000000000..cdaee6a38d --- /dev/null +++ b/engines/gob/pregob/onceupon/parents.cpp @@ -0,0 +1,217 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gob/gob.h" +#include "gob/global.h" +#include "gob/dataio.h" +#include "gob/palanim.h" +#include "gob/draw.h" +#include "gob/video.h" + +#include "gob/sound/sound.h" + +#include "gob/pregob/gctfile.h" + +#include "gob/pregob/onceupon/palettes.h" +#include "gob/pregob/onceupon/parents.h" + +namespace Gob { + +namespace OnceUpon { + +const char *Parents::kSound[kSoundCount] = { + "rire.snd", // kSoundCackle + "tonn.snd" // kSoundThunder +}; + +// So that every GCT line is displayed for 12 seconds +const uint16 Parents::kLoop[kLoopCount][3] = { + { 72, 77, 33}, + {105, 109, 38}, + {141, 145, 38}, + {446, 454, 23}, + {456, 464, 23}, + {466, 474, 23}, + {476, 484, 23} +}; + + +Parents::Parents(GobEngine *vm, const Common::String &seq, const Common::String &gct, + const Common::String &childName, uint8 house, const Font &font, + const byte *normalPalette, const byte *brightPalette, uint paletteSize) : + SEQFile(vm, seq), + _gct(0), _house(house), _font(&font), + _paletteSize(paletteSize), _normalPalette(normalPalette), _brightPalette(brightPalette) { + + // Load sounds + for (int i = 0; i < kSoundCount; i++) + _vm->_sound->sampleLoad(&_sounds[i], SOUND_SND, kSound[i]); + + // Load GCT + Common::SeekableReadStream *gctStream = _vm->_dataIO->getFile(gct); + if (gctStream) { + _gct = new GCTFile(*gctStream, _vm->_rnd); + + delete gctStream; + } else + error("Parents::Parents(): Failed to open \"%s\"", gct.c_str()); + + _gct->setArea(17, 18, 303, 41); + _gct->setText(1, childName); + + _gct->selectLine(2, _house); + _gct->selectLine(4, _house); + + for (uint i = 0; i < kLoopCount; i++) + _loopID[i] = addLoop(kLoop[i][0], kLoop[i][1], kLoop[i][2]); +} + +Parents::~Parents() { + delete _gct; +} + +void Parents::play() { + _currentLoop = 0; + + SEQFile::play(true, 496, 15); + + // After playback, fade out + if (!_vm->shouldQuit()) + _vm->_palAnim->fade(0, 0, 0); +} + +void Parents::handleFrameEvent() { + switch (getFrame()) { + case 0: + // On fame 0, fade in + _vm->_draw->forceBlit(); + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, 0, 0); + break; + + case 4: + drawGCT(0); + break; + + case 55: + drawGCT(3, 0); + break; + + case 79: + drawGCT(_house + 5, 1); + break; + + case 110: + drawGCT(_house + 9, 2); + break; + + case 146: + drawGCT(17); + break; + + case 198: + drawGCT(13); + break; + + case 445: + drawGCT(14, 3); + break; + + case 455: + drawGCT(18, 4); + break; + + case 465: + drawGCT(19, 5); + break; + + case 475: + drawGCT(20, 6); + break; + + case 188: + case 228: + case 237: + case 257: + case 275: + case 426: + lightningEffect(); + break; + + case 203: + case 243: + case 252: + case 272: + case 290: + case 441: + playSound(kSoundThunder); + break; + + case 340: + playSound(kSoundCackle); + break; + } +} + +void Parents::handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons) { + if ((key == kKeyEscape) || (mouseButtons == kMouseButtonsRight)) + abortPlay(); + + if (((key == kKeySpace) || (mouseButtons == kMouseButtonsLeft)) && (_currentLoop < kLoopCount)) + skipLoop(_loopID[_currentLoop]); +} + +void Parents::playSound(Sound sound) { + _vm->_sound->blasterStop(0); + _vm->_sound->blasterPlay(&_sounds[sound], 0, 0); +} + +void Parents::lightningEffect() { + for (int i = 0; (i < 5) && !_vm->shouldQuit(); i++) { + + setPalette(_brightPalette, _paletteSize); + _vm->_util->delay(5); + + setPalette(_normalPalette, _paletteSize); + _vm->_util->delay(5); + } +} + +void Parents::setPalette(const byte *palette, uint size) { + memcpy(_vm->_draw->_vgaPalette, palette, 3 * size); + + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + _vm->_video->retrace(); +} + +void Parents::drawGCT(uint item, uint loop) { + int16 left, top, right, bottom; + if (_gct->clear(*_vm->_draw->_backSurface, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + if (_gct->draw(*_vm->_draw->_backSurface, item, *_font, 10, left, top, right, bottom)) + _vm->_draw->dirtiedRect(_vm->_draw->_backSurface, left, top, right, bottom); + + _currentLoop = loop; +} + +} // End of namespace OnceUpon + +} // End of namespace Gob diff --git a/engines/gob/pregob/onceupon/parents.h b/engines/gob/pregob/onceupon/parents.h new file mode 100644 index 0000000000..f5c8307b73 --- /dev/null +++ b/engines/gob/pregob/onceupon/parents.h @@ -0,0 +1,94 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GOB_PREGOB_ONCEUPON_PARENTS_H +#define GOB_PREGOB_ONCEUPON_PARENTS_H + +#include "gob/sound/sounddesc.h" + +#include "gob/pregob/seqfile.h" + +namespace Gob { + +class Font; + +class GCTFile; + +namespace OnceUpon { + +/** The home / parents animation sequence. */ +class Parents : public SEQFile { +public: + Parents(GobEngine *vm, const Common::String &seq, const Common::String &gct, + const Common::String &childName, uint8 house, const Font &font, + const byte *normalPalette, const byte *brightPalette, uint paletteSize); + ~Parents(); + + void play(); + +protected: + void handleFrameEvent(); + void handleInput(int16 key, int16 mouseX, int16 mouseY, MouseButtons mouseButtons); + +private: + static const uint kLoopCount = 7; + + static const uint16 kLoop[kLoopCount][3]; + + enum Sound { + kSoundCackle = 0, + kSoundThunder , + kSoundCount + }; + + static const char *kSound[kSoundCount]; + + + uint8 _house; + + const Font *_font; + + uint _paletteSize; + const byte *_normalPalette; + const byte *_brightPalette; + + SoundDesc _sounds[kSoundCount]; + + GCTFile *_gct; + + uint _loopID[kLoopCount]; + uint _currentLoop; + + + void lightningEffect(); + + void playSound(Sound sound); + void setPalette(const byte *palette, uint size); + + void drawGCT(uint item, uint loop = 0xFFFF); +}; + +} // End of namespace OnceUpon + +} // End of namespace Gob + +#endif // GOB_PREGOB_ONCEUPON_PARENTS_H -- cgit v1.2.3 From ef8e15255d2415add42d4463e1672ea215f4ab80 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 5 Aug 2012 10:43:41 +0200 Subject: GOB: Add a Spanish/Italian DOS version of Geisha As supplied by einstein95 in bug report #3544449. --- engines/gob/detection/tables_geisha.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'engines/gob') diff --git a/engines/gob/detection/tables_geisha.h b/engines/gob/detection/tables_geisha.h index d05659d9e5..a32d1ebf81 100644 --- a/engines/gob/detection/tables_geisha.h +++ b/engines/gob/detection/tables_geisha.h @@ -69,6 +69,34 @@ kFeaturesEGA | kFeaturesAdLib, "disk1.stk", "intro.tot", 0 }, +{ // Supplied by einstein95 in bug report #3544449 + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "49107ac897e7c00af6c4ecd78a74a710", 212169), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA | kFeaturesAdLib, + "disk1.stk", "intro.tot", 0 +}, +{ // Supplied by einstein95 in bug report #3544449 + { + "geisha", + "", + AD_ENTRY1s("disk1.stk", "49107ac897e7c00af6c4ecd78a74a710", 212169), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO2(GUIO_NOSUBTITLES, GUIO_NOSPEECH) + }, + kGameTypeGeisha, + kFeaturesEGA | kFeaturesAdLib, + "disk1.stk", "intro.tot", 0 +}, { { "geisha", -- cgit v1.2.3