diff options
author | Arnaud Boutonné | 2009-09-29 22:43:30 +0000 |
---|---|---|
committer | Arnaud Boutonné | 2009-09-29 22:43:30 +0000 |
commit | ff70b554eace73fafb0165fb0dc16da91f377ce4 (patch) | |
tree | 0bbbb0bc899e7b5f07433f681c556690faf94769 /engines/gob | |
parent | c85736913140a8c65aed7060a4ae2cc4a64bee70 (diff) | |
download | scummvm-rg350-ff70b554eace73fafb0165fb0dc16da91f377ce4.tar.gz scummvm-rg350-ff70b554eace73fafb0165fb0dc16da91f377ce4.tar.bz2 scummvm-rg350-ff70b554eace73fafb0165fb0dc16da91f377ce4.zip |
Playtoons - implement some functions related to hotspot texts
Fascination - initial version of several 'Fascination Window' functions, proper naming of most of fascination OPCODEDRAW and OPCODEGOB functions
svn-id: r44472
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/dataio.cpp | 2 | ||||
-rw-r--r-- | engines/gob/draw.cpp | 752 | ||||
-rw-r--r-- | engines/gob/draw.h | 49 | ||||
-rw-r--r-- | engines/gob/draw_fascin.cpp | 227 | ||||
-rw-r--r-- | engines/gob/global.cpp | 2 | ||||
-rw-r--r-- | engines/gob/global.h | 2 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 2 | ||||
-rw-r--r-- | engines/gob/hotspots.cpp | 123 | ||||
-rw-r--r-- | engines/gob/hotspots.h | 2 | ||||
-rw-r--r-- | engines/gob/init.cpp | 5 | ||||
-rw-r--r-- | engines/gob/init.h | 7 | ||||
-rw-r--r-- | engines/gob/inter.h | 34 | ||||
-rw-r--r-- | engines/gob/inter_fascin.cpp | 136 | ||||
-rw-r--r-- | engines/gob/inter_playtoons.cpp | 1 | ||||
-rw-r--r-- | engines/gob/inter_v3.cpp | 5 |
15 files changed, 1193 insertions, 156 deletions
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index ec4818837d..675046ff64 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -363,7 +363,7 @@ uint32 DataIO::getChunkPos(int16 handle) const { int32 DataIO::getChunkSize(const char *chunkName, int32 &packSize) { packSize = -1; - for (int16 file = 0; file < MAX_DATA_FILES; file++) { + for (int file = 0; file < MAX_DATA_FILES; file++) { if (_dataFiles[file] == 0) return -1; diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 38d82e0825..6a7f53a91e 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -31,6 +31,7 @@ #include "gob/util.h" #include "gob/dataio.h" #include "gob/game.h" +#include "gob/resources.h" #include "gob/script.h" #include "gob/inter.h" #include "gob/video.h" @@ -57,6 +58,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _letterToPrint = 0; _textToPrint = 0; + _hotspotText = 0; _backDeltaX = 0; _backDeltaY = 0; @@ -435,6 +437,756 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, spriteOperation(DRAW_PRINTTEXT); } +void Draw::oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 fontIndex, int16 var4, int16 shortId) { + int16 i, j, width; + char tmpStr[128]; + + strcpy( tmpStr, paramStr); + adjustCoords(1, &left, &top); + adjustCoords(1, &right, &bottom); + + uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter); + if (centerOffset != 0) { + _vm->_game->_script->call(centerOffset); + + WRITE_VAR(17, (uint32) id & 0x7FFF); + WRITE_VAR(18, (uint32) left); + WRITE_VAR(19, (uint32) top); + WRITE_VAR(20, (uint32) (right - left + 1)); + WRITE_VAR(21, (uint32) (bottom - top + 1)); + + if (_vm->_game->_script->peekUint16(41) >= '4') { + WRITE_VAR(22, (uint32) fontIndex); + WRITE_VAR(23, (uint32) var4); + if (id & 0x8000) + WRITE_VAR(24, (uint32) 1); + else + WRITE_VAR(24, (uint32) 0); + WRITE_VAR(25, (uint32) shortId); + if (_hotspotText) { + strncpy(_hotspotText, paramStr, 40); + _hotspotText[39] = 0; + } + } + _vm->_inter->funcBlock(0); + _vm->_game->_script->pop(); + } + strcpy(paramStr, tmpStr); + if (*paramStr) { + _transparency = 1; + _fontIndex = fontIndex; + _frontColor = var4; + if (_vm->_game->_script->peekUint16(41) >= '4' && strchr(paramStr, 92)) { + char str[80]; + char *str2; + int16 strLen= 0; + int16 offY, deltaY; + + str2 = paramStr; + do { + strLen++; + str2++; + str2 = strchr(str2, 92); + } while (str2); + deltaY = (bottom - right + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1); + offY = right + deltaY; + for (i = 0; paramStr[i]; i++) { + j = 0; + while (paramStr[i] && paramStr[i] != 92) + str[j++] = paramStr[i++]; + str[j] = 0; + _destSpriteX = left; + _destSpriteY = offY; + _textToPrint = str; + width = stringLength(str, fontIndex); + adjustCoords(1, &width, NULL); + _destSpriteX += (top - left + 1 - width) / 2; + spriteOperation(DRAW_PRINTTEXT); + offY += deltaY + _fonts[fontIndex]->getCharHeight(); + } + } else { + _destSpriteX = left; + if (_vm->_game->_script->peekUint16(41) >= '4') + _destSpriteY = right + (bottom - right + 1 - _fonts[fontIndex]->getCharHeight()) / 2; + else + _destSpriteY = right; + _textToPrint = paramStr; + width = stringLength(paramStr, fontIndex); + adjustCoords(1, &width, NULL); + _destSpriteX += (top - left + 1 - width) / 2; + spriteOperation(DRAW_PRINTTEXT); + } + } + return; +} + +void Draw::activeWin (int16 id) { + int i, j; + bool found = false; + int16 t[10], t2[10]; + int nextId = -1; + int oldId = -1; + SurfaceDescPtr tempSrf; + SurfaceDescPtr oldSrf[10]; + + warning ("activeWindow %d", id); + + if (_fascinWin[id].id == -1) + return; + warning("swap screen ?"); + forceBlit(); + _vm->_video->dirtyRectsAll(); + for (i = 0; i < 10; i++) { + t[i] = -1; + t2[i] = -1; +// oldSrf[i] = 0; + } + for (i = 0; i < 10; i++) + if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id) && (winOverlap(i, id))) { + t[_fascinWin[i].id] = i; + found = true; + } + if (found) { + for (j = 10 - 1; j >= 0; j--) + if (t[j] != -1) { + if (nextId != -1) + _vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[nextId].savedSurface, + _fascinWin[t[j]].left, _fascinWin[t[j]].top, + _fascinWin[t[j]].left + _fascinWin[t[j]].width - 1, + _fascinWin[t[j]].top + _fascinWin[t[j]].height - 1, + _fascinWin[t[j]].left & 15, 0, 0); + t2[j] = nextId; + restoreWin(t[j]); + nextId = t[j]; + } + oldId = nextId; + _vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[nextId].savedSurface, + _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1, + _fascinWin[id].left & 15, 0, 0); + restoreWin(id); + nextId = id; + for (j = 0; j < 10; j++) + if (t[j] != -1) { + _vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[nextId].savedSurface, + _fascinWin[t[j]].left, _fascinWin[t[j]].top, + _fascinWin[t[j]].left + _fascinWin[t[j]].width - 1, + _fascinWin[t[j]].top + _fascinWin[t[j]].height - 1, + _fascinWin[t[j]].left & 15, 0, 0); + oldSrf[t[j]] = _fascinWin[nextId].savedSurface; + if (t2[j] != -1) + _vm->_video->drawSprite(*_fascinWin[t2[j]].savedSurface, *_spritesArray[_destSurface], + _fascinWin[t[j]].left & 15, 0, + (_fascinWin[t[j]].left & 15) + _fascinWin[t[j]].width - 1, + _fascinWin[t[j]].height - 1, _fascinWin[t[j]].left, + _fascinWin[t[j]].top, 0); + else { +// Strangerke not sure concerning the use of _sourceSurface +// Shift skipped as always set to zero (?) + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface], + _fascinWin[t[j]].left, _fascinWin[t[j]].top, + _fascinWin[t[j]].left + _fascinWin[t[j]].width - 1, + _fascinWin[t[j]].top + _fascinWin[t[j]].height - 1, + _fascinWin[t[j]].left, _fascinWin[t[j]].top, 0); + } +// Strangerke not sure concerning the use of _sourceSurface + dirtiedRect(_sourceSurface, _fascinWin[t[j]].left, _fascinWin[t[j]].top, + _fascinWin[t[j]].left + _fascinWin[t[j]].width - 1, + _fascinWin[t[j]].top + _fascinWin[t[j]].height - 1); + nextId = t2[j]; + } + tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 15, _winMaxHeight, 0); + _vm->_video->drawSprite(*_spritesArray[_destSurface], *tempSrf, + _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1, + _fascinWin[id].left & 15, 0, 0); + _vm->_video->drawSprite(*_fascinWin[oldId].savedSurface, *_spritesArray[_destSurface], + _fascinWin[id].left & 15, 0, + (_fascinWin[id].left & 15) + _fascinWin[id].width - 1, + _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top, 0); + _fascinWin[oldId].savedSurface.reset(); + _fascinWin[oldId].savedSurface = tempSrf; + oldSrf[id] = _fascinWin[oldId].savedSurface; +// Strangerke not sure concerning the use of _destSurface + dirtiedRect(_destSurface, _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1); + nextId = id; + for (j = 0; j < 10; j++) + if (oldSrf[j]) + _fascinWin[j].savedSurface = oldSrf[j]; + } + for (i = 0; i < 10; i++) + if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id)) + _fascinWin[i].id--; + _fascinWin[id].id = _winCount - 1; +} + +bool Draw::winOverlap(int16 idWin1, int16 idWin2) { + if ((_fascinWin[idWin1].left + _fascinWin[idWin1].width <= _fascinWin[idWin2].left) || + (_fascinWin[idWin2].left + _fascinWin[idWin2].width <= _fascinWin[idWin1].left) || + (_fascinWin[idWin1].top + _fascinWin[idWin1].height <= _fascinWin[idWin2].top ) || + (_fascinWin[idWin2].top + _fascinWin[idWin2].height <= _fascinWin[idWin1].top )) + return(false); + return(true); +} + +void Draw::closeWin (int16 i) { + warning("closeWin %d", i); + if (_fascinWin[i].id == -1) + return; + WRITE_VAR((_winVarArrayStatus / 4) + i, VAR((_winVarArrayStatus / 4) + i) | 1); + restoreWin(i); + _fascinWin[i].id = -1; + _fascinWin[i].savedSurface.reset(); + _winCount--; +} + +int16 Draw::openWin(int16 id) { + if (_fascinWin[id].id != -1) + return(0); + _fascinWin[id].id = _winCount; + _winCount++; + _fascinWin[id].left = VAR((_winVarArrayLeft / 4) + id); + _fascinWin[id].top = VAR((_winVarArrayTop / 4) + id); + _fascinWin[id].width = VAR((_winVarArrayWidth / 4) + id); + _fascinWin[id].height = VAR((_winVarArrayHeight / 4) + id); + _fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 15, _winMaxHeight, 0); + + warning("Draw::openWin id %d- left %d top %d l %d h%d", id, _fascinWin[id].left, _fascinWin[id].top, _fascinWin[id].width, _fascinWin[id].height); + + saveWin(id); + WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) & 0xFFFFFFFE); + return(1); +} + +void Draw::restoreWin(int16 i) { + warning("restoreWin"); + _vm->_video->drawSprite(*_fascinWin[i].savedSurface, *_spritesArray[_destSurface], + _fascinWin[i].left & 15, 0, + (_fascinWin[i].left & 15) + _fascinWin[i].width - 1, _fascinWin[i].height - 1, + _fascinWin[i].left, _fascinWin[i].top, 0); + dirtiedRect(_fascinWin[i].savedSurface, _fascinWin[i].left, _fascinWin[i].top, + _fascinWin[i].left + _fascinWin[i].width - 1, + _fascinWin[i].top + _fascinWin[i].height - 1); +} + +void Draw::saveWin(int16 id) { + warning("saveWin"); + _vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[id].savedSurface, + _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1, + _fascinWin[id].left & 15, 0, 0); + dirtiedRect(_destSurface, _fascinWin[id].left, 0, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1); +} + +void Draw::winMove(int16 id) { + int oldLeft, oldTop; + + oldLeft = _fascinWin[id].left; + oldTop = _fascinWin[id].top; + restoreWin(id); + + _fascinWin[id].left = _vm->_global->_inter_mouseX; + _fascinWin[id].top = _vm->_global->_inter_mouseY; + WRITE_VAR((_winVarArrayLeft / 4) + id, _fascinWin[id].left); + WRITE_VAR((_winVarArrayTop / 4) + id, _fascinWin[id].top); + saveWin(id); + +// Shift skipped as always set to zero (?) + _vm->_video->drawSprite(*_frontSurface, *_spritesArray[_destSurface], + oldLeft, oldTop, + oldLeft + _fascinWin[id].width - 1, + oldTop + _fascinWin[id].height - 1, + _fascinWin[id].left, _fascinWin[id].top, 0); + dirtiedRect(_frontSurface, _fascinWin[id].left, _fascinWin[id].top, + _fascinWin[id].left + _fascinWin[id].width - 1, + _fascinWin[id].top + _fascinWin[id].height - 1); +} + +void Draw::winTrace(int16 left, int16 top, int16 width, int16 height) { +// TODO : Implement correct the trace of the Window. In short, +// - drawline currently use the wrong surface, to be fixed +// - dirtiedRect should be put after the 4 drawlines when the surface is fixed +// - drawline should be replaced by a drawline with palette inversion + + int16 right, bottom; + + right = left + width - 1; + bottom = top + height - 1; + + _vm->_video->drawLine(*_backSurface, left, top, right, top, 0); + _vm->_video->drawLine(*_backSurface, left, top, left, bottom, 0); + _vm->_video->drawLine(*_backSurface, left, bottom, right, bottom, 0); + _vm->_video->drawLine(*_backSurface, right, top, right, bottom, 0); +} + +void Draw::handleWinBorder(int16 id) { + int16 minX = 0; + int16 maxX = 320; + int16 minY = 0; + int16 maxY = 200; + warning("handleWinBorder"); + + if (VAR((_winVarArrayStatus / 4) + id) & 8) + minX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) >> 16L); + if (VAR((_winVarArrayStatus / 4) + id) & 16) + maxX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) & 0xFFFFL); + if (VAR((_winVarArrayStatus / 4) + id) & 32) + minY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) >> 16L); + if (VAR((_winVarArrayStatus / 4) + id) & 64) + maxY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) & 0xFFFFL); + _vm->_global->_inter_mouseX = _fascinWin[id].left; + _vm->_global->_inter_mouseY = _fascinWin[id].top; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + winTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height); + _cursorX = _vm->_global->_inter_mouseX; + _cursorY = _vm->_global->_inter_mouseY; + + do { +// TODO: Usage of checkKeys to be confirmed. A simple refresh of the mouse buttons is required + _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 1); + if (_vm->_global->_inter_mouseX != _cursorX || _vm->_global->_inter_mouseY != _cursorY) { + if (_vm->_global->_inter_mouseX < minX) { + _vm->_global->_inter_mouseX = minX; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + if (_vm->_global->_inter_mouseY < minY) { + _vm->_global->_inter_mouseY = minY; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + if (_vm->_global->_inter_mouseX + _fascinWin[id].width > maxX) { + _vm->_global->_inter_mouseX = maxX - _fascinWin[id].width; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + if (_vm->_global->_inter_mouseY + _fascinWin[id].height > maxY) { + _vm->_global->_inter_mouseY = maxY - _fascinWin[id].height; + if (_vm->_global->_mousePresent) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + } + winTrace(_cursorX,_cursorY, _fascinWin[id].width, _fascinWin[id].height); + winTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height); + _cursorX = _vm->_global->_inter_mouseX; + _cursorY = _vm->_global->_inter_mouseY; + } + } while (_vm->_game->_mouseButtons); + winTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height); + _cursorX = _vm->_global->_inter_mouseX; + _cursorY = _vm->_global->_inter_mouseY; +} + +int16 Draw::handleCurWin() { + int8 i, matchNum; + int16 bestMatch = -1; + + warning("handleCurWin"); + if (_vm->_game->_mouseButtons != 1 || ((_vm->_draw->_renderFlags & 128) == 0)) + return(0); + for (i = 0; i < 10; i++) + if (_fascinWin[i].id != -1) + if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) && + (_vm->_global->_inter_mouseX < _fascinWin[i].left + _fascinWin[i].width) && + (_vm->_global->_inter_mouseY >= _fascinWin[i].top) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + _fascinWin[i].height)) { + if (_fascinWin[i].id == _winCount - 1) { + if ((_vm->_global->_inter_mouseX < _fascinWin[i].left + 12) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) && + (VAR(_winVarArrayStatus / 4 + i) & 2)) { + blitCursor(); + activeWin(i); + closeWin(i); + _vm->_util->waitMouseRelease(1); + return(i); + } + if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left + _fascinWin[i].width - 12) && + (_vm->_global->_inter_mouseY < _fascinWin[i].top + 12) && + (VAR(_winVarArrayStatus / 4 + i) & 4) && + (_vm->_global->_mousePresent) && + (_vm->_global->_videoMode != 0x07)) { + blitCursor(); + handleWinBorder(i); + winMove(i); + _vm->_global->_inter_mouseX = _fascinWin[i].left + _fascinWin[i].width - 12 + 1; + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + return(-i); + } + return(0); + } else + if (_fascinWin[i].id > bestMatch) { + bestMatch = _fascinWin[i].id; + matchNum = i; + } + } + if (bestMatch != -1) { + blitCursor(); + activeWin(matchNum); + } + return(0); +} + +void Draw::winDecomp(int16 x, int16 y, SurfaceDescPtr bmp) { +// TODO: Implementation to be confirmed (used cut and paste from another part of the code) + Resource *resource; + + resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, + &_spriteRight, &_spriteBottom); + + if (!resource) + return; + + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, *_spritesArray[_destSurface]); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + + delete resource; + return; +} + +void Draw::winDraw(int16 fct) { + int16 left; + int16 top; + int16 width; + int16 height; + + bool found = false; + int i, j, k, l; + int len; + Resource *resource; + int table[10]; + SurfaceDescPtr tempSrf; + + if (_destSurface == 21) { + if (_vm->_global->_curWinId) { + if (_fascinWin[_vm->_global->_curWinId].id == -1) + return; + else { + _destSpriteX += _fascinWin[_vm->_global->_curWinId].left; + _destSpriteY += _fascinWin[_vm->_global->_curWinId].top; + if (fct == 3 || (fct >= 7 && fct <= 9)) { + _spriteRight += _fascinWin[_vm->_global->_curWinId].left; + _spriteBottom += _fascinWin[_vm->_global->_curWinId].top; + } + } + } + left = _destSpriteX; + top = _destSpriteY; + } else { + if (_vm->_global->_curWinId) { + if (_fascinWin[_vm->_global->_curWinId].id == -1) + return; + else { + _spriteLeft += _fascinWin[_vm->_global->_curWinId].left; + _spriteTop += _fascinWin[_vm->_global->_curWinId].top; + } + } + left = _spriteLeft; + top = _spriteTop; + } + for (i = 0; i < 10; i++) + table[i] = 0; + switch (fct) { + case DRAW_BLITSURF: // 0 - move + case DRAW_FILLRECT: // 2 - fill rectangle + width = left + _spriteRight - 1; + height = top + _spriteBottom - 1; + break; + case DRAW_PUTPIXEL: // 1 - put a pixel + width = _destSpriteX; + height = _destSpriteY; + break; + case DRAW_DRAWLINE: // 3 - draw line + case DRAW_DRAWBAR: // 7 - draw border + case DRAW_CLEARRECT: // 8 - clear rectangle + case DRAW_FILLRECTABS:// 9 - fill rectangle, with other coordinates + width = _spriteRight; + height = _spriteBottom; + break; + case DRAW_INVALIDATE: // 4 - Draw a circle + left = _destSpriteX - _spriteRight; + top = _destSpriteY - _spriteRight; + width = _destSpriteX + _spriteRight; + height = _destSpriteY + _spriteBottom; + break; + case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite + +// TODO: check the implementation, currently dirty cut and paste of DRAW_SPRITE code + resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, + &_spriteRight, &_spriteBottom); + + if (!resource) + break; + + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, *_spritesArray[_destSurface]); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + + delete resource; + + width = _destSpriteX + _spriteRight - 1; + height = _destSpriteY + _spriteBottom - 1; + break; + case DRAW_PRINTTEXT: // 6 - Display string + width = _destSpriteX - 1 + strlen(_textToPrint) * _fonts[_fontIndex]->getCharWidth(); + height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight(); + break; + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) { + width = _destSpriteX - 1 + _fonts[_fontIndex]->getCharWidth(); + height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight(); + } else { + width = _destSpriteX + _fontToSprite[_fontIndex].width - 1; + height = _destSpriteY + _fontToSprite[_fontIndex].height - 1; + } + break; + default: + warning("Unexpected fct value"); + break; + } + for (i = 0; i < 10; i++) + if ((i != _vm->_global->_curWinId) && (_fascinWin[i].id != -1)) + if (!_vm->_global->_curWinId || _fascinWin[i].id>_fascinWin[_vm->_global->_curWinId].id) + if ((_fascinWin[i].left + _fascinWin[i].width > left) && (width >= _fascinWin[i].left) && + (_fascinWin[i].top + _fascinWin[i].height > top ) && (height >= _fascinWin[i].top)) { + found = true; + table[_fascinWin[i].id] = i; + } + if ((_sourceSurface == 21) && (fct == 0)) { + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface], + _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); + if (!found) + return; + if (_vm->_global->_curWinId == 0) + j = 0; + else + j = _fascinWin[_vm->_global->_curWinId].id + 1; + for (i = 9; i >= j; i--) { + if (table[i]) + _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *_spritesArray[_destSurface], + _fascinWin[table[i]].left & 15, 0, + (_fascinWin[table[i]].left & 15) + _fascinWin[table[i]].width - 1, + _fascinWin[table[i]].height - 1, _fascinWin[table[i]].left - _spriteLeft + _destSpriteX, + _fascinWin[table[i]].top - _spriteTop + _destSpriteY, 0); + } + return; + } + if (found) { + tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0); + _vm->_video->drawSprite(*_backSurface, *tempSrf, left, top, width, height, 0, 0, 0); + if (_vm->_global->_curWinId == 0) + j = 0; + else + j = _fascinWin[_vm->_global->_curWinId].id + 1; + for (i = 9; i >= j; i--) { + if (table[i]) + _vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *tempSrf, + _fascinWin[table[i]].left & 15, 0, + (_fascinWin[table[i]].left & 15) + _fascinWin[table[i]].width - 1, + _fascinWin[table[i]].height - 1, + _fascinWin[table[i]].left - left, + _fascinWin[table[i]].top - top , 0); + } +// Strangerke not sure concerning the use of _destSurface + dirtiedRect(_destSurface, left, top, width, height); + switch (fct) { + case DRAW_BLITSURF: // 0 - move + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *tempSrf, + _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, 0, 0, _transparency); + break; + case DRAW_PUTPIXEL: // 1 - put a pixel + _vm->_video->putPixel(0, 0, _frontColor, *tempSrf); + break; + case DRAW_FILLRECT: // 2 - fill rectangle + _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor); + break; + case DRAW_DRAWLINE: // 3 - draw line + _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + break; + case DRAW_INVALIDATE: // 4 - Draw a circle + _vm->_video->drawCircle(*tempSrf, _spriteRight, _spriteRight, _spriteRight, _frontColor); + break; + case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite + winDecomp(0, 0, tempSrf); + break; + case DRAW_PRINTTEXT: // 6 - Display string + len = strlen(_textToPrint); + for (j = 0; j < len; j++) + _vm->_video->drawLetter(_textToPrint[j], j * _fonts[_fontIndex]->getCharWidth(), 0, + *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); + _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); + break; + case DRAW_DRAWBAR: // 7 - draw border + _vm->_video->drawLine(*tempSrf, 0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + _vm->_video->drawLine(*tempSrf, 0, 0, 0, _spriteBottom - _destSpriteY, _frontColor); + _vm->_video->drawLine(*tempSrf, _spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor); + _vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, 0, _frontColor); + break; + case DRAW_CLEARRECT: // 8 - clear rectangle + if (_backColor < 16) + _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); + break; + case DRAW_FILLRECTABS:// 9 - fill rectangle, with other coordinates + _vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor); + break; + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) + _vm->_video->drawLetter(_letterToPrint, 0, 0, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf); + else { + int xx, yy, nn; + nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width; + yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height; + xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width; + _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *tempSrf, + xx, yy, xx + _fontToSprite[_fontIndex].width - 1, + yy + _fontToSprite[_fontIndex].height - 1, 0, 0, _transparency); + } + break; + default: + warning("Unexpected fct value"); + break; + } + if (_vm->_global->_curWinId == 0) + i = 0; + else + i = _fascinWin[_vm->_global->_curWinId].id + 1; + for (;i < 10; i++) { + if (table[i]) { + k = table[i]; + _vm->_video->drawSprite(*tempSrf, *_fascinWin[k].savedSurface, + 0, 0, width - left, height - top, + left - _fascinWin[k].left + (_fascinWin[k].left & 15), + top - _fascinWin[k].top, 0); +// Shift skipped as always set to zero (?) + _vm->_video->drawSprite(*_frontSurface, *tempSrf, + MAX(left , _fascinWin[k].left), + MAX(top , _fascinWin[k].top), + MIN(width , (int16) (_fascinWin[k].left + _fascinWin[k].width - 1)), + MIN(height, (int16) (_fascinWin[k].top + _fascinWin[k].height - 1)), + MAX(left , _fascinWin[k].left) - left, + MAX(top , _fascinWin[k].top) - top, 0); + if (_cursorIndex != -1) + _vm->_video->drawSprite(*_cursorSpritesBack, *tempSrf, + 0, 0, _cursorWidth - 1, _cursorHeight - 1, + _cursorX - left, _cursorY - top, 0); + for (j = 9; j > i; j--) { + if (table[j] && winOverlap(k, table[j])) { + l = table[j]; + _vm->_video->drawSprite(*_fascinWin[l].savedSurface, *tempSrf, + MAX(_fascinWin[l].left, _fascinWin[k].left) + - _fascinWin[l].left + (_fascinWin[l].left & 15), + MAX(_fascinWin[l].top , _fascinWin[k].top ) - _fascinWin[l].top, + MIN(_fascinWin[l].left + _fascinWin[l].width - 1, _fascinWin[k].left + _fascinWin[k].width - 1) + - _fascinWin[l].left + (_fascinWin[l].left & 15), + MIN(_fascinWin[l].top + _fascinWin[l].height - 1, _fascinWin[k].top + _fascinWin[k].height - 1) + - _fascinWin[l].top, + MAX(_fascinWin[l].left, _fascinWin[k].left) - left, + MAX(_fascinWin[l].top , _fascinWin[k].top ) - top, 0); + } + } + } + } + _vm->_video->drawSprite(*tempSrf, *_backSurface, 0, 0, width - left, height - top, left, top, 0); + tempSrf.reset(); + } else { +// Strangerke not sure concerning the use of _destSurface + dirtiedRect(_destSurface, left, top, width, height); + switch (fct) { + case DRAW_BLITSURF: // 0 - move + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_backSurface, + _spriteLeft, _spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); + break; + case DRAW_PUTPIXEL: // 1 - put a pixel + _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, *_backSurface); + break; + case DRAW_FILLRECT: // 2 - fill rectangle + _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); + break; + case DRAW_DRAWLINE: // 3 - draw line + _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); + break; + case DRAW_INVALIDATE: // 4 - Draw a circle + _vm->_video->drawCircle(*_backSurface, _spriteRight, _spriteRight, _spriteRight, _frontColor); + break; + case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite + winDecomp(_destSpriteX, _destSpriteY, _backSurface); + break; + case DRAW_PRINTTEXT: // 6 - Display string + len = strlen(_textToPrint); + for ( j = 0; j < len; j++) + _vm->_video->drawLetter(_textToPrint[j], _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(), + _destSpriteY, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *_backSurface); + _destSpriteX += len * _fonts[_fontIndex]->getCharWidth(); + break; + case DRAW_DRAWBAR: // 7 - draw border + _vm->_video->drawLine(*_backSurface, _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); + _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); + _vm->_video->drawLine(*_backSurface, _spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); + _vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); + break; + case DRAW_CLEARRECT: // 8 - clear rectangle + if (_backColor < 16) + _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); + break; + case DRAW_FILLRECTABS:// 9 - fill rectangle, with other coordinates + _vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); + break; + case DRAW_DRAWLETTER: // 10 - Display a character + if (_fontToSprite[_fontIndex].sprite == -1) + _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, *_fonts[_fontIndex], _transparency, + _frontColor, _backColor, *_spritesArray[_destSurface]); + else { + int xx, yy, nn; + nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width; + yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height; + xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width; + _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *_spritesArray[_destSurface], + xx, yy, + xx + _fontToSprite[_fontIndex].width - 1, + yy + _fontToSprite[_fontIndex].height - 1, + _destSpriteX, _destSpriteY, _transparency); + } + break; + default: + warning("Unexpected fct value"); + break; + } + } + if (_renderFlags & 16) { + if (_sourceSurface == 21) { + _spriteLeft -= _backDeltaX; + _spriteTop -= _backDeltaY; + } + if (_destSurface == 21) { + _destSpriteX -= _backDeltaX; + _destSpriteY -= _backDeltaY; + } + } + if (_vm->_global->_curWinId) { + _destSpriteX -= _fascinWin[_vm->_global->_curWinId].left; + _destSpriteY -= _fascinWin[_vm->_global->_curWinId].top; + } +} + int32 Draw::getSpriteRectSize(int16 index) { if (!_spritesArray[index]) return 0; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index ef8149d514..8aca71f494 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -55,6 +55,15 @@ public: FontToSprite() : sprite(0), base(0), width(0), height(0) {} }; + struct fascinWin { + int16 id; + int16 left; + int16 top; + int16 width; + int16 height; + SurfaceDescPtr savedSurface; + }; + int16 _renderFlags; int16 _fontIndex; @@ -73,6 +82,7 @@ public: char _letterToPrint; const char *_textToPrint; + char *_hotspotText; int16 _backDeltaX; int16 _backDeltaY; @@ -86,8 +96,8 @@ public: Common::Array<SurfaceDescPtr> _spritesArray; int16 _invalidatedCount; - int16 _invalidatedTops[30]; int16 _invalidatedLefts[30]; + int16 _invalidatedTops[30]; int16 _invalidatedRights[30]; int16 _invalidatedBottoms[30]; @@ -140,6 +150,19 @@ public: int16 _pattern; + fascinWin _fascinWin[10]; + int16 _winMaxWidth; + int16 _winMaxHeight; + int16 _winCount; + int16 _winVarArrayLeft; + int16 _winVarArrayTop; + int16 _winVarArrayWidth; + int16 _winVarArrayHeight; + int16 _winVarArrayStatus; + int16 _winVarArrayLimitsX; + int16 _winVarArrayLimitsY; + + void invalidateRect(int16 left, int16 top, int16 right, int16 bottom); void blitInvalidated(); void setPalette(); @@ -162,6 +185,21 @@ public: int16 transp, SurfaceDesc &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); + + int16 openWin(int16 id); + int16 handleCurWin(); + bool winOverlap(int16 idWin1, int16 idWin2); + void winDecomp(int16 x, int16 y, SurfaceDescPtr bmp); + void activeWin(int16 id); + void closeWin(int16 id); + void restoreWin(int16 i); + void saveWin(int16 id); + void winMove(int16 id); + void handleWinBorder(int16 id); + void winDraw(int16 fct); + void winTrace(int16 left, int16 top, int16 width, int16 height); + int32 getSpriteRectSize(int16 index); void forceBlit(bool backwards = false); @@ -222,12 +260,11 @@ public: virtual ~Draw_Bargon() {} }; -class Draw_Fascin: public Draw_v2 { +class Draw_Fascination: public Draw_v1 { public: - virtual void initScreen(); - - Draw_Fascin(GobEngine *vm); - virtual ~Draw_Fascin() {} + Draw_Fascination(GobEngine *vm); + virtual ~Draw_Fascination() {} + virtual void spriteOperation(int16 operation); }; class Draw_Playtoons: public Draw_v2 { diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 58bf486bc1..6a44cdc7f0 100644 --- a/engines/gob/draw_fascin.cpp +++ b/engines/gob/draw_fascin.cpp @@ -23,22 +23,231 @@ * */ -#include "gob/gob.h" +//#include "common/endian.h" +//#include "graphics/cursorman.h" + #include "gob/draw.h" -#include "gob/global.h" -#include "gob/video.h" +#include "gob/game.h" +#include "gob/resources.h" namespace Gob { -Draw_Fascin::Draw_Fascin(GobEngine *vm) : Draw_v2(vm) { +Draw_Fascination::Draw_Fascination(GobEngine *vm) : Draw_v1(vm) { } -void Draw_Fascin::initScreen(void) { - _vm->_global->_videoMode = 0x14; - _vm->_video->_surfWidth = 640; - _vm->_video->initPrimary(_vm->_global->_videoMode); +void Draw_Fascination::spriteOperation(int16 operation) { + int16 len; + int16 x, y; + int16 perLine; + Resource *resource; + + operation &= 0x0F; + + if (_sourceSurface >= 100) + _sourceSurface -= 80; + if (_destSurface >= 100) + _destSurface -= 80; + + if (_renderFlags & RENDERFLAG_USEDELTAS) { + if (_sourceSurface == 21) { + _spriteLeft += _backDeltaX; + _spriteTop += _backDeltaY; + } + + if (_destSurface == 21) { + _destSpriteX += _backDeltaX; + _destSpriteY += _backDeltaY; + if ((operation == DRAW_DRAWLINE) || + ((operation >= DRAW_DRAWBAR) && + (operation <= DRAW_FILLRECTABS))) { + _spriteRight += _backDeltaX; + _spriteBottom += _backDeltaY; + } + } + } + + if (_renderFlags & 0x20) { + if (_destSurface == 21 || (operation == 0 && _sourceSurface == 21)) { + winDraw(operation); + return; + } + } + + Font *font = 0; + switch (operation) { + case DRAW_BLITSURF: + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], + *_spritesArray[_destSurface], + _spriteLeft, _spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + break; + + case DRAW_PUTPIXEL: + _vm->_video->putPixel(_destSpriteX, _destSpriteY, + _frontColor, *_spritesArray[_destSurface]); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); + break; + + case DRAW_FILLRECT: + _vm->_video->fillRect(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1, _backColor); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + break; + + case DRAW_DRAWLINE: + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _spriteBottom, _frontColor); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); + break; + + case DRAW_INVALIDATE: + dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, + _destSpriteX + _spriteRight, _destSpriteY + _spriteBottom); + break; + + case DRAW_LOADSPRITE: + resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, + &_spriteRight, &_spriteBottom); + + if (!resource) + break; + + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, *_spritesArray[_destSurface]); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + + delete resource; + break; + + case DRAW_PRINTTEXT: + font = _fonts[_fontIndex]; + if (!font) { + warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex); + break; + } + + len = strlen(_textToPrint); + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + len * font->getCharWidth() - 1, + _destSpriteY + font->getCharHeight() - 1); + + for (int i = 0; i < len; i++) { + _vm->_video->drawLetter(_textToPrint[i], + _destSpriteX, _destSpriteY, + *font, _transparency, + _frontColor, _backColor, + *_spritesArray[_destSurface]); + + _destSpriteX += font->getCharWidth(); + } + break; + + case DRAW_DRAWBAR: + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _spriteBottom, + _spriteRight, _spriteBottom, _frontColor); + + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _destSpriteX, _spriteBottom, _frontColor); + + _vm->_video->drawLine(*_spritesArray[_destSurface], + _spriteRight, _destSpriteY, + _spriteRight, _spriteBottom, _frontColor); + + _vm->_video->drawLine(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _destSpriteY, _frontColor); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); + break; + + case DRAW_CLEARRECT: + if (_backColor < 16) { + _vm->_video->fillRect(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _spriteBottom, + _backColor); + } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); + break; + + case DRAW_FILLRECTABS: + _vm->_video->fillRect(*_spritesArray[_destSurface], + _destSpriteX, _destSpriteY, + _spriteRight, _spriteBottom, _backColor); + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); + break; + + case DRAW_DRAWLETTER: + font = _fonts[_fontIndex]; + if (!font) { + warning("Trying to print \'%c\' with undefined font %d", _letterToPrint, _fontIndex); + break; + } + + if (_fontToSprite[_fontIndex].sprite == -1) { + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + font->getCharWidth() - 1, + _destSpriteY + font->getCharHeight() - 1); + _vm->_video->drawLetter(_letterToPrint, + _destSpriteX, _destSpriteY, + *font, _transparency, + _frontColor, _backColor, + *_spritesArray[_destSurface]); + break; + } + + perLine = + _spritesArray[(int16)_fontToSprite[_fontIndex].sprite]->getWidth() / + _fontToSprite[_fontIndex].width; + + y = (_letterToPrint - _fontToSprite[_fontIndex].base) / perLine * + _fontToSprite[_fontIndex].height; + + x = (_letterToPrint - _fontToSprite[_fontIndex].base) % perLine * + _fontToSprite[_fontIndex].width; + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _fontToSprite[_fontIndex].width, + _destSpriteY + _fontToSprite[_fontIndex].height); + + _vm->_video->drawSprite(*_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], + *_spritesArray[_destSurface], x, y, + x + _fontToSprite[_fontIndex].width, + y + _fontToSprite[_fontIndex].height, + _destSpriteX, _destSpriteY, _transparency); + + break; + } + + if (_renderFlags & RENDERFLAG_USEDELTAS) { + if (_sourceSurface == 21) { + _spriteLeft -= _backDeltaX; + _spriteTop -= _backDeltaY; + } - Draw_v2::initScreen(); + if (_destSurface == 21) { + _destSpriteX -= _backDeltaX; + _destSpriteY -= _backDeltaY; + } + } } } // End of namespace Gob diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index f4f1303386..ede88514a5 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -127,6 +127,8 @@ Global::Global(GobEngine *vm) : _vm(vm) { _doSubtitles = false; _noCd = false; + + _curWinId = 0; } Global::~Global() { diff --git a/engines/gob/global.h b/engines/gob/global.h index 5830e3e58c..c86e321737 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -145,6 +145,8 @@ public: bool _noCd; + int16 _curWinId; + Global(GobEngine *vm); ~Global(); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 774b25dc48..0c6024e4aa 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -362,7 +362,7 @@ bool GobEngine::initGameParts() { _video = new Video_v2(this); _inter = new Inter_Fascination(this); _mult = new Mult_v2(this); - _draw = new Draw_v2(this); + _draw = new Draw_Fascination(this); _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index ff8ffbbab8..4f863888fb 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -646,7 +646,6 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index if (isValid(_currentKey, _currentId, _currentIndex)) enter(_currentIndex); } - _vm->_draw->animateCursor(-1); } @@ -712,48 +711,59 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index if (_vm->_game->_mouseButtons != kMouseButtonsNone) { // Mouse button pressed - - if (delay > 0) { - // If a delay was requested, wait the specified time - + int i; + if (_vm->getGameType() == kGameTypeFascination) + i = _vm->_draw->handleCurWin(); + else + i = 0; + if (!i) { _vm->_draw->animateCursor(2); - _vm->_util->delay(delay); - } else if (handleMouse & 1) - _vm->_util->waitMouseRelease(1); - - _vm->_draw->animateCursor(-1); + if (delay > 0) { + // If a delay was requested, wait the specified time + _vm->_util->delay(delay); + } else if (handleMouse & 1) + _vm->_util->waitMouseRelease(1); - // Which region was clicked? - key = checkMouse(kTypeClick, id, index); + _vm->_draw->animateCursor(-1); - if ((key != 0) || (id != 0)) { - // Got a valid region + // Which region was clicked? + key = checkMouse(kTypeClick, id, index); - if ( (handleMouse & 1) && - ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone))) - _vm->_draw->blitCursor(); + if ((key != 0) || (id != 0)) { + // Got a valid region - // If the hotspot changed, leave the old one - if (key != _currentKey) - leave(_currentIndex); + if ( (handleMouse & 1) && + ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone))) + _vm->_draw->blitCursor(); - _currentKey = 0; - break; - } + // If the hotspot changed, leave the old one + if (key != _currentKey) + leave(_currentIndex); - if (handleMouse & 4) - // Nothing further than one simple check was requested => return - return 0; + _currentKey = 0; + break; + } - // Leave the current area - if (_currentKey != 0) - leave(_currentIndex); + if (handleMouse & 4) + // Nothing further than one simple check was requested => return + return 0; - // No click, but do we have a move event? If so, enter that hotspot - _currentKey = checkMouse(kTypeMove, _currentId, _currentIndex); - if (isValid(_currentKey, _currentId, _currentIndex)) - enter(_currentIndex); + // Leave the current area + if (_currentKey != 0) + leave(_currentIndex); + // No click, but do we have a move event? If so, enter that hotspot + _currentKey = checkMouse(kTypeMove, _currentId, _currentIndex); + if (isValid(_currentKey, _currentId, _currentIndex)) + enter(_currentIndex); + } else { + WRITE_VAR(16, (int32) i); + if (id) + id=0; + if (index) + index=0; + return(0); + } } else // No mouse button pressed, check whether the position changed at least checkHotspotChanged(); @@ -1180,6 +1190,30 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, width = _vm->_game->_script->readUint16(); height = _vm->_game->_script->readUint16(); } + if (_vm->_draw->_renderFlags & 64) { + warning("_renderFlags check added for Fascination"); + _vm->_draw->_invalidatedTops[0] = 0; + _vm->_draw->_invalidatedLefts[0] = 0; + _vm->_draw->_invalidatedRights[0] = 319; + _vm->_draw->_invalidatedBottoms[0] = 199; + _vm->_draw->_invalidatedCount = 1; + if (window == 0) { + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0); + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); + } else + if ((_vm->_draw->_fascinWin[window].id != -1) && (_vm->_draw->_fascinWin[window].id == _vm->_draw->_winCount - 1)) { + left += _vm->_draw->_fascinWin[window].left; + top += _vm->_draw->_fascinWin[window].top; + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0); + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); + _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); + left -= _vm->_draw->_fascinWin[window].left; + top -= _vm->_draw->_fascinWin[window].top; + } + } type &= 0x7F; // Apply global drawing offset @@ -1569,7 +1603,7 @@ void Hotspots::oPlaytoons_F_1B(void) { int16 shortId; int16 longId; int16 var2; - int16 var3; + int16 fontIndex; int16 var4; uint16 left; @@ -1582,7 +1616,7 @@ void Hotspots::oPlaytoons_F_1B(void) { _vm->_game->_script->evalExpr(0); - var3 = _vm->_game->_script->readValExpr(); + fontIndex = _vm->_game->_script->readValExpr(); var4 = _vm->_game->_script->readValExpr(); // this variable is always set to 0 in Playtoons @@ -1595,8 +1629,7 @@ void Hotspots::oPlaytoons_F_1B(void) { if ((_hotspots[i].id == 0xD000 + shortId) || (_hotspots[i].id == 0xB000 + shortId) || (_hotspots[i].id == 0x4000 + shortId)) { longId = _hotspots[i].id; - warning("oPlaytoons_F_1B not fully handled"); - warning("shortId %d, var2 %d var3 %d var4 %d", shortId, var2, var3, var4); + warning("oPlaytoons_F_1B: shortId %d, var2 %d fontIndex %d var4 %d - longId %d", shortId, var2, fontIndex, var4, longId); left = _hotspots[i].left; top = _hotspots[i].top; @@ -1613,7 +1646,8 @@ void Hotspots::oPlaytoons_F_1B(void) { right -= 2; bottom -= 2; } - oPlaytoons_sub_F_1B(0x8000 + var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), var3, var4, shortId); +// oPlaytoons_sub_F_1B(0x8000 + var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), var3, var4, shortId); + _vm->_draw->oPlaytoons_sub_F_1B(0x8000+ var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), fontIndex, var4, shortId); return; } } @@ -2030,17 +2064,4 @@ void Hotspots::updateAllTexts(const InputDesc *inputs) const { input++; } } - -void Hotspots::oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 var3, int16 var4, int16 shortId) -{ - char tmpStr[128]; - - strcpy( tmpStr, paramStr); - _vm->_draw->adjustCoords(1, &left, &right); - _vm->_draw->adjustCoords(1, &top, &bottom); - - warning("oPlaytoons_sub_F_1B display string %s", paramStr); - return; -} - } // End of namespace Gob diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h index 29f4d40b7b..0679d3a78e 100644 --- a/engines/gob/hotspots.h +++ b/engines/gob/hotspots.h @@ -269,8 +269,6 @@ private: /** Go through all inputs we manage and redraw their texts. */ void updateAllTexts(const InputDesc *inputs) const; - - void oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *str, int16 var3, int16 var4, int16 shortId); }; } // End of namespace Gob diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 834e9b8553..79304419ab 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -113,6 +113,11 @@ void Init::initGame() { _palDesc->unused2 = _vm->_draw->_unusedPalette2; _vm->_video->setFullPalette(_palDesc); + for (int i = 0; i < 10; i++) + _vm->_draw->_fascinWin[i].id = -1; + + _vm->_draw->_winCount = 0; + for (int i = 0; i < 8; i++) _vm->_draw->_fonts[i] = 0; diff --git a/engines/gob/init.h b/engines/gob/init.h index c2784a59ac..85e268a69e 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -90,6 +90,13 @@ public: void initGame(); }; +class Init_Fascination : public Init_v2 { +public: + Init_Fascination(GobEngine *vm); + ~Init_Fascination(); + + void initGame(); +}; } // End of namespace Gob #endif // GOB_INIT_H diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 772dd9c46d..157476f241 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -432,29 +432,29 @@ protected: void oFascin_playProtracker(OpGobParams ¶ms); - void oFascin_geUnknown0(OpGobParams ¶ms); - void oFascin_geUnknown1(OpGobParams ¶ms); - void oFascin_geUnknown2(OpGobParams ¶ms); - void oFascin_geUnknown3(OpGobParams ¶ms); - void oFascin_geUnknown4(OpGobParams ¶ms); - void oFascin_geUnknown5(OpGobParams ¶ms); - void oFascin_geUnknown6(OpGobParams ¶ms); - void oFascin_geUnknown7(OpGobParams ¶ms); - void oFascin_geUnknown8(OpGobParams ¶ms); - void oFascin_geUnknown9(OpGobParams ¶ms); - void oFascin_geUnknown10(OpGobParams ¶ms); - void oFascin_geUnknown11(OpGobParams ¶ms); + void oFascin_playTirb(OpGobParams ¶ms); + void oFascin_playTira(OpGobParams ¶ms); + void oFascin_loadExtasy(OpGobParams ¶ms); + void oFascin_adlibPlay(OpGobParams ¶ms); + void oFascin_adlibStop(OpGobParams ¶ms); + void oFascin_adlibUnload(OpGobParams ¶ms); + void oFascin_loadMus1(OpGobParams ¶ms); + void oFascin_loadMus2(OpGobParams ¶ms); + void oFascin_loadMus3(OpGobParams ¶ms); + void oFascin_loadBatt1(OpGobParams ¶ms); + void oFascin_loadBatt2(OpGobParams ¶ms); + void oFascin_loadBatt3(OpGobParams ¶ms); void oFascin_geUnknown1000(OpGobParams ¶ms); void oFascin_geUnknown1001(OpGobParams ¶ms); void oFascin_geUnknown1002(OpGobParams ¶ms); bool oFascin_feUnknown4(OpFuncParams ¶ms); bool oFascin_feUnknown27(OpFuncParams ¶ms); - void oFascin_cdUnknown3(); - void oFascin_cdUnknown4(); - void oFascin_cdUnknown5(); - void oFascin_cdUnknown6(); + void oFascin_setWinSize(); + void oFascin_closeWin(); + void oFascin_activeWin(); + void oFascin_openWin(); void oFascin_setRenderFlags(); - void oFascin_cdUnknown11(); + void oFascin_setWinFlags(); }; class Inter_v3 : public Inter_v2 { diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp index 3c4713f9eb..9bd837f194 100644 --- a/engines/gob/inter_fascin.cpp +++ b/engines/gob/inter_fascin.cpp @@ -51,14 +51,13 @@ Inter_Fascination::Inter_Fascination(GobEngine *vm) : Inter_v2(vm) { void Inter_Fascination::setupOpcodesDraw() { Inter_v2::setupOpcodesDraw(); - OPCODEDRAW(0x03, oFascin_cdUnknown3); - - OPCODEDRAW(0x04, oFascin_cdUnknown4); - OPCODEDRAW(0x05, oFascin_cdUnknown5); - OPCODEDRAW(0x06, oFascin_cdUnknown6); + OPCODEDRAW(0x03, oFascin_setWinSize); + OPCODEDRAW(0x04, oFascin_closeWin); + OPCODEDRAW(0x05, oFascin_activeWin); + OPCODEDRAW(0x06, oFascin_openWin); OPCODEDRAW(0x0A, oFascin_setRenderFlags); - OPCODEDRAW(0x0B, oFascin_cdUnknown11); + OPCODEDRAW(0x0B, oFascin_setWinFlags); CLEAROPCODEDRAW(0x50); CLEAROPCODEDRAW(0x51); @@ -89,27 +88,27 @@ void Inter_Fascination::setupOpcodesFunc() { } void Inter_Fascination::setupOpcodesGob() { - OPCODEGOB( 1, oFascin_geUnknown0); - OPCODEGOB( 2, oFascin_geUnknown1); - OPCODEGOB( 3, oFascin_geUnknown2); - OPCODEGOB( 4, oFascin_geUnknown3); + OPCODEGOB( 1, oFascin_playTirb); + OPCODEGOB( 2, oFascin_playTira); + OPCODEGOB( 3, oFascin_loadExtasy); + OPCODEGOB( 4, oFascin_adlibPlay); - OPCODEGOB( 5, oFascin_geUnknown4); - OPCODEGOB( 6, oFascin_geUnknown5); - OPCODEGOB( 7, oFascin_geUnknown6); - OPCODEGOB( 8, oFascin_geUnknown7); + OPCODEGOB( 5, oFascin_adlibStop); + OPCODEGOB( 6, oFascin_adlibUnload); + OPCODEGOB( 7, oFascin_loadMus1); + OPCODEGOB( 8, oFascin_loadMus2); - OPCODEGOB( 9, oFascin_geUnknown8); - OPCODEGOB( 10, oFascin_geUnknown9); - OPCODEGOB( 11, oFascin_geUnknown10); - OPCODEGOB( 12, oFascin_geUnknown11); + OPCODEGOB( 9, oFascin_loadMus3); + OPCODEGOB( 10, oFascin_loadBatt1); + OPCODEGOB( 11, oFascin_loadBatt2); + OPCODEGOB( 12, oFascin_loadBatt3); OPCODEGOB(1000, oFascin_geUnknown1000); OPCODEGOB(1001, oFascin_geUnknown1001); //protrackerPlay doesn't play correctly "mod.extasy" OPCODEGOB(1002, oFascin_geUnknown1002); //to be replaced by o2_stopProtracker when protrackerPlay is fixed } -void Inter_Fascination::oFascin_geUnknown0(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_playTirb(OpGobParams ¶ms) { warning("Fascination Unknown GE Function 0"); warning("funcPlayImd with parameter : 'tirb.imd'"); @@ -120,7 +119,7 @@ void Inter_Fascination::oFascin_geUnknown0(OpGobParams ¶ms) { _vm->_draw->closeScreen(); } -void Inter_Fascination::oFascin_geUnknown1(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_playTira(OpGobParams ¶ms) { warning("Fascination Unknown GE Function 1"); warning("funcPlayImd with parameter : 'tira.imd'"); if (_vm->_vidPlayer->primaryOpen("tira.imd")) { @@ -130,49 +129,49 @@ void Inter_Fascination::oFascin_geUnknown1(OpGobParams ¶ms) { _vm->_draw->closeScreen(); } -void Inter_Fascination::oFascin_geUnknown2(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadExtasy(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("extasy.tbr"); _vm->_sound->adlibLoadMDY("extasy.mdy"); } -void Inter_Fascination::oFascin_geUnknown3(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_adlibPlay(OpGobParams ¶ms) { _vm->_sound->adlibPlay(); } -void Inter_Fascination::oFascin_geUnknown4(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_adlibStop(OpGobParams ¶ms) { _vm->_sound->adlibStop(); } -void Inter_Fascination::oFascin_geUnknown5(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_adlibUnload(OpGobParams ¶ms) { _vm->_sound->adlibUnload(); } -void Inter_Fascination::oFascin_geUnknown6(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadMus1(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("music1.tbr"); _vm->_sound->adlibLoadMDY("music1.mdy"); } -void Inter_Fascination::oFascin_geUnknown7(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadMus2(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("music2.tbr"); _vm->_sound->adlibLoadMDY("music2.mdy"); } -void Inter_Fascination::oFascin_geUnknown8(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadMus3(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("music3.tbr"); _vm->_sound->adlibLoadMDY("music3.mdy"); } -void Inter_Fascination::oFascin_geUnknown9(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadBatt1(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("batt1.tbr"); _vm->_sound->adlibLoadMDY("batt1.mdy"); } -void Inter_Fascination::oFascin_geUnknown10(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadBatt2(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("batt2.tbr"); _vm->_sound->adlibLoadMDY("batt2.mdy"); } -void Inter_Fascination::oFascin_geUnknown11(OpGobParams ¶ms) { +void Inter_Fascination::oFascin_loadBatt3(OpGobParams ¶ms) { _vm->_sound->adlibLoadTBR("batt3.tbr"); _vm->_sound->adlibLoadMDY("batt3.mdy"); } @@ -199,59 +198,58 @@ bool Inter_Fascination::oFascin_feUnknown27(OpFuncParams ¶ms) { return true; } -void Inter_Fascination::oFascin_cdUnknown3() { - uint16 resVar, resVar2; - int16 retVal1, retVal2, retVal3, retVal4, retVal5, retVal6, retVal7; - - warning("Fascination oFascin_cdUnknown3 - Variables initialisations"); - - resVar = _vm->_game->_script->readUint16(); - resVar2 = _vm->_game->_script->readUint16(); - retVal1 = _vm->_game->_script->readVarIndex(); - retVal2 = _vm->_game->_script->readVarIndex(); - retVal3 = _vm->_game->_script->readVarIndex(); - retVal4 = _vm->_game->_script->readVarIndex(); - retVal5 = _vm->_game->_script->readVarIndex(); - retVal6 = _vm->_game->_script->readVarIndex(); - retVal7 = _vm->_game->_script->readVarIndex(); - warning ("Width? :%d Height? :%d",resVar, resVar2); - warning ("Fetched variables 1:%d 2:%d 3:%d 4:%d 5:%d 6:%d 7:%d", retVal1, retVal2, retVal3, retVal4, retVal5, retVal6, retVal7); +void Inter_Fascination::oFascin_setWinSize() { + _vm->_draw->_winMaxWidth = _vm->_game->_script->readUint16(); + _vm->_draw->_winMaxHeight = _vm->_game->_script->readUint16(); + _vm->_draw->_winVarArrayLeft = _vm->_game->_script->readVarIndex(); + _vm->_draw->_winVarArrayTop = _vm->_game->_script->readVarIndex(); + _vm->_draw->_winVarArrayWidth = _vm->_game->_script->readVarIndex(); + _vm->_draw->_winVarArrayHeight = _vm->_game->_script->readVarIndex(); + _vm->_draw->_winVarArrayStatus = _vm->_game->_script->readVarIndex(); + _vm->_draw->_winVarArrayLimitsX = _vm->_game->_script->readVarIndex(); + _vm->_draw->_winVarArrayLimitsY = _vm->_game->_script->readVarIndex(); + warning("Inter_Fascination::oFascin_setWinSize lmax %d hmax %d x %d y %d l %d h %d stat %d limx %d limy %d", + _vm->_draw->_winMaxWidth, _vm->_draw->_winMaxHeight, + _vm->_draw->_winVarArrayLeft, _vm->_draw->_winVarArrayTop, + _vm->_draw->_winVarArrayWidth, _vm->_draw->_winVarArrayHeight, _vm->_draw->_winVarArrayStatus, + _vm->_draw->_winVarArrayLimitsX, _vm->_draw->_winVarArrayLimitsY); } -void Inter_Fascination::oFascin_cdUnknown4() { - int16 expr; - warning("Fascination oFascin_cdUnknown4"); - _vm->_game->_script->evalExpr(&expr); - warning ("_vm->_game->_script->evalExpr: %d, the rest is not yet implemented",expr); +void Inter_Fascination::oFascin_closeWin() { + int16 id; + _vm->_game->_script->evalExpr(&id); + warning("Inter_Fascination::closeWin id %d", id); + _vm->_draw->activeWin(id); + _vm->_draw->closeWin(id); } -void Inter_Fascination::oFascin_cdUnknown5() { - int16 retVal1,expr; - warning("Fascination oFascin_cdUnknown5"); - _vm->_game->_script->evalExpr(&expr); - retVal1 = _vm->_game->_script->readVarIndex(); - warning ("_vm->_game->_script->evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1); +void Inter_Fascination::oFascin_activeWin() { + int16 id; + _vm->_game->_script->evalExpr(&id); + warning("Inter_Fascination::activeWin id %d", id); + _vm->_draw->activeWin(id); } -void Inter_Fascination::oFascin_cdUnknown6() { - int16 retVal1,expr; - warning("Fascination oFascin_cdUnknown6"); - _vm->_game->_script->evalExpr(&expr); - retVal1 = _vm->_game->_script->readVarIndex(); - warning ("_vm->_game->_script->evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1); +void Inter_Fascination::oFascin_openWin() { + int16 retVal,id; + _vm->_game->_script->evalExpr(&id); + retVal = _vm->_game->_script->readVarIndex(); + warning("Inter_Fascination::openWin index %d, id %d", retVal, id); + WRITE_VAR((retVal / 4), (int32) _vm->_draw->openWin(id)); } void Inter_Fascination::oFascin_setRenderFlags() { int16 expr; -// warning("Fascination oFascin_cdUnknown10 (set render flags)"); _vm->_game->_script->evalExpr(&expr); - warning("_draw_renderFlags <- %d",expr); _vm->_draw->_renderFlags = expr; + warning("Inter_Fascination::oFascin_setRenderFlags: _draw_renderFlags <- %d",expr); } -void Inter_Fascination::oFascin_cdUnknown11() { -// warning("Fascination oFascin_cdUnknown11 (set variable)"); - _vm->_game->_script->evalExpr(0); +void Inter_Fascination::oFascin_setWinFlags() { + int16 expr; + _vm->_game->_script->evalExpr(&expr); + _vm->_global->_curWinId = expr; + warning("Inter_Fascination::oFascin_setWinFlags: _global_DEVwnd <- %d",expr); } void Inter_Fascination::oFascin_playProtracker(OpGobParams ¶ms) { diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index a5747d9574..9e7aa3484c 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -380,6 +380,7 @@ void Inter_Playtoons::oPlaytoons_getObjAnimSize() { warning("oPlaytoons_getObjAnimSize case -2 not implemented"); return; } + if ((objIndex < 0) || (objIndex >= _vm->_mult->_objCount)) { warning("oPlaytoons_getObjAnimSize(): objIndex = %d (%d)", objIndex, _vm->_mult->_objCount); _vm->_scenery->_toRedrawLeft = 0; diff --git a/engines/gob/inter_v3.cpp b/engines/gob/inter_v3.cpp index 17ce7feafa..beace1b7d8 100644 --- a/engines/gob/inter_v3.cpp +++ b/engines/gob/inter_v3.cpp @@ -80,6 +80,11 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { part = _vm->_game->_script->readValExpr(); stringVar = stringStartVar; + if (part == -1) { + warning("o3_getTotTextItemPart, part == -1"); + _vm->_draw->_hotspotText = GET_VARO_STR(stringVar); + } + WRITE_VARO_UINT8(stringVar, 0); TextItem *textItem = _vm->_game->_resources->getTextItem(totTextItem); |