aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2006-04-18 09:59:18 +0000
committerSven Hesse2006-04-18 09:59:18 +0000
commitab48280f731cf65313b4bd57896e762eb04fbce9 (patch)
tree1646d50032b5c2bf2040cf4ae51f5ce9d50ee918 /engines/gob
parent4b59f6fbda912ccac9619d144d68536cb4d72834 (diff)
downloadscummvm-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.cpp297
-rw-r--r--engines/gob/draw.h26
-rw-r--r--engines/gob/draw_v2.cpp605
-rw-r--r--engines/gob/game.cpp289
-rw-r--r--engines/gob/game.h36
-rw-r--r--engines/gob/game_v1.cpp293
-rw-r--r--engines/gob/game_v2.cpp302
-rw-r--r--engines/gob/gob.cpp6
-rw-r--r--engines/gob/inter_v1.cpp2
-rw-r--r--engines/gob/inter_v2.cpp10
-rw-r--r--engines/gob/module.mk6
-rw-r--r--engines/gob/mult.cpp1
-rw-r--r--engines/gob/mult_v2.cpp17
-rw-r--r--engines/gob/video.cpp63
-rw-r--r--engines/gob/video.h25
-rw-r--r--engines/gob/video_v1.cpp41
-rw-r--r--engines/gob/video_v2.cpp74
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