- 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
This commit is contained in:
Sven Hesse 2006-04-18 09:59:18 +00:00
parent 4b59f6fbda
commit ab48280f73
17 changed files with 1704 additions and 389 deletions

View File

@ -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;
_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];
}
else {
*fragment = _vm->_video->initSurfDesc(_spritesWidths[index], height,
flags, _vm->_global->_videoMode);
realwidth += _spritesWidths[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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

293
engines/gob/game_v1.cpp Normal file
View File

@ -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

302
engines/gob/game_v2.cpp Normal file
View File

@ -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

View File

@ -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");

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -120,6 +120,7 @@ Mult::Mult(GobEngine *vm) : _vm(vm) {
}
_orderArray = 0;
warning("GOB2 Stub! _word_2CC88");
_word_2CC88 = -1;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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() {}

41
engines/gob/video_v1.cpp Normal file
View File

@ -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

74
engines/gob/video_v2.cpp Normal file
View File

@ -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