diff options
author | Sven Hesse | 2006-04-18 09:59:18 +0000 |
---|---|---|
committer | Sven Hesse | 2006-04-18 09:59:18 +0000 |
commit | ab48280f731cf65313b4bd57896e762eb04fbce9 (patch) | |
tree | 1646d50032b5c2bf2040cf4ae51f5ce9d50ee918 /engines/gob | |
parent | 4b59f6fbda912ccac9619d144d68536cb4d72834 (diff) | |
download | scummvm-rg350-ab48280f731cf65313b4bd57896e762eb04fbce9.tar.gz scummvm-rg350-ab48280f731cf65313b4bd57896e762eb04fbce9.tar.bz2 scummvm-rg350-ab48280f731cf65313b4bd57896e762eb04fbce9.zip |
- I misunderstood Draw::initBigSprite(); fixed
- Changed Draw::spriteOperation() for blitting from/to/between and
fillrecting to big sprites
- Enabled drawing of text
svn-id: r22001
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/draw.cpp | 297 | ||||
-rw-r--r-- | engines/gob/draw.h | 26 | ||||
-rw-r--r-- | engines/gob/draw_v2.cpp | 605 | ||||
-rw-r--r-- | engines/gob/game.cpp | 289 | ||||
-rw-r--r-- | engines/gob/game.h | 36 | ||||
-rw-r--r-- | engines/gob/game_v1.cpp | 293 | ||||
-rw-r--r-- | engines/gob/game_v2.cpp | 302 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 6 | ||||
-rw-r--r-- | engines/gob/inter_v1.cpp | 2 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 10 | ||||
-rw-r--r-- | engines/gob/module.mk | 6 | ||||
-rw-r--r-- | engines/gob/mult.cpp | 1 | ||||
-rw-r--r-- | engines/gob/mult_v2.cpp | 17 | ||||
-rw-r--r-- | engines/gob/video.cpp | 63 | ||||
-rw-r--r-- | engines/gob/video.h | 25 | ||||
-rw-r--r-- | engines/gob/video_v1.cpp | 41 | ||||
-rw-r--r-- | engines/gob/video_v2.cpp | 74 |
17 files changed, 1704 insertions, 389 deletions
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index e43a76f614..06f44a794d 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -39,6 +39,9 @@ namespace Gob { Draw::Draw(GobEngine *vm) : _vm(vm) { + int i; + int j; + _fontIndex = 0; _spriteLeft = 0; _spriteTop = 0; @@ -55,10 +58,8 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _renderFlags = 0; _backDeltaX = 0; _backDeltaY = 0; - - int i; - for (i = 0; i < 4; i++) + for (i = 0; i < 8; i++) _fonts[i] = 0; _textToPrint = 0; @@ -66,10 +67,10 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { for (i = 0; i < 50; i++) { _spritesArray[i] = 0; - _sprites1[i] = 0; - _sprites2[i] = 0; - _sprites3[i] = 0; - _spritesWidths[i] = 0; + _spritesHeights[i] = 0; + for (j = 0; j < 3; j++) { + _bigSpritesParts[i][j] = 0; + } } _invalidatedCount = 0; @@ -132,6 +133,9 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _palLoadData2[3] = 204; _cursorTimeKey = 0; + + warning("GOB2 Stub! _word_2E8E2"); + _word_2E8E2 = 2; } void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { @@ -435,27 +439,25 @@ void Draw::animateCursor(int16 cursor) { } void Draw::freeSprite(int16 index) { + int i; + // .-- sub_CD84 --- if (_spritesArray[index] == 0) return; _vm->_video->freeSurfDesc(_spritesArray[index]); -// warning("GOB2 Stub! freeSprite: dword_2EFB4, dword_2EFB8, dword_2EFBC"); - - if (_sprites1[index] != 0) - _vm->_video->freeSurfDesc(_sprites1[index]); - if (_sprites2[index] != 0) - _vm->_video->freeSurfDesc(_sprites2[index]); - if (_sprites3[index] != 0) - _vm->_video->freeSurfDesc(_sprites3[index]); - + for (i = 0; i < 3; i++) + if (_bigSpritesParts[index][i] != 0) + _vm->_video->freeSurfDesc(_bigSpritesParts[index][i]); // '------ _spritesArray[index] = 0; } -void Draw::adjustCoords(int16 *coord1, int16 *coord2, char adjust) { - warning("GOB2 Stub! if (word_2E8E2 == 2) return;"); +void Draw::adjustCoords(char adjust, int16 *coord1, int16 *coord2) { + if (_word_2E8E2 == 2) + return; + if (adjust == 0) { if (coord2 != 0) *coord2 *= 2; @@ -476,53 +478,250 @@ void Draw::adjustCoords(int16 *coord1, int16 *coord2, char adjust) { } } -// sub_EDFC(0x16, _anim_animAreaWidth, _anim_animAreaHeight, 0); -void Draw::initBigSprite(int16 index, int16 height, int16 width, int16 flags) { - int16 realwidth; - int16 widthdiff; - Gob::Video::SurfaceDesc **fragment; +void Draw::initBigSprite(int16 index, int16 width, int16 height, int16 flags) { + int i; + int16 partsheight; + int16 remainheight; + int8 fragment; if (flags != 0) flags = 2; // .-- sub_CBD0 --- - _sprites1[index] = 0; - _sprites2[index] = 0; - _sprites3[index] = 0; - _spritesWidths[index] = width; + for (i = 0; i < 3; i++) + _bigSpritesParts[index][i] = 0; + _spritesHeights[index] = height; if (_vm->_video->getRectSize(width, height, flags, _vm->_global->_videoMode) > 6500) { - _spritesWidths[index] = width & 0xFFFE; - while (_vm->_video->getRectSize(_spritesWidths[index], - height, flags, _vm->_global->_videoMode) > 6500) - _spritesWidths[index] -= 2; + _spritesHeights[index] = height & 0xFFFE; + while (_vm->_video->getRectSize(width, _spritesHeights[index], flags, + _vm->_global->_videoMode) > 6500) { + _spritesHeights[index] -= 2; + } - realwidth = _spritesWidths[index]; + partsheight = _spritesHeights[index]; _spritesArray[index] = - _vm->_video->initSurfDesc(realwidth, height, flags, _vm->_global->_videoMode); - - fragment = _sprites1 + index; - while (realwidth < width) { - widthdiff = width - realwidth; - if (_spritesWidths[index] >= widthdiff) { - *fragment = _vm->_video->initSurfDesc(widthdiff, height, flags, _vm->_global->_videoMode); - realwidth = width; - } - else { - *fragment = _vm->_video->initSurfDesc(_spritesWidths[index], height, - flags, _vm->_global->_videoMode); - realwidth += _spritesWidths[index]; + _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, partsheight, flags); + fragment = 0; + while (partsheight < height) { + remainheight = height - partsheight; + if (_spritesHeights[index] >= remainheight) { + _bigSpritesParts[index][fragment] = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, + remainheight, flags); + partsheight = height; + } else { + _bigSpritesParts[index][fragment] = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, + _spritesHeights[index], flags); + partsheight += _spritesHeights[index]; } - _vm->_video->clearSurf(*fragment++); + _vm->_video->clearSurf(_bigSpritesParts[index][fragment]); + fragment++; } } else - _spritesArray[index] = - _vm->_video->initSurfDesc(width, height, flags, _vm->_global->_videoMode); + _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); _vm->_video->clearSurf(_spritesArray[index]); // '------ } -} // End of namespace Gob +void Draw::fillRect(int16 index, int16 left, int16 top, int16 right, + int16 bottom, int16 color) { + int i; + int16 newbottom; + + if (bottom < _spritesHeights[index]) { + _vm->_video->fillRect(_spritesArray[index], left, top, right, bottom, color); + return; + } + + if (top < _spritesHeights[index]) { + _vm->_video->fillRect(_spritesArray[index], left, top, right, + _spritesHeights[index]-1, color); + } + + for (i = 1; i < 4; i++) { + if ((_spritesHeights[index] * i) > bottom) + continue; + if (_bigSpritesParts[index][i-1] == 0) + return; + newbottom = MIN(bottom - (_spritesHeights[index] * i), (_spritesHeights[index] * i) - 1); + _vm->_video->fillRect(_bigSpritesParts[index][i-1], left, 0, right, newbottom, color); + } +} + +void Draw::drawSprite(int16 source, int16 dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { + int i; + int16 topS; + int16 yS; + int16 newbottom; + + if (bottom < _spritesHeights[source]) { + drawSprite(_spritesArray[source], dest, left, top, right, bottom, x, y, transp); + return; + } + + topS = top; + yS = y; + + if (top < _spritesHeights[source]) { + drawSprite(_spritesArray[source], dest, left, top, right, + _spritesHeights[source], x, y, transp); + yS = y + _spritesHeights[source] - top; + topS = _spritesHeights[source]; + } + for (i = 1; i < 4; i++) { + if ((_spritesHeights[source] * i) > topS) + continue; + if ((_spritesHeights[source] * (i+1)) <= topS) + continue; + if (_bigSpritesParts[source][i-1] == 0) + break; + newbottom = MIN(bottom - (_spritesHeights[source] * i), _spritesHeights[source] - 1); + drawSprite(_bigSpritesParts[source][i-1], dest, left, + topS - _spritesHeights[source], right, newbottom, x, yS, transp); + yS += newbottom - (topS - (_spritesHeights[source] * i)) + 1; + topS += newbottom - (topS - (_spritesHeights[source] * i)) + 1; + } +} + +void Draw::drawSprite(Video::SurfaceDesc * source, int16 dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { + int i; + int16 topS; + int16 yS; + int16 newbottom; + + if ((y + bottom - top) < _spritesHeights[dest]) { + _vm->_video->drawSprite(source, _spritesArray[dest], left, top, + right, bottom, x, y, transp); + return; + } + + topS = top; + yS = y; + + if (y < _spritesHeights[dest]) { + _vm->_video->drawSprite(source, _spritesArray[dest], left, top, right, + top + _spritesHeights[dest] - y - 1, x, y, transp); + yS = _spritesHeights[dest]; + topS += _spritesHeights[dest] - y; + } + + for (i = 1; i < 4; i++) { + if ((_spritesHeights[dest] * i) > yS) + continue; + if ((_spritesHeights[dest] * (i+1)) <= yS) + continue; + if (_bigSpritesParts[dest][i-1] == 0) + break; + newbottom = MIN(bottom, (int16) (topS + _spritesHeights[dest] - 1)); + _vm->_video->drawSprite(source, _bigSpritesParts[dest][i-1], left, topS, + right, newbottom, x, yS - (_spritesHeights[dest] * i), transp); + yS += newbottom - topS + 1; + topS += newbottom - topS + 1; + } +} + +void Draw::drawSprite(int16 source, Video::SurfaceDesc * dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { + int i; + int16 topS; + int16 yS; + int16 newbottom; + + if (bottom < _spritesHeights[source]) { + _vm->_video->drawSprite(_spritesArray[source], dest, left, top, right, + bottom, x, y, transp); + return; + } + + topS = top; + yS = y; + + if (top < _spritesHeights[source]) { + _vm->_video->drawSprite(_spritesArray[source], dest, left, top, right, + _spritesHeights[source] - 1, x, y, transp); + yS = y + _spritesHeights[source] - top; + topS = _spritesHeights[source]; + } + + for (i = 1; i < 4; i++) { + if ((_spritesHeights[source] * i) > topS) + continue; + if ((_spritesHeights[source] * (i+1)) <= topS) + continue; + if (_bigSpritesParts[source][i-1] == 0) + break; + newbottom = MIN(bottom - (_spritesHeights[source] * i), _spritesHeights[source] - 1); + _vm->_video->drawSprite(_bigSpritesParts[source][i-1], dest, left, + topS - (_spritesHeights[source] * i), right, newbottom, x, y, transp); + yS += newbottom - (topS - (_spritesHeights[source] * i)) + 1; + topS += newbottom - (topS - (_spritesHeights[source] * i)) + 1; + } +} + +void Draw::drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, + int16 transp, Video::SurfaceDesc *dest, Video::FontDesc *font) { + while(*str != '\0') { + _vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest); + if (font->extraData == 0) + x += font->itemWidth; + else + x += *(((char *)font->extraData) + (*str - font->startItem)); + str++; + } +} + +void Draw::printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, + int16 bottom, char *str, int16 fontIndex, int16 color) { + char *storedIP; + int i; + int length; + int16 width; + + adjustCoords(1, &left, &top); + adjustCoords(1, &right, &bottom); + + if (_vm->_game->_totFileData[0x7E] != 0) { + storedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = _vm->_game->_totFileData + 0x7E; + WRITE_VAR(17, (uint32) arg_0); + WRITE_VAR(18, (uint32) left); + WRITE_VAR(19, (uint32) top); + WRITE_VAR(20, (uint32) right-left+1); + WRITE_VAR(21, (uint32) bottom-top+1); + _vm->_inter->funcBlock(0); + _vm->_global->_inter_execPtr = storedIP; + } + + if (str[0] == '\0') + return; + + _transparency = 1; + _destSpriteX = left; + _destSpriteY = top; + _fontIndex = fontIndex; + _frontColor = color; + _textToPrint = str; + width = 0; + if (_fonts[fontIndex]->extraData == 0) + width = strlen(str) * _fonts[fontIndex]->itemWidth; + else { + length = strlen(str); + for (i = 0; i < length; i++) + width += + *(((char*)_fonts[fontIndex]->extraData) + (str[i] - _fonts[_fontIndex]->startItem)); + } + + adjustCoords(1, &width, 0); + _destSpriteX += (right - left + 1 - width) / 2; + + spriteOperation(DRAW_PRINTTEXT); +} + +} // End of namespace Gob diff --git a/engines/gob/draw.h b/engines/gob/draw.h index bf9bf3f212..5dfc231668 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -58,14 +58,12 @@ public: int16 _renderFlags; int16 _backDeltaX; int16 _backDeltaY; - Video::FontDesc *_fonts[4]; + Video::FontDesc *_fonts[8]; char *_textToPrint; int16 _transparency; Video::SurfaceDesc *_spritesArray[50]; - Video::SurfaceDesc *_sprites1[50]; - Video::SurfaceDesc *_sprites2[50]; - Video::SurfaceDesc *_sprites3[50]; - uint16 _spritesWidths[50]; + Video::SurfaceDesc *_bigSpritesParts[50][3]; + uint16 _spritesHeights[50]; int16 _invalidatedCount; int16 _invalidatedTops[30]; @@ -108,6 +106,8 @@ public: int16 _palLoadData1[4]; int16 _palLoadData2[4]; + int16 _word_2E8E2; + void invalidateRect(int16 left, int16 top, int16 right, int16 bottom); void blitInvalidated(void); void setPalette(void); @@ -117,8 +117,20 @@ public: void animateCursor(int16 cursor); void freeSprite(int16 index); - void adjustCoords(int16 *coord1, int16 *coord2, char adjust); - void initBigSprite(int16 index, int16 height, int16 width, int16 flags); + void adjustCoords(char adjust, int16 *coord1, int16 *coord2); + void initBigSprite(int16 index, int16 width, int16 height, int16 flags); + void fillRect(int16 index, int16 left, int16 top, int16 right, + int16 bottom, int16 color); + void drawSprite(int16 source, int16 dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); + void drawSprite(Video::SurfaceDesc * source, int16 dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); + void drawSprite(int16 source, Video::SurfaceDesc * dest, int16 left, + int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); + void drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, + int16 transp, Video::SurfaceDesc *dest, Video::FontDesc *font); + void printTextCentered(int16 arg_0, int16 left, int16 top, int16 right, + int16 bottom, char *str, int16 fontIndex, int16 color); virtual void printText(void) = 0; virtual void spriteOperation(int16 operation) = 0; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 74039c9b2b..34ee703572 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -39,25 +39,385 @@ Draw_v2::Draw_v2(GobEngine *vm) : Draw_v1(vm) { } void Draw_v2::printText(void) { -/* - int16 savedFlags; - int16 ldestSpriteX; + int i; char *dataPtr; char *ptr; char *ptr2; + char mask[80]; + char str[80]; + char buf[50]; + char cmd; + int16 savedFlags; int16 destX; int16 destY; - char cmd; + int16 spriteRight; + int16 spriteBottom; int16 val; - char buf[20]; -*/ int16 index; - warning("GOB2 Stub! Draw_v2::printText()"); + int16 rectLeft; + int16 rectTop; + int16 rectRight; + int16 rectBottom; + int16 fontIndex; + int16 strPos; // si + int16 frontColor; + int16 colId; + int16 strPos2; + int16 offX; + int16 offY; + int16 extraCmd; + int16 strPosBak; + int16 maskChar; + int16 width; index = _vm->_inter->load16(); _vm->_cdrom->playMultMusic(); + if (_vm->_game->_totTextData == 0) + return; + + dataPtr = (char *)_vm->_game->_totTextData + _vm->_game->_totTextData->items[index].offset; + ptr = dataPtr; + + if ((_renderFlags & 0x400) && (ptr[1] & 0x80)) + return; + + if (_renderFlags & RENDERFLAG_CAPTUREPUSH) { + _destSpriteX = READ_LE_UINT16(ptr) & 0x7FFF; + _destSpriteY = READ_LE_UINT16(ptr + 2); + _spriteRight = READ_LE_UINT16(ptr + 4) - _destSpriteX + 1; + _spriteBottom = READ_LE_UINT16(ptr + 6) - _destSpriteY + 1; + _vm->_game->capturePush(_destSpriteX, _destSpriteY, + _spriteRight, _spriteBottom); + (*_vm->_scenery->_pCaptureCounter)++; + } + + _destSpriteX = READ_LE_UINT16(ptr) & 0x7FFF; + destX = _destSpriteX; + + _destSpriteY = READ_LE_UINT16(ptr + 2); + destY = _destSpriteY; + + _spriteRight = READ_LE_UINT16(ptr + 4); + spriteRight = _spriteRight; + + _spriteBottom = READ_LE_UINT16(ptr + 6); + spriteBottom = _spriteBottom; + + _destSurface = 21; + + ptr += 8; + + _backColor = *ptr++; + _transparency = 1; + + spriteOperation(DRAW_CLEARRECT); + + _backColor = 0; + + savedFlags = _renderFlags; + _renderFlags &= ~RENDERFLAG_NOINVALIDATE; + + for (; (_destSpriteX = READ_LE_UINT16(ptr)) != -1; ptr++) { + _destSpriteX += destX; + _destSpriteY = READ_LE_UINT16(ptr + 2) + destY; + _spriteRight = READ_LE_UINT16(ptr + 4) + destX; + _spriteBottom = READ_LE_UINT16(ptr + 6) + destY; + ptr += 8; + + cmd = (*ptr & 0xf0) >> 4; + if (cmd == 0) { + _frontColor = *ptr & 0xf; + spriteOperation(DRAW_DRAWLINE); + } else if (cmd == 1) { + _frontColor = *ptr & 0xf; + spriteOperation(DRAW_DRAWBAR); + } else if (cmd == 2) { + _backColor = *ptr & 0xf; + spriteOperation(DRAW_FILLRECTABS); + } + } + ptr += 2; + + for (ptr2 = ptr; *ptr2 != 1; ptr2++) { + if ((_vm->_game->_totFileData[0x29] < 0x32) && (*ptr2 > 3) && (*ptr2 < 32)) + *ptr2 = 32; + + switch(*ptr2) { + case 1: + break; + + case 2: + case 5: + ptr2 += 5; + break; + + case 3: + case 4: + ptr2 += 2; + break; + + case 6: + ptr2++; + switch (*ptr & 0xC0) { + case 0x40: + ptr2 += 9; + break; + case 0x80: + ptr2 += 3; + break; + case 0xC0: + ptr2 += 11; + break; + default: + ptr2++; + break; + } + break; + + case 10: + ptr2 += (ptr2[1] * 2) + 2; + break; + + default: + ptr2++; + break; + } + } + + ptr2++; + + fontIndex = 0; + strPos = 0; + extraCmd = 0; + frontColor = 0; + colId = 0; + offX = 0; + offY = 0; + strPos2 = -1; + memset(mask, 0, 80); + memset(str, ' ', 80); + maskChar = 0; + _backColor = 0; + _transparency = 1; + + while(true) { + if ((*ptr >= 1) && ((*ptr <= 7) || (*ptr == 10)) && (strPos != 0)) { + str[MAX(strPos, strPos2)] = 0; + strPosBak = strPos; + width = strlen(str) * _fonts[fontIndex]->itemWidth; + adjustCoords(1, &width, 0); + if (extraCmd & 0x0F) { + rectLeft = offX - 2; + rectTop = offY - 2; + rectRight = offX + width + 1; + rectBottom = _fonts[fontIndex]->itemHeight; + adjustCoords(1, &rectBottom, 0); + rectBottom += offY + 1; + adjustCoords(0, &rectLeft, &rectTop); + adjustCoords(2, &rectRight, &rectBottom); + if (colId != -1) + _vm->_game->addNewCollision(colId & 0x0D000, rectLeft, rectTop, + rectRight, rectBottom, 2, 0, 0, 0); + if (_word_2E8E2 != 2) + printTextCentered(extraCmd & 0x0F, rectLeft + 4, rectTop + 4, + rectRight - 4, rectBottom - 4, str, fontIndex, frontColor); + else + printTextCentered(extraCmd & 0x0F, rectLeft + 2, rectTop + 2, + rectRight - 2, rectBottom - 2, str, fontIndex, frontColor); + } else { + _destSpriteX = offX; + _destSpriteY = offY; + _fontIndex = fontIndex; + _frontColor = frontColor; + _textToPrint = str; + if (_word_2E8E2 != 2) { + if ((_destSpriteX >= destX) && (_destSpriteY >= destY)) { + if (((_fonts[_fontIndex]->itemHeight / 2) + _destSpriteY - 1) <= spriteBottom) { + while (((_destSpriteX + width - 1) > spriteRight) && (width > 0)) { + width -= _fonts[_fontIndex]->itemWidth / 2; + str[strlen(str) - 1] = '\0'; + } + spriteOperation(DRAW_PRINTTEXT); + } + } + } else + spriteOperation(DRAW_PRINTTEXT); + width = strlen(str); + for (strPos = 0; strPos < width; strPos++) { + if (mask[strPos] == '\0') continue; + rectLeft = _fonts[fontIndex]->itemWidth; + rectTop = _fonts[fontIndex]->itemHeight; + adjustCoords(1, &rectLeft, &rectTop); + _destSpriteX = strPos * rectLeft + offX; + _spriteRight = _destSpriteX + rectLeft - 1; + _spriteBottom = offY + rectTop; + _destSpriteY = _spriteBottom; + spriteOperation(DRAW_DRAWLINE); + } + } + rectLeft = _fonts[_fontIndex]->itemWidth; + adjustCoords(1, &rectLeft, 0); + offX += strPosBak * rectLeft; + strPos = 0; + strPos2 = -1; + memset(mask, 0, 80); + memset(str, ' ', 80); + } + + if (*ptr == 1) + break; + + cmd = *ptr; + switch ((uint8) cmd) { + case 2: + case 5: + ptr++; + offX = destX + (int16)READ_LE_UINT16(ptr); + offY = destY + (int16)READ_LE_UINT16(ptr + 2); + ptr += 4; + break; + + case 3: + ptr++; + fontIndex = ((*ptr & 0xF0) >> 4) & 7; + frontColor = *ptr & 0x0F; + ptr++; + break; + + case 4: + ptr++; + frontColor = *ptr++; + break; + + case 6: + ptr++; + extraCmd = *ptr++; + colId = -1; + if (extraCmd & 0x80) { + colId = (int16)READ_LE_UINT16(ptr); + ptr += 2; + } + if (extraCmd & 0x40) { + rectLeft = destX + (int16)READ_LE_UINT16(ptr); + rectRight = destX + (int16)READ_LE_UINT16(ptr + 2); + rectTop = destY + (int16)READ_LE_UINT16(ptr + 4); + rectBottom = destY + (int16)READ_LE_UINT16(ptr + 6); + adjustCoords(2, &rectLeft, &rectTop); + adjustCoords(2, &rectRight, &rectBottom); + _vm->_game->addNewCollision(colId & 0x0D000, rectLeft, rectTop, + rectRight, rectBottom, 2, 0, 0, 0); + ptr += 8; + } + break; + + case 7: + ptr++; + extraCmd = 0; + break; + + case 8: + ptr++; + maskChar = 1; + break; + + case 9: + ptr++; + maskChar = 0; + break; + + case 10: + // loc_12C93 + warning("GOB2 Stub! Draw_v2::printText: cmd == 10"); +/* +WTF: + mov ax, word ptr [bp+ptr] + xor dx, dx + sub ax, word ptr _game_totTextData + sbb dx, 0 +*/ + ptr++; + i = *ptr++; + for (i = *ptr++; i > 0; i--) { + mask[strPos++] = maskChar; + ptr += 2; + } + break; + + default: + str[strPos] = cmd; + case 32: + mask[strPos++] = maskChar; + ptr++; + break; + + case 186: + cmd = ptr2[17] & 0x7f; + if (cmd == 0) { + val = READ_LE_UINT16(ptr2 + 18) * 4; + sprintf(buf, "%d", VAR_OFFSET(val)); + } else if(cmd == 1) { + val = READ_LE_UINT16(ptr2 + 18) * 4; + strcpy(buf, _vm->_global->_inter_variables + val); + } else { + val = READ_LE_UINT16(ptr2 + 18) * 4; + sprintf(buf, "%d", VAR_OFFSET(val)); + if (buf[0] == '-') { + while (strlen(buf) - 1 < (uint32)ptr2[17]) { + _vm->_util->insertStr("0", buf, 1); + } + } else { + while (strlen(buf) - 1 < (uint32)ptr2[17]) { + _vm->_util->insertStr("0", buf, 0); + } + } + if (_vm->_global->_language == 2) + _vm->_util->insertStr(".", buf, strlen(buf) + 1 - ptr2[17]); + else + _vm->_util->insertStr(",", buf, strlen(buf) + 1 - ptr2[17]); + } + memcpy(str + strPos, buf, strlen(buf)); + memset(mask, maskChar, strlen(buf)); + if (ptr2[17] & 0x80) { + strPos2 = strPos + strlen(buf); + strPos++; + ptr2 += 23; + ptr++; + } else { + strPos += strlen(buf); + if (ptr[1] != ' ') { + if ((ptr[1] == 2) && (((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) { + ptr += 5; + str[strPos] = ' '; + mask[strPos++] = maskChar; + } + } else { + str[strPos] = ' '; + mask[strPos++] = maskChar; + while (ptr[1] == ' ') + ptr++; + if ((ptr[1] == 2) && (((int16)READ_LE_UINT16(ptr + 4)) == _destSpriteY)) + ptr += 5; + } + ptr2 += 23; + ptr++; + } + break; + } + } + + _renderFlags = savedFlags; + if (!(_renderFlags & 4)) + return; + + _vm->_game->checkCollisions(0, 0, 0, 0); + + if (*_vm->_scenery->_pCaptureCounter != 0) { + (*_vm->_scenery->_pCaptureCounter)--; + _vm->_game->capturePop(1); + } + return; } @@ -71,6 +431,29 @@ void Draw_v2::spriteOperation(int16 operation) { int16 x; int16 y; int16 perLine; + Video::SurfaceDesc *sourceSurf; + Video::SurfaceDesc *destSurf; + bool deltaveto; + int16 left; + int16 ratio; + int16 spriteLeft; + int16 spriteTop; + int16 spriteRight; + int16 spriteBottom; + int16 destSpriteX; + int16 destSpriteY; + int16 destSurface; + int16 sourceSurface; +// .--- + Video::SurfaceDesc *off_2E51B = 0; + int8 word_2F2D2 = -1; +// '--- + + if (operation & 0x10) { + deltaveto = true; + operation &= 0x0F; + } else + deltaveto = false; if (_sourceSurface >= 100) _sourceSurface -= 80; @@ -78,8 +461,8 @@ void Draw_v2::spriteOperation(int16 operation) { if (_destSurface >= 100) _destSurface -= 80; - if (_renderFlags & RENDERFLAG_USEDELTAS) { - if (_sourceSurface == 21) { + if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaveto) { + if ((_sourceSurface == 21) && (operation != DRAW_LOADSPRITE)) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } @@ -96,14 +479,96 @@ void Draw_v2::spriteOperation(int16 operation) { } } + spriteLeft = _spriteLeft; + spriteTop = _spriteTop; + spriteRight = _spriteRight; + spriteBottom = _spriteLeft; + destSpriteX = _destSpriteX; + destSpriteY = _destSpriteY; + destSurface = _destSurface; + sourceSurface = _sourceSurface; + +// warning("GOB2 Stub! off_2E51B"); + if (off_2E51B != 0) { + if ((_frontSurface->height <= _destSpriteY) && + ((_destSurface == 20) || (_destSurface == 21))) { + _destSpriteY -= _frontSurface->height; + if (operation == DRAW_DRAWLINE || + (operation >= DRAW_DRAWBAR + && operation <= DRAW_FILLRECTABS)) { + _spriteBottom -= _frontSurface->height; + } + if (_destSurface == 21) + invalidateRect(0, _frontSurface->height, 319, _frontSurface->height+off_2E51B->height-1); + destSurface += 4; + } + if ((_frontSurface->height <= _spriteTop) && (operation == DRAW_BLITSURF) + && ((_destSurface == 20) || (_destSurface == 21))) { + _spriteTop -= _frontSurface->height; + _sourceSurface += 4; + } + } + + adjustCoords(0, &_destSpriteX, &_destSpriteY); + if ((operation != DRAW_LOADSPRITE) && (_word_2E8E2 != 2)) { + adjustCoords(0, &_spriteRight, &_spriteBottom); + adjustCoords(0, &_spriteLeft, &_spriteTop); + if (operation == DRAW_DRAWLETTER) + operation = DRAW_BLITSURF; + if ((operation == DRAW_DRAWLINE) && + ((_spriteRight == _destSpriteX) || (_spriteBottom == _destSpriteY))) { + operation = DRAW_FILLRECTABS; + _backColor = _frontColor; + } + if (operation == DRAW_DRAWLINE) { + if (_spriteBottom < _destSpriteY) { + SWAP(_spriteBottom, _destSpriteY); + SWAP(_spriteRight, _destSpriteX); + } + } else if ((operation == DRAW_LOADSPRITE) || (operation > DRAW_PRINTTEXT)) { + if (_spriteBottom < _destSpriteY) + SWAP(_spriteBottom, _destSpriteY); + if (_spriteRight < _destSpriteX) + SWAP(_spriteRight, _destSpriteX); + _spriteRight++; + _spriteBottom++; + } + } + + sourceSurf = _spritesArray[_sourceSurface]; + destSurf = _spritesArray[_destSurface]; + switch (operation) { case DRAW_BLITSURF: - _vm->_video->drawSprite(_spritesArray[_sourceSurface], - _spritesArray[_destSurface], - _spriteLeft, _spriteTop, - _spriteLeft + _spriteRight - 1, - _spriteTop + _spriteBottom - 1, - _destSpriteX, _destSpriteY, _transparency); + case DRAW_DRAWLETTER: + if ((sourceSurf == 0) || (destSurf == 0)) + break; + + if ((sourceSurf->vidMode & 0x80) && (destSurf->vidMode & 0x80)) + _vm->_video->drawSprite(_spritesArray[_sourceSurface], + _spritesArray[_destSurface], + _spriteLeft, _spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); + else if (!(sourceSurf->vidMode & 0x80) && (destSurf->vidMode & 0x80)) + drawSprite(_sourceSurface, _spritesArray[_destSurface], + _spriteLeft, spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); + else if ((sourceSurf->vidMode & 0x80) && !(destSurf->vidMode & 0x80)) + drawSprite(_spritesArray[_sourceSurface], _destSurface, + _spriteLeft, spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); + else + drawSprite(_sourceSurface, _destSurface, + _spriteLeft, _spriteTop, + _spriteLeft + _spriteRight - 1, + _spriteTop + _spriteBottom - 1, + _destSpriteX, _destSpriteY, _transparency); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, @@ -122,10 +587,9 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_FILLRECT: - _vm->_video->fillRect(_spritesArray[_destSurface], - _destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1, _backColor); + fillRect(_destSurface, destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, + _destSpriteY + _spriteBottom - 1, _backColor); if (_destSurface == 21) { invalidateRect(_destSpriteX, _destSpriteY, @@ -146,6 +610,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_INVALIDATE: + _vm->_video->drawCircle(_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _frontColor); if (_destSurface == 21) { invalidateRect(_destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, // !! _destSpriteX + _spriteRight, @@ -201,25 +666,72 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_PRINTTEXT: - break; len = strlen(_textToPrint); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + - len * _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + - _fonts[_fontIndex]->itemHeight - 1); + left = _destSpriteX; + if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) { + if (_fonts[_fontIndex]->extraData == 0) { + if (((signed) _textToPrint[0]) == -1) { + dataBuf = (char*)_vm->_game->_totTextData + _textToPrint[1] + 1; + len = *dataBuf++; + for (i = 0; i < len; i++) { + _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, + _destSpriteY, _fonts[_fontIndex], _transparency, _frontColor, + _backColor, _spritesArray[_destSurface]); + dataBuf += 2; + } + } else { + drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, + _backColor, _transparency, _spritesArray[_destSurface], + _fonts[_fontIndex]); + _destSpriteX += len * _fonts[_fontIndex]->itemWidth; + } + } else { + if (word_2F2D2 >= 0) { + for (i = 0; i < len; i++) { + _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, + _destSpriteY, _fonts[_fontIndex], _transparency, + _frontColor, _backColor, _spritesArray[_destSurface]); + _destSpriteX += + *(((char*)_fonts[_fontIndex]->extraData) + (_textToPrint[i] - _fonts[_fontIndex]->startItem)); + } + } else { // loc_DBE9 + warning("Untested, does that work?"); + // Does something different for each character depending on whether it's a space + // That *should* be it... + for (i = 0; i < len; i++) { + if (_textToPrint[i] == ' ') + _destSpriteX += _fonts[_fontIndex]->itemWidth; + else { + _vm->_video->drawLetter(_textToPrint[i], + _destSpriteX, _destSpriteY, + _fonts[_fontIndex], + _transparency, + _frontColor, _backColor, + _spritesArray[_destSurface]); + _destSpriteX += + *(((char*)_fonts[_fontIndex]->extraData) + (_textToPrint[i] - _fonts[_fontIndex]->startItem)); + } + } + } + } + } else { + for (i = 0; i < len; i++) { + ratio = _spritesArray[_fontToSprite[_fontIndex].sprite]->width / _fontToSprite[_fontIndex].width; + x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) / ratio) * _fontToSprite[_fontIndex].height; + y = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) / ratio) * _fontToSprite[_fontIndex].width; + _vm->_video->drawSprite(_spritesArray[_fontToSprite[_fontIndex].sprite], + _spritesArray[_destSurface], x, y, + x + _fontToSprite[_fontIndex].width - 1, + y + _fontToSprite[_fontIndex].height - 1, + _destSpriteX, _destSpriteY, _transparency); + _destSpriteX += _fontToSprite[_fontIndex].width; + } } - for (i = 0; i < len; i++) { - _vm->_video->drawLetter(_textToPrint[i], - _destSpriteX, _destSpriteY, - _fonts[_fontIndex], - _transparency, - _frontColor, _backColor, - _spritesArray[_destSurface]); - - _destSpriteX += _fonts[_fontIndex]->itemWidth; + if (_destSurface == 21) { + invalidateRect(left, _destSpriteY, + _destSpriteX - 1, + _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); } break; @@ -270,27 +782,6 @@ void Draw_v2::spriteOperation(int16 operation) { } break; - case DRAW_DRAWLETTER: - break; - if (_fontToSprite[_fontIndex].sprite == -1) { - if (_destSurface == 21) { - invalidateRect(_destSpriteX, - _destSpriteY, - _destSpriteX + - _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + - _fonts[_fontIndex]->itemHeight - - 1); - } - _vm->_video->drawLetter(_letterToPrint, - _destSpriteX, _destSpriteY, - _fonts[_fontIndex], - _transparency, - _frontColor, _backColor, - _spritesArray[_destSurface]); - break; - } - perLine = _spritesArray[(int16)_fontToSprite[_fontIndex]. sprite]->width / _fontToSprite[_fontIndex].width; @@ -321,7 +812,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; } - if (_renderFlags & RENDERFLAG_USEDELTAS) { + if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaveto) { if (_sourceSurface == 21) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index c3c47be306..3bdf9bc2c0 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -191,44 +191,6 @@ char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight) { } -void Game::clearCollisions() { - int16 i; - for (i = 0; i < 250; i++) { - _collisionAreas[i].id = 0; - _collisionAreas[i].left = -1; - } -} - -void Game::addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, - int16 flags, int16 key, int16 funcEnter, int16 funcLeave) { - int16 i; - Collision *ptr; - - debugC(5, DEBUG_COLLISIONS, "addNewCollision"); - debugC(5, DEBUG_COLLISIONS, "id = %x", id); - debugC(5, DEBUG_COLLISIONS, "left = %d, top = %d, right = %d, bottom = %d", left, top, right, bottom); - debugC(5, DEBUG_COLLISIONS, "flags = %x, key = %x", flags, key); - debugC(5, DEBUG_COLLISIONS, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave); - - for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left != -1) - continue; - - ptr = &_collisionAreas[i]; - ptr->id = id; - ptr->left = left; - ptr->top = top; - ptr->right = right; - ptr->bottom = bottom; - ptr->flags = flags; - ptr->key = key; - ptr->funcEnter = funcEnter; - ptr->funcLeave = funcLeave; - return; - } - error("addNewCollision: Collision array full!\n"); -} - void Game::freeCollision(int16 id) { int16 i; @@ -1726,213 +1688,6 @@ void Game::loadImFile(void) { _imFileData = _vm->_dataio->getData(path); } -void Game::playTot(int16 skipPlay) { - char savedTotName[20]; - int16 *oldCaptureCounter; - int16 *oldBreakFrom; - int16 *oldNestLevel; - int16 _captureCounter; - int16 breakFrom; - int16 nestLevel; - char needTextFree; - char needFreeResTable; - char *curPtr; - int32 variablesCount; - char *filePtr; - char *savedIP; - int16 i; - - oldNestLevel = _vm->_inter->_nestLevel; - oldBreakFrom = _vm->_inter->_breakFromLevel; - oldCaptureCounter = _vm->_scenery->_pCaptureCounter; - savedIP = _vm->_global->_inter_execPtr; - - _vm->_inter->_nestLevel = &nestLevel; - _vm->_inter->_breakFromLevel = &breakFrom; - _vm->_scenery->_pCaptureCounter = &_captureCounter; - strcpy(savedTotName, _curTotFile); - - if (skipPlay == 0) { - while (1) { - for (i = 0; i < 4; i++) { - _vm->_draw->_fontToSprite[i].sprite = -1; - _vm->_draw->_fontToSprite[i].base = -1; - _vm->_draw->_fontToSprite[i].width = -1; - _vm->_draw->_fontToSprite[i].height = -1; - } - - if(_vm->_features & GF_MAC) - _vm->_music->stopPlay(); - else - _vm->_cdrom->stopPlaying(); - _vm->_draw->animateCursor(4); - _vm->_inter->initControlVars(); - _vm->_mult->initAll(); - _vm->_mult->zeroMultData(); - - for (i = 0; i < 20; i++) - _vm->_draw->_spritesArray[i] = 0; - - _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; - _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; - _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; - - for (i = 0; i < 20; i++) - _soundSamples[i] = 0; - - _totTextData = 0; - _totResourceTable = 0; - _imFileData = 0; - _extTable = 0; - _extHandle = -1; - - needFreeResTable = 1; - needTextFree = 1; - - _totToLoad[0] = 0; - - if (_curTotFile[0] == 0 && _totFileData == 0) - break; - - loadTotFile(_curTotFile); - if (_totFileData == 0) { - _vm->_draw->blitCursor(); - break; - } - - strcpy(_curImaFile, _curTotFile); - strcpy(_curExtFile, _curTotFile); - - _curImaFile[strlen(_curImaFile) - 4] = 0; - strcat(_curImaFile, ".ima"); - - _curExtFile[strlen(_curExtFile) - 4] = 0; - strcat(_curExtFile, ".ext"); - - debugC(4, DEBUG_FILEIO, "IMA: %s", _curImaFile); - debugC(4, DEBUG_FILEIO, "EXT: %s", _curExtFile); - - filePtr = (char *)_totFileData + 0x30; - - if (READ_LE_UINT32(filePtr) != (uint32)-1) { - curPtr = _totFileData; - _totTextData = - (TotTextTable *) (curPtr + - READ_LE_UINT32((char *)_totFileData + 0x30)); - - _totTextData->itemsCount = (int16)READ_LE_UINT16(&_totTextData->itemsCount); - - for (i = 0; i < _totTextData->itemsCount; ++i) { - _totTextData->items[i].offset = (int16)READ_LE_UINT16(&_totTextData->items[i].offset); - _totTextData->items[i].size = (int16)READ_LE_UINT16(&_totTextData->items[i].size); - } - - needTextFree = 0; - } - - filePtr = (char *)_totFileData + 0x34; - if (READ_LE_UINT32(filePtr) != (uint32)-1) { - curPtr = _totFileData; - - _totResourceTable = - (TotResTable *)(curPtr + - READ_LE_UINT32((char *)_totFileData + 0x34)); - - _totResourceTable->itemsCount = (int16)READ_LE_UINT16(&_totResourceTable->itemsCount); - - for (i = 0; i < _totResourceTable->itemsCount; ++i) { - _totResourceTable->items[i].offset = (int32)READ_LE_UINT32(&_totResourceTable->items[i].offset); - _totResourceTable->items[i].size = (int16)READ_LE_UINT16(&_totResourceTable->items[i].size); - _totResourceTable->items[i].width = (int16)READ_LE_UINT16(&_totResourceTable->items[i].width); - _totResourceTable->items[i].height = (int16)READ_LE_UINT16(&_totResourceTable->items[i].height); - } - - needFreeResTable = 0; - } - - loadImFile(); - loadExtTable(); - - _vm->_global->_inter_animDataSize = READ_LE_UINT16((char *)_totFileData + 0x38); - if (_vm->_global->_inter_variables == 0) { - variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); - _vm->_global->_inter_variables = new char[variablesCount * 4]; - for (i = 0; i < variablesCount; i++) - WRITE_VAR(i, 0); - } - - _vm->_global->_inter_execPtr = (char *)_totFileData; - _vm->_global->_inter_execPtr += READ_LE_UINT32((char *)_totFileData + 0x64); - - _vm->_inter->renewTimeInVars(); - - WRITE_VAR(13, _vm->_global->_useMouse); - WRITE_VAR(14, _vm->_global->_soundFlags); - WRITE_VAR(15, _vm->_global->_videoMode); - WRITE_VAR(16, _vm->_global->_language); - - _vm->_inter->callSub(2); - - if (_totToLoad[0] != 0) - _vm->_inter->_terminate = false; - - variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); - _vm->_draw->blitInvalidated(); - delete[] _totFileData; - _totFileData = 0; - - if (needTextFree) - delete[] _totTextData; - _totTextData = 0; - - if (needFreeResTable) - delete[] _totResourceTable; - _totResourceTable = 0; - - delete[] _imFileData; - _imFileData = 0; - - if (_extTable) - delete[] _extTable->items; - delete _extTable; - _extTable = 0; - - if (_extHandle >= 0) - _vm->_dataio->closeData(_extHandle); - - _extHandle = -1; - - for (i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) - capturePop(0); - - _vm->_mult->checkFreeMult(); - _vm->_mult->freeAll(); - - for (i = 0; i < 20; i++) { - if (_vm->_draw->_spritesArray[i] != 0) - _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); - _vm->_draw->_spritesArray[i] = 0; - } - _vm->_snd->stopSound(0); - - for (i = 0; i < 20; i++) - freeSoundSlot(i); - - if (_totToLoad[0] == 0) - break; - - strcpy(_curTotFile, _totToLoad); - } - } - - strcpy(_curTotFile, savedTotName); - - _vm->_inter->_nestLevel = oldNestLevel; - _vm->_inter->_breakFromLevel = oldBreakFrom; - _vm->_scenery->_pCaptureCounter = oldCaptureCounter; - _vm->_global->_inter_execPtr = savedIP; -} - void Game::start(void) { _collisionAreas = new Collision[250]; prepareStart(); @@ -2014,4 +1769,48 @@ void Game::totSub(int8 flags, char *newTotFile) { strcat(_curExtFile, ".EXT"); } +char *Game::loadLocTexts(void) { + char locTextFile[20]; + int16 handle; + + strcpy(locTextFile, _curTotFile); + locTextFile[strlen(locTextFile) - 4] = 0; + switch (_vm->_global->_language) { + case 0: + strcat(locTextFile, ".dat"); + break; + case 1: + strcat(locTextFile, ".all"); + break; + case 3: + strcat(locTextFile, ".esp"); + break; + case 4: + strcat(locTextFile, ".ita"); + break; + case 5: + strcat(locTextFile, ".usa"); + break; + case 6: + strcat(locTextFile, ".ndl"); + break; + case 7: + strcat(locTextFile, ".kor"); + break; + case 8: + strcat(locTextFile, ".isr"); + break; + default: + strcat(locTextFile, ".ang"); + break; + } + + handle = _vm->_dataio->openData(locTextFile); + if (handle >= 0) { + _vm->_dataio->closeData(handle); + return _vm->_dataio->getData(locTextFile); + } + return 0; +} + } // End of namespace Gob diff --git a/engines/gob/game.h b/engines/gob/game.h index 2e13d229d2..713051cc86 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -31,7 +31,6 @@ class Game { public: #pragma START_PACK_STRUCTS -#define szGame_TotResItem (4 + 2 + 2 + 2) struct Collision { int16 id; int16 left; @@ -42,8 +41,10 @@ public: int16 key; int16 funcEnter; int16 funcLeave; + int16 field_12; // New in GOB2 } GCC_PACK; +#define szGame_TotResItem (4 + 2 + 2 + 2) struct TotResItem { int32 offset; // if > 0, then offset from end of resource table. // If < 0, then -offset-1 is index in .IM file table @@ -132,6 +133,7 @@ public: char _curTotFileArray[5][14]; Game(GobEngine *vm); + virtual ~Game() {}; char *loadExtData(int16 dataId, int16 *pResWidth, int16 *pResHeight); char *loadTotResource(int16 id); @@ -144,9 +146,6 @@ public: char handleMouse); int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId, int16 *pResIndex); - void clearCollisions(void); - void addNewCollision(int16 val_0, int16 left, int16 top, int16 right, int16 bottom, - int16 flags, int16 key, int16 val_E, int16 val_10); void freeCollision(int16 id); void loadSound(int16 slot, char *dataPtr); @@ -160,9 +159,14 @@ public: void loadTotFile(char *path); void loadExtTable(void); void loadImFile(void); - void playTot(int16 skipPlay); void start(void); void totSub(int8 flags, char *newTotFile); + char *loadLocTexts(void); + + virtual void playTot(int16 skipPlay) = 0; + virtual void clearCollisions(void) = 0; + virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, + int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave) = 0; protected: @@ -198,6 +202,28 @@ protected: int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex); }; +class Game_v1 : public Game { +public: + virtual void playTot(int16 skipPlay); + virtual void clearCollisions(void); + virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, + int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave); + + Game_v1(GobEngine *vm); + virtual ~Game_v1() {}; +}; + +class Game_v2 : public Game_v1 { +public: + virtual void playTot(int16 skipPlay); + virtual void clearCollisions(void); + virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right, + int16 bottom, int16 flags, int16 key, int16 funcEnter, int16 funcLeave); + + Game_v2(GobEngine *vm); + virtual ~Game_v2() {}; +}; + } // End of namespace Gob #endif diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp new file mode 100644 index 0000000000..2050fae242 --- /dev/null +++ b/engines/gob/game_v1.cpp @@ -0,0 +1,293 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/global.h" +#include "gob/game.h" +#include "gob/video.h" +#include "gob/dataio.h" +#include "gob/pack.h" +#include "gob/scenery.h" +#include "gob/inter.h" +#include "gob/parse.h" +#include "gob/draw.h" +#include "gob/mult.h" +#include "gob/util.h" +#include "gob/goblin.h" +#include "gob/cdrom.h" +#include "gob/music.h" + +namespace Gob { + +Game_v1::Game_v1(GobEngine *vm) : Game(vm) { +} + +void Game_v1::playTot(int16 skipPlay) { + char savedTotName[20]; + int16 *oldCaptureCounter; + int16 *oldBreakFrom; + int16 *oldNestLevel; + int16 _captureCounter; + int16 breakFrom; + int16 nestLevel; + char needTextFree; + char needFreeResTable; + char *curPtr; + int32 variablesCount; + char *filePtr; + char *savedIP; + int16 i; + + oldNestLevel = _vm->_inter->_nestLevel; + oldBreakFrom = _vm->_inter->_breakFromLevel; + oldCaptureCounter = _vm->_scenery->_pCaptureCounter; + savedIP = _vm->_global->_inter_execPtr; + + _vm->_inter->_nestLevel = &nestLevel; + _vm->_inter->_breakFromLevel = &breakFrom; + _vm->_scenery->_pCaptureCounter = &_captureCounter; + strcpy(savedTotName, _curTotFile); + + if (skipPlay == 0) { + while (1) { + for (i = 0; i < 4; i++) { + _vm->_draw->_fontToSprite[i].sprite = -1; + _vm->_draw->_fontToSprite[i].base = -1; + _vm->_draw->_fontToSprite[i].width = -1; + _vm->_draw->_fontToSprite[i].height = -1; + } + + if(_vm->_features & GF_MAC) + _vm->_music->stopPlay(); + else + _vm->_cdrom->stopPlaying(); + _vm->_draw->animateCursor(4); + _vm->_inter->initControlVars(); + _vm->_mult->initAll(); + _vm->_mult->zeroMultData(); + + for (i = 0; i < 20; i++) + _vm->_draw->_spritesArray[i] = 0; + + _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; + _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; + _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; + + for (i = 0; i < 20; i++) + _soundSamples[i] = 0; + + _totTextData = 0; + _totResourceTable = 0; + _imFileData = 0; + _extTable = 0; + _extHandle = -1; + + needFreeResTable = 1; + needTextFree = 1; + + _totToLoad[0] = 0; + + if (_curTotFile[0] == 0 && _totFileData == 0) + break; + + loadTotFile(_curTotFile); + if (_totFileData == 0) { + _vm->_draw->blitCursor(); + break; + } + + strcpy(_curImaFile, _curTotFile); + strcpy(_curExtFile, _curTotFile); + + _curImaFile[strlen(_curImaFile) - 4] = 0; + strcat(_curImaFile, ".ima"); + + _curExtFile[strlen(_curExtFile) - 4] = 0; + strcat(_curExtFile, ".ext"); + + debugC(4, DEBUG_FILEIO, "IMA: %s", _curImaFile); + debugC(4, DEBUG_FILEIO, "EXT: %s", _curExtFile); + + filePtr = (char *)_totFileData + 0x30; + + if (READ_LE_UINT32(filePtr) != (uint32)-1) { + curPtr = _totFileData; + _totTextData = + (TotTextTable *) (curPtr + + READ_LE_UINT32((char *)_totFileData + 0x30)); + + _totTextData->itemsCount = (int16)READ_LE_UINT16(&_totTextData->itemsCount); + + for (i = 0; i < _totTextData->itemsCount; ++i) { + _totTextData->items[i].offset = (int16)READ_LE_UINT16(&_totTextData->items[i].offset); + _totTextData->items[i].size = (int16)READ_LE_UINT16(&_totTextData->items[i].size); + } + + needTextFree = 0; + } + + filePtr = (char *)_totFileData + 0x34; + if (READ_LE_UINT32(filePtr) != (uint32)-1) { + curPtr = _totFileData; + + _totResourceTable = + (TotResTable *)(curPtr + + READ_LE_UINT32((char *)_totFileData + 0x34)); + + _totResourceTable->itemsCount = (int16)READ_LE_UINT16(&_totResourceTable->itemsCount); + + for (i = 0; i < _totResourceTable->itemsCount; ++i) { + _totResourceTable->items[i].offset = (int32)READ_LE_UINT32(&_totResourceTable->items[i].offset); + _totResourceTable->items[i].size = (int16)READ_LE_UINT16(&_totResourceTable->items[i].size); + _totResourceTable->items[i].width = (int16)READ_LE_UINT16(&_totResourceTable->items[i].width); + _totResourceTable->items[i].height = (int16)READ_LE_UINT16(&_totResourceTable->items[i].height); + } + + needFreeResTable = 0; + } + + loadImFile(); + loadExtTable(); + + _vm->_global->_inter_animDataSize = READ_LE_UINT16((char *)_totFileData + 0x38); + if (_vm->_global->_inter_variables == 0) { + variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); + _vm->_global->_inter_variables = new char[variablesCount * 4]; + for (i = 0; i < variablesCount; i++) + WRITE_VAR(i, 0); + } + + _vm->_global->_inter_execPtr = (char *)_totFileData; + _vm->_global->_inter_execPtr += READ_LE_UINT32((char *)_totFileData + 0x64); + + _vm->_inter->renewTimeInVars(); + + WRITE_VAR(13, _vm->_global->_useMouse); + WRITE_VAR(14, _vm->_global->_soundFlags); + WRITE_VAR(15, _vm->_global->_videoMode); + WRITE_VAR(16, _vm->_global->_language); + + _vm->_inter->callSub(2); + + if (_totToLoad[0] != 0) + _vm->_inter->_terminate = false; + + variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); + _vm->_draw->blitInvalidated(); + delete[] _totFileData; + _totFileData = 0; + + if (needTextFree) + delete[] _totTextData; + _totTextData = 0; + + if (needFreeResTable) + delete[] _totResourceTable; + _totResourceTable = 0; + + delete[] _imFileData; + _imFileData = 0; + + if (_extTable) + delete[] _extTable->items; + delete _extTable; + _extTable = 0; + + if (_extHandle >= 0) + _vm->_dataio->closeData(_extHandle); + + _extHandle = -1; + + for (i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) + capturePop(0); + + _vm->_mult->checkFreeMult(); + _vm->_mult->freeAll(); + + for (i = 0; i < 20; i++) { + if (_vm->_draw->_spritesArray[i] != 0) + _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); + _vm->_draw->_spritesArray[i] = 0; + } + _vm->_snd->stopSound(0); + + for (i = 0; i < 20; i++) + freeSoundSlot(i); + + if (_totToLoad[0] == 0) + break; + + strcpy(_curTotFile, _totToLoad); + } + } + + strcpy(_curTotFile, savedTotName); + + _vm->_inter->_nestLevel = oldNestLevel; + _vm->_inter->_breakFromLevel = oldBreakFrom; + _vm->_scenery->_pCaptureCounter = oldCaptureCounter; + _vm->_global->_inter_execPtr = savedIP; +} + +void Game_v1::clearCollisions() { + int16 i; + for (i = 0; i < 250; i++) { + _collisionAreas[i].id = 0; + _collisionAreas[i].left = -1; + } +} + +void Game_v1::addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, + int16 flags, int16 key, int16 funcEnter, int16 funcLeave) { + int16 i; + Collision *ptr; + + debugC(5, DEBUG_COLLISIONS, "addNewCollision"); + debugC(5, DEBUG_COLLISIONS, "id = %x", id); + debugC(5, DEBUG_COLLISIONS, "left = %d, top = %d, right = %d, bottom = %d", left, top, right, bottom); + debugC(5, DEBUG_COLLISIONS, "flags = %x, key = %x", flags, key); + debugC(5, DEBUG_COLLISIONS, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave); + + for (i = 0; i < 250; i++) { + if (_collisionAreas[i].left != -1) + continue; + + ptr = &_collisionAreas[i]; + ptr->id = id; + ptr->left = left; + ptr->top = top; + ptr->right = right; + ptr->bottom = bottom; + ptr->flags = flags; + ptr->key = key; + ptr->funcEnter = funcEnter; + ptr->funcLeave = funcLeave; + return; + } + error("addNewCollision: Collision array full!\n"); +} + +} // End of namespace Gob diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp new file mode 100644 index 0000000000..6a47288c0e --- /dev/null +++ b/engines/gob/game_v2.cpp @@ -0,0 +1,302 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/global.h" +#include "gob/game.h" +#include "gob/video.h" +#include "gob/dataio.h" +#include "gob/pack.h" +#include "gob/scenery.h" +#include "gob/inter.h" +#include "gob/parse.h" +#include "gob/draw.h" +#include "gob/mult.h" +#include "gob/util.h" +#include "gob/goblin.h" +#include "gob/cdrom.h" +#include "gob/music.h" + +namespace Gob { + +Game_v2::Game_v2(GobEngine *vm) : Game_v1(vm) { +} + +void Game_v2::playTot(int16 skipPlay) { + char savedTotName[20]; + int16 *oldCaptureCounter; + int16 *oldBreakFrom; + int16 *oldNestLevel; + int16 _captureCounter; + int16 breakFrom; + int16 nestLevel; + char needTextFree; + char needFreeResTable; + char *curPtr; + int32 variablesCount; + char *filePtr; + char *savedIP; + int16 i; + + oldNestLevel = _vm->_inter->_nestLevel; + oldBreakFrom = _vm->_inter->_breakFromLevel; + oldCaptureCounter = _vm->_scenery->_pCaptureCounter; + savedIP = _vm->_global->_inter_execPtr; + + _vm->_inter->_nestLevel = &nestLevel; + _vm->_inter->_breakFromLevel = &breakFrom; + _vm->_scenery->_pCaptureCounter = &_captureCounter; + strcpy(savedTotName, _curTotFile); + + if (skipPlay == 0) { + while (1) { + for (i = 0; i < 4; i++) { + _vm->_draw->_fontToSprite[i].sprite = -1; + _vm->_draw->_fontToSprite[i].base = -1; + _vm->_draw->_fontToSprite[i].width = -1; + _vm->_draw->_fontToSprite[i].height = -1; + } + + if(_vm->_features & GF_MAC) + _vm->_music->stopPlay(); + else + _vm->_cdrom->stopPlaying(); + _vm->_draw->animateCursor(4); + _vm->_inter->initControlVars(); + _vm->_mult->initAll(); + _vm->_mult->zeroMultData(); + + for (i = 0; i < 20; i++) + _vm->_draw->_spritesArray[i] = 0; + + _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; + _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; + _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites; + + for (i = 0; i < 20; i++) + _soundSamples[i] = 0; + + _totTextData = 0; + _totResourceTable = 0; + _imFileData = 0; + _extTable = 0; + _extHandle = -1; + + needFreeResTable = 1; + needTextFree = 1; + + _totToLoad[0] = 0; + + if (_curTotFile[0] == 0 && _totFileData == 0) + break; + + loadTotFile(_curTotFile); + if (_totFileData == 0) { + _vm->_draw->blitCursor(); + break; + } + + strcpy(_curImaFile, _curTotFile); + strcpy(_curExtFile, _curTotFile); + + _curImaFile[strlen(_curImaFile) - 4] = 0; + strcat(_curImaFile, ".ima"); + + _curExtFile[strlen(_curExtFile) - 4] = 0; + strcat(_curExtFile, ".ext"); + + debugC(4, DEBUG_FILEIO, "IMA: %s", _curImaFile); + debugC(4, DEBUG_FILEIO, "EXT: %s", _curExtFile); + + filePtr = (char *)_totFileData + 0x30; + + if (READ_LE_UINT32(filePtr) != (uint32)-1) { + curPtr = _totFileData; + if (READ_LE_UINT32(filePtr) == 0) + _totTextData = (TotTextTable *) loadLocTexts(); + else + _totTextData = + (TotTextTable *) (curPtr + + READ_LE_UINT32((char *)_totFileData + 0x30)); + + if (_totTextData != 0) { + _totTextData->itemsCount = (int16)READ_LE_UINT16(&_totTextData->itemsCount); + + for (i = 0; i < _totTextData->itemsCount; ++i) { + _totTextData->items[i].offset = (int16)READ_LE_UINT16(&_totTextData->items[i].offset); + _totTextData->items[i].size = (int16)READ_LE_UINT16(&_totTextData->items[i].size); + } + } + + needTextFree = 0; + } + + filePtr = (char *)_totFileData + 0x34; + if (READ_LE_UINT32(filePtr) != (uint32)-1) { + curPtr = _totFileData; + + _totResourceTable = + (TotResTable *)(curPtr + + READ_LE_UINT32((char *)_totFileData + 0x34)); + + _totResourceTable->itemsCount = (int16)READ_LE_UINT16(&_totResourceTable->itemsCount); + + for (i = 0; i < _totResourceTable->itemsCount; ++i) { + _totResourceTable->items[i].offset = (int32)READ_LE_UINT32(&_totResourceTable->items[i].offset); + _totResourceTable->items[i].size = (int16)READ_LE_UINT16(&_totResourceTable->items[i].size); + _totResourceTable->items[i].width = (int16)READ_LE_UINT16(&_totResourceTable->items[i].width); + _totResourceTable->items[i].height = (int16)READ_LE_UINT16(&_totResourceTable->items[i].height); + } + + needFreeResTable = 0; + } + + loadImFile(); + loadExtTable(); + + _vm->_global->_inter_animDataSize = READ_LE_UINT16((char *)_totFileData + 0x38); + if (_vm->_global->_inter_variables == 0) { + variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); + _vm->_global->_inter_variables = new char[variablesCount * 4]; + for (i = 0; i < variablesCount; i++) + WRITE_VAR(i, 0); + } + + _vm->_global->_inter_execPtr = (char *)_totFileData; + _vm->_global->_inter_execPtr += READ_LE_UINT32((char *)_totFileData + 0x64); + + _vm->_inter->renewTimeInVars(); + + WRITE_VAR(13, _vm->_global->_useMouse); + WRITE_VAR(14, _vm->_global->_soundFlags); + WRITE_VAR(15, _vm->_global->_videoMode); + WRITE_VAR(16, _vm->_global->_language); + + _vm->_inter->callSub(2); + + if (_totToLoad[0] != 0) + _vm->_inter->_terminate = false; + + variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c); + _vm->_draw->blitInvalidated(); + delete[] _totFileData; + _totFileData = 0; + + if (needTextFree) + delete[] _totTextData; + _totTextData = 0; + + if (needFreeResTable) + delete[] _totResourceTable; + _totResourceTable = 0; + + delete[] _imFileData; + _imFileData = 0; + + if (_extTable) + delete[] _extTable->items; + delete _extTable; + _extTable = 0; + + if (_extHandle >= 0) + _vm->_dataio->closeData(_extHandle); + + _extHandle = -1; + + for (i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) + capturePop(0); + + _vm->_mult->checkFreeMult(); + _vm->_mult->freeAll(); + + for (i = 0; i < 20; i++) { + if (_vm->_draw->_spritesArray[i] != 0) + _vm->_video->freeSurfDesc(_vm->_draw->_spritesArray[i]); + _vm->_draw->_spritesArray[i] = 0; + } + _vm->_snd->stopSound(0); + + for (i = 0; i < 20; i++) + freeSoundSlot(i); + + if (_totToLoad[0] == 0) + break; + + strcpy(_curTotFile, _totToLoad); + } + } + + strcpy(_curTotFile, savedTotName); + + _vm->_inter->_nestLevel = oldNestLevel; + _vm->_inter->_breakFromLevel = oldBreakFrom; + _vm->_scenery->_pCaptureCounter = oldCaptureCounter; + _vm->_global->_inter_execPtr = savedIP; +} + +void Game_v2::clearCollisions() { + int16 i; + + _lastCollKey = 0; + + for (i = 0; i < 250; i++) { + _collisionAreas[i].id = 0; + _collisionAreas[i].left = -1; + } +} + +void Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, + int16 flags, int16 key, int16 funcEnter, int16 funcLeave) { + int16 i; + Collision *ptr; + + debugC(5, DEBUG_COLLISIONS, "addNewCollision"); + debugC(5, DEBUG_COLLISIONS, "id = %x", id); + debugC(5, DEBUG_COLLISIONS, "left = %d, top = %d, right = %d, bottom = %d", left, top, right, bottom); + debugC(5, DEBUG_COLLISIONS, "flags = %x, key = %x", flags, key); + debugC(5, DEBUG_COLLISIONS, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave); + + for (i = 0; i < 250; i++) { + if ((_collisionAreas[i].left != -1) && (_collisionAreas[i].id != id)) + continue; + + ptr = &_collisionAreas[i]; + ptr->id = id; + ptr->left = left; + ptr->top = top; + ptr->right = right; + ptr->bottom = bottom; + ptr->flags = flags; + ptr->key = key; + ptr->funcEnter = funcEnter; + ptr->funcLeave = funcLeave; + ptr->field_12 = 0; + return; + } + error("addNewCollision: Collision array full!\n"); +} + +} // End of namespace Gob diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index e5b9979147..af6f4f5140 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -189,9 +189,7 @@ void GobEngine::shutdown() { } int GobEngine::init() { - _game = new Game(this); _snd = new Snd(this); - _video = new Video(this); _global = new Global(this); _anim = new Anim(); _cdrom = new CDROM(this); @@ -209,12 +207,16 @@ int GobEngine::init() { _parse = new Parse_v1(this); _mult = new Mult_v1(this); _draw = new Draw_v1(this); + _game = new Game_v1(this); + _video = new Video_v1(this); } else if (_features & Gob::GF_GOB2) { _inter = new Inter_v2(this); _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); + _game = new Game_v2(this); + _video = new Video_v2(this); } else error("GobEngine::init(): Unknown version of game engine"); diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index e009123fee..269ea0e861 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1736,7 +1736,7 @@ bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { _vm->_global->_inter_execPtr += 2; return false; } - + _vm->_global->_inter_execPtr = (char *)_vm->_game->_totFileData + offset; if (counter == cmdCount && retFlag == 2) diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 1d3b2d9244..9631761e31 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1261,7 +1261,7 @@ void Inter_v2::o2_initMult(void) { delete _vm->_anim->_animSurf; } - _vm->_draw->adjustCoords(&_vm->_anim->_areaHeight, &_vm->_anim->_areaWidth, 0); + _vm->_draw->adjustCoords(0, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); warning("===> %d", _vm->_global->_videoMode); if (_vm->_anim->_animSurf == 0) { @@ -1292,7 +1292,7 @@ void Inter_v2::o2_initMult(void) { return; } - _vm->_draw->adjustCoords(&_vm->_anim->_areaHeight, &_vm->_anim->_areaWidth, 1); + _vm->_draw->adjustCoords(1, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); _vm->_draw->_sourceSurface = 21; _vm->_draw->_destSurface = 22; @@ -1380,14 +1380,12 @@ void Inter_v2::o2_totSub(void) { if (length & 0x80) { evalExpr(0); strcpy(totFile, _vm->_global->_inter_resStr); - } else { // loc_E8CE - for (i = 0; i < length; i++) // loc_E8E3 + } else { + for (i = 0; i < length; i++) totFile[i] = *_vm->_global->_inter_execPtr++; totFile[i] = 0; } - // loc_E910 - _vm->_global->_inter_execPtr++; flags = *_vm->_global->_inter_execPtr; _vm->_game->totSub(flags, totFile); diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 69bdc1ba17..bded301193 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -9,6 +9,8 @@ MODULE_OBJS := \ draw_v2.o \ driver_vga.o \ game.o \ + game_v1.o \ + game_v2.o \ global.o \ gob.o \ goblin.o \ @@ -30,7 +32,9 @@ MODULE_OBJS := \ sound.o \ timer.o \ util.o \ - video.o + video.o \ + video_v1.o \ + video_v2.o MODULE_DIRS += \ engines/gob diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index ea043d5d1a..0ad2fb5b50 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -120,6 +120,7 @@ Mult::Mult(GobEngine *vm) : _vm(vm) { } _orderArray = 0; + warning("GOB2 Stub! _word_2CC88"); _word_2CC88 = -1; } diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index f6ddf2abc0..fd56f321b5 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -57,6 +57,11 @@ void Mult_v2::loadMult(int16 resId) { _multData2 = new Mult_Data; _multDatas[index] = _multData2; + for (i = 0; i < 10; i++) { + _multData2->staticLoaded[i] = 0; + _multData2->animLoaded[i] = 0; + } + for (i = 0; i < 4; i++) _multData2->field_124[0][i] = i; @@ -331,7 +336,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, multObj->lastBottom = -1; } - _vm->_draw->adjustCoords(&_vm->_anim->_areaHeight, &_vm->_anim->_areaWidth, 0); + _vm->_draw->adjustCoords(0, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); if ((_vm->_global->_videoMode == 0x14) && ((_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2 @@ -344,16 +349,16 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape, _vm->_anim->_animSurf->vidPtr += (_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2; } else - _vm->_draw->initBigSprite(22, _vm->_anim->_areaHeight, _vm->_anim->_areaWidth, 0); + _vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0); - _vm->_draw->adjustCoords(&_vm->_anim->_areaHeight, &_vm->_anim->_areaWidth, 1); + _vm->_draw->adjustCoords(1, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight); _vm->_draw->_sourceSurface = 21; _vm->_draw->_destSurface = 22; _vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteY = 0; _vm->_draw->_spriteLeft = 0; _vm->_draw->_spriteTop = 0; - _vm->_draw->_spriteRight= 320; + _vm->_draw->_spriteRight = 320; _vm->_draw->_spriteBottom = 200; _vm->_draw->_transparency = 0; _vm->_draw->spriteOperation(0); @@ -986,7 +991,6 @@ void Mult_v2::animate(void) { } } - warning("GOB2 Stub! _word_2CC88"); if (_word_2CC88 >= 0) { for (i = 0; i < orderArrayPos; i++) { animObj1 = _renderData2[orderArray[i]]; @@ -1175,8 +1179,6 @@ void Mult_v2::freeMultKeys(void) { if (_multData2 == 0) return; - return; - // loc_7323 staticCount = (_multData2->staticCount + 1) && 0x7F; @@ -1210,7 +1212,6 @@ void Mult_v2::freeMultKeys(void) { } delete[] _multData2->sndKeys; - delete[] _multData2->fadePal; if (_multData2->somepointer09 != 0) delete[] _multData2->somepointer09; diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 5e0dcad185..db88e547d3 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -293,16 +293,67 @@ void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest) { _videoDriver->putPixel(x, y, color, dest); } -void Video::drawLetter(unsigned char item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, - int16 color2, int16 transp, SurfaceDesc *dest) { - - _videoDriver->drawLetter(item, x, y, fontDesc, color1, color2, transp, dest); -} - void Video::clearSurf(SurfaceDesc *dest) { Video::fillRect(dest, 0, 0, dest->width - 1, dest->height - 1, 0); } +void Video::drawCircle(Video::SurfaceDesc *dest, int16 x, int16 y, int16 radius, int16 color) { + int16 si; + int16 var_18; + int16 var_16; + int16 y4; + int16 y3; + int16 x4; + int16 x3; + int16 x2; + int16 y2; + int16 x1; + int16 y1; + int16 var_4; + int16 var_2; + + var_2 = radius; + var_4 = 0; + si = -radius; + y1 = y; + x1 = x + radius; + y2 = y + radius; + x2 = x; + x3 = x - radius; + x4 = x; + y3 = y; + y4 = y - radius; + var_16 = 0; + var_18 = radius * 2; + + while (var_2 >= var_4) { + putPixel(x1, y1, color, dest); + putPixel(x2, y2, color, dest); + putPixel(x3, y1, color, dest); + putPixel(x4, y2, color, dest); + putPixel(x1, y3, color, dest); + putPixel(x2, y4, color, dest); + putPixel(x3, y3, color, dest); + putPixel(x4, y4, color, dest); + y1++; + x2++; + x4--; + y3--; + var_16 += 2; + var_4++; + si += var_16 + 1; + if (si > 0) { + x1--; + y2--; + x3++; + y4++; + var_18 -= 2; + var_2--; + si -= var_18 + 1; + } + } +} + void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, int16 transp, SurfaceDesc *dest) { diff --git a/engines/gob/video.h b/engines/gob/video.h index 58c6bdb3c2..02b9090cc9 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -90,6 +90,7 @@ public: }; Video(class GobEngine *vm); + virtual ~Video() {}; int32 getRectSize(int16 width, int16 height, int16 flag, int16 mode); SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); void freeSurfDesc(SurfaceDesc * surfDesc); @@ -101,8 +102,7 @@ public: void drawLine(SurfaceDesc * dest, int16 x0, int16 y0, int16 x1, int16 y1, int16 color); void putPixel(int16 x, int16 y, int16 color, SurfaceDesc * dest); - void drawLetter(unsigned char item, int16 x, int16 y, FontDesc * fontDesc, int16 color1, - int16 color2, int16 transp, SurfaceDesc * dest); + void drawCircle(Video::SurfaceDesc *dest, int16 x, int16 y, int16 radius, int16 color); void clearSurf(SurfaceDesc * dest); void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, int16 transp, SurfaceDesc * dest); @@ -117,6 +117,9 @@ public: void freeDriver(void); void setHandlers(); + virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, + int16 color1, int16 color2, int16 transp, SurfaceDesc * dest) = 0; + protected: class VideoDriver *_videoDriver; GobEngine *_vm; @@ -124,6 +127,24 @@ protected: char initDriver(int16 vidMode); }; +class Video_v1 : public Video { +public: + virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, + int16 color1, int16 color2, int16 transp, SurfaceDesc * dest); + + Video_v1(GobEngine *vm); + virtual ~Video_v1() {}; +}; + +class Video_v2 : public Video_v1 { +public: + virtual void drawLetter(int16 item, int16 x, int16 y, FontDesc * fontDesc, + int16 color1, int16 color2, int16 transp, SurfaceDesc * dest); + + Video_v2(GobEngine *vm); + virtual ~Video_v2() {}; +}; + class VideoDriver { public: VideoDriver() {} diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp new file mode 100644 index 0000000000..e1d20f01d4 --- /dev/null +++ b/engines/gob/video_v1.cpp @@ -0,0 +1,41 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/video.h" + +namespace Gob { + +Video_v1::Video_v1(GobEngine *vm) : Video(vm) { +} + +void Video_v1::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, + int16 color2, int16 transp, SurfaceDesc *dest) { + + _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); +} + +} // End of namespace Gob diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp new file mode 100644 index 0000000000..0d0a7be9e1 --- /dev/null +++ b/engines/gob/video_v2.cpp @@ -0,0 +1,74 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/video.h" + +namespace Gob { + +Video_v2::Video_v2(GobEngine *vm) : Video_v1(vm) { +} + +void Video_v2::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, int16 color1, + int16 color2, int16 transp, SurfaceDesc *dest) { + int16 videoMode; + + videoMode = dest->vidMode; + + // Is that needed at all? And what does it do anyway? + char *dataPtr; + int16 itemSize; + int16 si; + int16 di; + int16 dx; + char *var_A; + int16 var_10; + if (fontDesc->endItem == 0) { + itemSize = fontDesc->itemSize + 3; + dataPtr = fontDesc->dataPtr; + var_10 = dataPtr[-2] - 1; + si = 0; + do { + di = ((si + var_10) / 2) * itemSize; + var_A = fontDesc->dataPtr + di; + dx = (READ_LE_UINT16(var_A) & 0x7FFF); + if (item > dx) + var_10 = di - 1; + else + si = di + 1; + } while ((dx != item) && (si <= var_10)); + if (dx != item) + return; + fontDesc->dataPtr = var_A + 3; + item = 0; + } + + dest->vidMode &= 0x7F; + _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); + dest->vidMode = videoMode; +} + +} // End of namespace Gob |