Implemented vertical scrolling

svn-id: r25401
This commit is contained in:
Sven Hesse 2007-02-06 14:42:05 +00:00
parent 56ff44633f
commit d706d8e4c0
16 changed files with 325 additions and 236 deletions

View file

@ -129,10 +129,11 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
_cursorTimeKey = 0; _cursorTimeKey = 0;
warning("GOB2 Stub! _word_2E8E2, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517"); _scrollOffsetX = 0;
_scrollOffsetY = 0;
warning("GOB2 Stub! _word_2E8E2, _word_2E51F, _off_2E51B, _off_2E517");
_word_2E8E2 = 2; _word_2E8E2 = 2;
_word_2FC9C = 0;
_word_2FC9E = 0;
_word_2E51F = 0; _word_2E51F = 0;
_off_2E51B = 0; _off_2E51B = 0;
_off_2E517 = 0; _off_2E517 = 0;
@ -157,7 +158,8 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) {
bottom = temp; bottom = temp;
} }
if (left > (_vm->_video->_surfWidth - 1) || right < 0 || top > 199 || bottom < 0) if ((left > (_vm->_video->_surfWidth - 1)) || (right < 0) ||
(top > (_vm->_video->_surfHeight - 1)) || (bottom < 0))
return; return;
_noInvalidated = 0; _noInvalidated = 0;
@ -166,7 +168,7 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) {
_invalidatedLefts[0] = 0; _invalidatedLefts[0] = 0;
_invalidatedTops[0] = 0; _invalidatedTops[0] = 0;
_invalidatedRights[0] = _vm->_video->_surfWidth - 1; _invalidatedRights[0] = _vm->_video->_surfWidth - 1;
_invalidatedBottoms[0] = 199; _invalidatedBottoms[0] = _vm->_video->_surfHeight - 1;
_invalidatedCount = 1; _invalidatedCount = 1;
return; return;
} }
@ -180,8 +182,8 @@ void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) {
if (top < 0) if (top < 0)
top = 0; top = 0;
if (bottom > 199) if (bottom > (_vm->_video->_surfHeight - 1))
bottom = 199; bottom = _vm->_video->_surfHeight - 1;
left &= 0xfff0; left &= 0xfff0;
right |= 0x000f; right |= 0x000f;
@ -266,7 +268,7 @@ void Draw::blitInvalidated(void) {
clearPalette(); clearPalette();
_vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0, _vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0,
_vm->_video->_surfWidth - 1, 199, 0, 0, 0); _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 0, 0, 0);
setPalette(); setPalette();
_invalidatedCount = 0; _invalidatedCount = 0;
_noInvalidated = 1; _noInvalidated = 1;

View file

@ -114,8 +114,8 @@ public:
int16 _palLoadData2[4]; int16 _palLoadData2[4];
int16 _word_2E8E2; int16 _word_2E8E2;
int16 _word_2FC9C; int16 _scrollOffsetY;
int16 _word_2FC9E; int16 _scrollOffsetX;
int16 _word_2E51F; int16 _word_2E51F;
Video::SurfaceDesc *_off_2E51B; Video::SurfaceDesc *_off_2E51B;
Video::SurfaceDesc *_off_2E517; Video::SurfaceDesc *_off_2E517;

View file

@ -957,8 +957,8 @@ void Draw_v2::animateCursor(int16 cursor) {
} }
void Draw_v2::initScreen(void) { void Draw_v2::initScreen(void) {
_word_2FC9C = 0; _scrollOffsetX = 0;
_word_2FC9E = 0; _scrollOffsetY = 0;
if (_word_2E51F != 0) { if (_word_2E51F != 0) {
_off_2E51B = new Video::SurfaceDesc; _off_2E51B = new Video::SurfaceDesc;
@ -974,7 +974,7 @@ void Draw_v2::initScreen(void) {
_off_2E517->vidPtr = _frontSurface->vidPtr + _off_2E517->vidPtr = _frontSurface->vidPtr +
((_frontSurface->width * _frontSurface->height ) / 4); ((_frontSurface->width * _frontSurface->height ) / 4);
} }
initBigSprite(21, _vm->_video->_surfWidth, 200, 0); initBigSprite(21, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0);
_backSurface = _spritesArray[21]; _backSurface = _spritesArray[21];
_vm->_video->clearSurf(_backSurface); _vm->_video->clearSurf(_backSurface);
@ -1002,7 +1002,7 @@ void Draw_v2::closeScreen(void) {
if (_off_2E51B != 0) { if (_off_2E51B != 0) {
memcpy(_frontSurface, _off_2E51B, sizeof(Video::SurfaceDesc)); memcpy(_frontSurface, _off_2E51B, sizeof(Video::SurfaceDesc));
_frontSurface->width = _vm->_video->_surfWidth; _frontSurface->width = _vm->_video->_surfWidth;
_frontSurface->height = 200; _frontSurface->height = _vm->_video->_surfHeight;
delete _off_2E51B; delete _off_2E51B;
delete _off_2E517; delete _off_2E517;
_off_2E51B = 0; _off_2E51B = 0;

View file

@ -452,15 +452,15 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
&_mouseButtons, handleMouse); &_mouseButtons, handleMouse);
// TODO: What of this is needed? // TODO: What of this is needed?
// Scrolling? // Mouse position calculation in scrollable screen?
int16 width; int16 width;
int16 height; int16 height;
int16 sWidth; int16 sWidth;
int16 sHeight; int16 sHeight;
int16 cursorRight; int16 cursorRight;
int16 cursorBottom; int16 cursorBottom;
int16 oldWord_2FC9C; int16 oldOffY;
int16 oldWord_2FC9E; int16 oldOffX;
if ((_vm->_global->_videoMode == 0x14) && (handleMouse != 0)) { if ((_vm->_global->_videoMode == 0x14) && (handleMouse != 0)) {
width = _vm->_draw->_frontSurface->width; width = _vm->_draw->_frontSurface->width;
height = _vm->_draw->_frontSurface->height; height = _vm->_draw->_frontSurface->height;
@ -470,64 +470,65 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
sHeight = _vm->_global->_primaryHeight; sHeight = _vm->_global->_primaryHeight;
if (_vm->_draw->_off_2E51B != 0) if (_vm->_draw->_off_2E51B != 0)
sHeight -= _vm->_draw->_off_2E51B->height; sHeight -= _vm->_draw->_off_2E51B->height;
oldWord_2FC9E = _vm->_draw->_word_2FC9E; oldOffX = _vm->_draw->_scrollOffsetX;
oldWord_2FC9C = _vm->_draw->_word_2FC9C; oldOffY = _vm->_draw->_scrollOffsetY;
if ((width > sWidth) && (_vm->_global->_inter_mouseX >= _vm->_draw->_word_2FC9E)) { if ((width > sWidth) && (_vm->_global->_inter_mouseX >= _vm->_draw->_scrollOffsetX)) {
cursorRight = _vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth; cursorRight = _vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth;
if (cursorRight > (_vm->_draw->_word_2FC9E + sWidth)) if (cursorRight > (_vm->_draw->_scrollOffsetX + sWidth))
_vm->_draw->_word_2FC9E = MIN(cursorRight - sWidth, width - sWidth); _vm->_draw->_scrollOffsetX = MIN(cursorRight - sWidth, width - sWidth);
} else if (_vm->_global->_inter_mouseX < _vm->_draw->_word_2FC9E) } else if (_vm->_global->_inter_mouseX < _vm->_draw->_scrollOffsetX)
_vm->_draw->_word_2FC9E = _vm->_global->_inter_mouseX; _vm->_draw->_scrollOffsetX = _vm->_global->_inter_mouseX;
height = _vm->_draw->_frontSurface->height; height = _vm->_draw->_frontSurface->height;
if ((height > sHeight) && (_vm->_global->_inter_mouseY >= _vm->_draw->_word_2FC9C)) { if ((height > sHeight) && (_vm->_global->_inter_mouseY >= _vm->_draw->_scrollOffsetY)) {
cursorBottom = _vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight; cursorBottom = _vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight;
if (cursorBottom > (_vm->_draw->_word_2FC9C + sHeight)) if (cursorBottom > (_vm->_draw->_scrollOffsetY + sHeight))
_vm->_draw->_word_2FC9C = MIN(cursorBottom - sHeight, height - sHeight); _vm->_draw->_scrollOffsetY = MIN(cursorBottom - sHeight, height - sHeight);
} else if (_vm->_global->_inter_mouseY < _vm->_draw->_word_2FC9C) } else if (_vm->_global->_inter_mouseY < _vm->_draw->_scrollOffsetY)
_vm->_draw->_word_2FC9C = _vm->_global->_inter_mouseY; _vm->_draw->_scrollOffsetY = _vm->_global->_inter_mouseY;
if ((oldWord_2FC9E != _vm->_draw->_word_2FC9E) || if ((oldOffX != _vm->_draw->_scrollOffsetX) ||
(oldWord_2FC9C != _vm->_draw->_word_2FC9C)) { (oldOffY != _vm->_draw->_scrollOffsetY)) {
if (_byte_2FC9B == 0) { if (_byte_2FC9B == 0) {
_vm->_draw->_word_2FC9E = oldWord_2FC9E; _vm->_draw->_scrollOffsetX = oldOffX;
_vm->_draw->_word_2FC9C = oldWord_2FC9C; _vm->_draw->_scrollOffsetY = oldOffY;
if ((_vm->_draw->_frontSurface->width > sWidth) && if ((_vm->_draw->_frontSurface->width > sWidth) &&
(_vm->_global->_inter_mouseX >= oldWord_2FC9E)) { (_vm->_global->_inter_mouseX >= oldOffX)) {
if ((_vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth) > if ((_vm->_global->_inter_mouseX + _vm->_draw->_cursorWidth) >
(_vm->_draw->_word_2FC9E + sWidth)) (_vm->_draw->_scrollOffsetX + sWidth))
_vm->_global->_inter_mouseX = _vm->_draw->_word_2FC9E + _vm->_global->_inter_mouseX = _vm->_draw->_scrollOffsetX +
sWidth - _vm->_draw->_cursorWidth; sWidth - _vm->_draw->_cursorWidth;
} else if (_vm->_global->_inter_mouseX < oldWord_2FC9E) } else if (_vm->_global->_inter_mouseX < oldOffX)
_vm->_global->_inter_mouseX = oldWord_2FC9E; _vm->_global->_inter_mouseX = oldOffX;
if ((_vm->_draw->_frontSurface->height > sHeight) && if ((_vm->_draw->_frontSurface->height > sHeight) &&
(_vm->_global->_inter_mouseY >= _vm->_draw->_word_2FC9C)) { (_vm->_global->_inter_mouseY >= _vm->_draw->_scrollOffsetY)) {
if ((_vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight) > if ((_vm->_global->_inter_mouseY + _vm->_draw->_cursorHeight) >
(_vm->_draw->_word_2FC9C + sHeight)) (_vm->_draw->_scrollOffsetY + sHeight))
_vm->_global->_inter_mouseY = _vm->_draw->_word_2FC9C + _vm->_global->_inter_mouseY = _vm->_draw->_scrollOffsetY +
sHeight - _vm->_draw->_cursorHeight; sHeight - _vm->_draw->_cursorHeight;
} else if (_vm->_global->_inter_mouseY < oldWord_2FC9E) } else if (_vm->_global->_inter_mouseY < oldOffX)
_vm->_global->_inter_mouseY = _vm->_draw->_word_2FC9C; _vm->_global->_inter_mouseY = _vm->_draw->_scrollOffsetY;
} else { } else {
if (oldWord_2FC9E > _vm->_draw->_word_2FC9E) { if (oldOffX > _vm->_draw->_scrollOffsetX) {
_vm->_global->_inter_mouseX += (oldWord_2FC9E - _vm->_draw->_word_2FC9E) / 2; _vm->_global->_inter_mouseX += (oldOffX - _vm->_draw->_scrollOffsetX) / 2;
_vm->_draw->_word_2FC9E += (oldWord_2FC9E - _vm->_draw->_word_2FC9E) / 2; _vm->_draw->_scrollOffsetX += (oldOffX - _vm->_draw->_scrollOffsetX) / 2;
} else { } else {
_vm->_global->_inter_mouseX -= (_vm->_draw->_word_2FC9E - oldWord_2FC9E) / 2; _vm->_global->_inter_mouseX -= (_vm->_draw->_scrollOffsetX - oldOffX) / 2;
_vm->_draw->_word_2FC9E -= (_vm->_draw->_word_2FC9E - oldWord_2FC9E) / 2; _vm->_draw->_scrollOffsetX -= (_vm->_draw->_scrollOffsetX - oldOffX) / 2;
} }
if (oldWord_2FC9C > _vm->_draw->_word_2FC9C) { if (oldOffY > _vm->_draw->_scrollOffsetY) {
_vm->_global->_inter_mouseY += (oldWord_2FC9C - _vm->_draw->_word_2FC9C) / 2; _vm->_global->_inter_mouseY += (oldOffY - _vm->_draw->_scrollOffsetY) / 2;
_vm->_draw->_word_2FC9C += (oldWord_2FC9C - _vm->_draw->_word_2FC9C) / 2; _vm->_draw->_scrollOffsetY += (oldOffY - _vm->_draw->_scrollOffsetY) / 2;
if (_vm->_draw->_word_2FC9C < 2) if (_vm->_draw->_scrollOffsetY < 2)
_vm->_draw->_word_2FC9C = 0; _vm->_draw->_scrollOffsetY = 0;
} else { } else {
_vm->_global->_inter_mouseY -= (_vm->_draw->_word_2FC9C - oldWord_2FC9C) / 2; _vm->_global->_inter_mouseY -= (_vm->_draw->_scrollOffsetY - oldOffY) / 2;
_vm->_draw->_word_2FC9C -= (_vm->_draw->_word_2FC9C - oldWord_2FC9C) / 2; _vm->_draw->_scrollOffsetY -= (_vm->_draw->_scrollOffsetY - oldOffY) / 2;
} }
if (_vm->_draw->_off_2E51B == 0) if (_vm->_draw->_off_2E51B == 0)
warning("_vid_setPixelShift(_vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C);"); _vm->_util->setScrollOffset();
else else
warning("_vid_setPixelShift(_vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C + _vm->_draw->_off_2E51B->height);"); _vm->_util->setScrollOffset(_vm->_draw->_scrollOffsetX,
_vm->_draw->_scrollOffsetY + _vm->_draw->_off_2E51B->height);;
} }
_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
} }
@ -646,7 +647,7 @@ void Game_v2::prepareStart(void) {
_vm->_draw->initScreen(); _vm->_draw->initScreen();
_vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0,
_vm->_video->_surfWidth - 1, 199, 1); _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1);
_vm->_util->setMousePos(152, 92); _vm->_util->setMousePos(152, 92);

View file

@ -43,7 +43,8 @@ void Init_v2::soundVideo(int32 smallHeap, int16 flag) {
_vm->_global->_videoMode); _vm->_global->_videoMode);
_vm->_draw->_frontSurface = &_vm->_global->_primarySurfDesc; _vm->_draw->_frontSurface = &_vm->_global->_primarySurfDesc;
_vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, 200, 0x80); _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth,
_vm->_video->_surfHeight, 0x80);
_vm->_global->_mousePresent = 1; _vm->_global->_mousePresent = 1;
@ -61,8 +62,8 @@ void Init_v2::soundVideo(int32 smallHeap, int16 flag) {
_vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2; _vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2;
if (_vm->_global->_videoMode != 0) if (_vm->_global->_videoMode != 0)
_vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, 200, _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth,
PRIMARY_SURFACE); _vm->_video->_surfHeight, PRIMARY_SURFACE);
} }
} // End of namespace Gob } // End of namespace Gob

View file

@ -190,60 +190,6 @@ void Inter::funcBlock(int16 retFlag) {
return; return;
} }
void Inter::checkSwitchTable(char **ppExec) {
int16 i;
int16 len;
char found;
int32 value;
char notFound;
char defFlag;
found = 0;
notFound = 1;
*ppExec = 0;
value = _vm->_parse->parseVarIndex();
value = VAR_OFFSET(value);
do {
len = *(int8*)_vm->_global->_inter_execPtr++; // must be a signed char typ and char is not default signed on all platforms.
if (len == -5)
break;
for (i = 0; i < len; i++) {
evalExpr(0);
if (_terminate)
return;
if (_vm->_global->_inter_resVal == value) {
found = 1;
notFound = 0;
}
}
if (found != 0)
*ppExec = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
found = 0;
} while (len != -5);
if (len != -5)
_vm->_global->_inter_execPtr++;
defFlag = *_vm->_global->_inter_execPtr;
defFlag >>= 4;
if (defFlag != 4)
return;
_vm->_global->_inter_execPtr++;
if (notFound)
*ppExec = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
}
void Inter::callSub(int16 retFlag) { void Inter::callSub(int16 retFlag) {
int16 block; int16 block;
while (!_vm->_quitRequested && _vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->_totFileData) { while (!_vm->_quitRequested && _vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->_totFileData) {

View file

@ -58,11 +58,11 @@ public:
char evalExpr(int16 *pRes); char evalExpr(int16 *pRes);
char evalBoolResult(void); char evalBoolResult(void);
void funcBlock(int16 retFlag); void funcBlock(int16 retFlag);
void checkSwitchTable(char **ppExec);
void callSub(int16 retFlag); void callSub(int16 retFlag);
void initControlVars(char full); void initControlVars(char full);
void renewTimeInVars(void); void renewTimeInVars(void);
void manipulateMap(int16 xPos, int16 yPos, int16 item); void manipulateMap(int16 xPos, int16 yPos, int16 item);
virtual void checkSwitchTable(char **ppExec) = 0;
virtual int16 loadSound(int16 slot) = 0; virtual int16 loadSound(int16 slot) = 0;
virtual void storeKey(int16 key) = 0; virtual void storeKey(int16 key) = 0;
virtual void storeMouse(void) = 0; virtual void storeMouse(void) = 0;
@ -95,6 +95,7 @@ class Inter_v1 : public Inter {
public: public:
Inter_v1(GobEngine *vm); Inter_v1(GobEngine *vm);
virtual ~Inter_v1() {}; virtual ~Inter_v1() {};
virtual void checkSwitchTable(char **ppExec);
virtual int16 loadSound(int16 slot); virtual int16 loadSound(int16 slot);
virtual void storeKey(int16 key); virtual void storeKey(int16 key);
virtual void storeMouse(void); virtual void storeMouse(void);
@ -288,6 +289,7 @@ class Inter_v2 : public Inter_v1 {
public: public:
Inter_v2(GobEngine *vm); Inter_v2(GobEngine *vm);
virtual ~Inter_v2() {}; virtual ~Inter_v2() {};
virtual void checkSwitchTable(char **ppExec);
virtual int16 loadSound(int16 search); virtual int16 loadSound(int16 search);
virtual void storeKey(int16 key); virtual void storeKey(int16 key);
virtual void storeMouse(void); virtual void storeMouse(void);

View file

@ -743,11 +743,11 @@ void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr,
_vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0); _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0);
_vm->_video->drawPackedSprite("2ille4.ims", surface); _vm->_video->drawPackedSprite("2ille4.ims", surface);
_vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0);
_vm->_util->setScrollOffset(320); _vm->_util->setScrollOffset(320, 0);
_vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0); _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0);
_vm->_util->longDelay(1000); _vm->_util->longDelay(1000);
for (i = 320; i >= 0; i--) { for (i = 320; i >= 0; i--) {
_vm->_util->setScrollOffset(i); _vm->_util->setScrollOffset(i, 0);
if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) ||
_vm->_quitRequested) { _vm->_quitRequested) {
_vm->_palanim->fade(0, -2, 0); _vm->_palanim->fade(0, -2, 0);
@ -760,7 +760,7 @@ void Inter_Bargon::oBargon_intro2(int16 &extraData, int32 *retVarPtr,
} }
} }
if (!_vm->_quitRequested) if (!_vm->_quitRequested)
_vm->_util->setScrollOffset(0); _vm->_util->setScrollOffset(0, 0);
_vm->_video->freeSurfDesc(surface); _vm->_video->freeSurfDesc(surface);
if (VAR(57) == ((uint32) -1)) if (VAR(57) == ((uint32) -1))
return; return;

View file

@ -646,6 +646,117 @@ void Inter_v1::setupOpcodes(void) {
_opcodesGoblinV1 = opcodesGoblin; _opcodesGoblinV1 = opcodesGoblin;
} }
void Inter_v1::executeDrawOpcode(byte i) {
debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i));
OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc;
if (op == NULL)
warning("unimplemented opcodeDraw: %d", i);
else
(this->*op) ();
}
bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) {
debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j));
if ((i > 4) || (j > 15)) {
warning("unimplemented opcodeFunc: %d.%d", i, j);
return false;
}
OpcodeFuncProcV1 op = _opcodesFuncV1[i*16 + j].proc;
if (op == NULL)
warning("unimplemented opcodeFunc: %d.%d", i, j);
else
return (this->*op) (cmdCount, counter, retFlag);
return false;
}
void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i));
OpcodeGoblinProcV1 op = NULL;
for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++)
if (_goblinFuncLookUp[j][0] == i) {
op = _opcodesGoblinV1[_goblinFuncLookUp[j][1]].proc;
break;
}
if (op == NULL) {
warning("unimplemented opcodeGoblin: %d", i);
_vm->_global->_inter_execPtr -= 2;
int16 cmd = load16();
_vm->_global->_inter_execPtr += cmd * 2;
}
else
(this->*op) (extraData, retVarPtr, objDesc);
}
const char *Inter_v1::getOpcodeDrawDesc(byte i) {
return _opcodesDrawV1[i].desc;
}
const char *Inter_v1::getOpcodeFuncDesc(byte i, byte j) {
if ((i > 4) || (j > 15))
return "";
return _opcodesFuncV1[i*16 + j].desc;
}
const char *Inter_v1::getOpcodeGoblinDesc(int i) {
for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++)
if (_goblinFuncLookUp[j][0] == i)
return _opcodesGoblinV1[_goblinFuncLookUp[j][1]].desc;
return "";
}
void Inter_v1::checkSwitchTable(char **ppExec) {
int i;
int16 len;
int32 value;
bool found;
bool notFound;
found = false;
notFound = true;
*ppExec = 0;
value = VAR_OFFSET(_vm->_parse->parseVarIndex());
len = (int8) *_vm->_global->_inter_execPtr++;
while (len != -5) {
for (i = 0; i < len; i++) {
evalExpr(0);
if (_terminate)
return;
if (_vm->_global->_inter_resVal == value) {
found = true;
notFound = false;
}
}
if (found)
*ppExec = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
found = false;
len = (int8) *_vm->_global->_inter_execPtr++;
}
if ((*_vm->_global->_inter_execPtr >> 4) != 4)
return;
_vm->_global->_inter_execPtr++;
if (notFound)
*ppExec = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
}
bool Inter_v1::o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag) { bool Inter_v1::o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag) {
_vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr();
_vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr();
@ -1303,6 +1414,7 @@ bool Inter_v1::o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag
_vm->_draw->_destSurface = 101; _vm->_draw->_destSurface = 101;
_vm->_draw->_transparency &= 1; _vm->_draw->_transparency &= 1;
_vm->_global->_inter_execPtr += 2; _vm->_global->_inter_execPtr += 2;
_vm->_draw->spriteOperation(DRAW_LOADSPRITE); _vm->_draw->spriteOperation(DRAW_LOADSPRITE);
return false; return false;
@ -1696,73 +1808,6 @@ void Inter_v1::o1_freeFontToSprite(void) {
_vm->_draw->_fontToSprite[i].height = -1; _vm->_draw->_fontToSprite[i].height = -1;
} }
void Inter_v1::executeDrawOpcode(byte i) {
debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%x] (%s)", i, i, getOpcodeDrawDesc(i));
OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc;
if (op == NULL)
warning("unimplemented opcodeDraw: %d", i);
else
(this->*op) ();
}
bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) {
debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%x.0x%x] (%s)", i, j, i, j, getOpcodeFuncDesc(i, j));
if ((i > 4) || (j > 15)) {
warning("unimplemented opcodeFunc: %d.%d", i, j);
return false;
}
OpcodeFuncProcV1 op = _opcodesFuncV1[i*16 + j].proc;
if (op == NULL)
warning("unimplemented opcodeFunc: %d.%d", i, j);
else
return (this->*op) (cmdCount, counter, retFlag);
return false;
}
void Inter_v1::executeGoblinOpcode(int i, int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%x] (%s)", i, i, getOpcodeGoblinDesc(i));
OpcodeGoblinProcV1 op = NULL;
for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++)
if (_goblinFuncLookUp[j][0] == i) {
op = _opcodesGoblinV1[_goblinFuncLookUp[j][1]].proc;
break;
}
if (op == NULL) {
warning("unimplemented opcodeGoblin: %d", i);
_vm->_global->_inter_execPtr -= 2;
int16 cmd = load16();
_vm->_global->_inter_execPtr += cmd * 2;
}
else
(this->*op) (extraData, retVarPtr, objDesc);
}
const char *Inter_v1::getOpcodeDrawDesc(byte i) {
return _opcodesDrawV1[i].desc;
}
const char *Inter_v1::getOpcodeFuncDesc(byte i, byte j) {
if ((i > 4) || (j > 15))
return "";
return _opcodesFuncV1[i*16 + j].desc;
}
const char *Inter_v1::getOpcodeGoblinDesc(int i) {
for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++)
if (_goblinFuncLookUp[j][0] == i)
return _opcodesGoblinV1[_goblinFuncLookUp[j][1]].desc;
return "";
}
bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) {
char *storedIP = _vm->_global->_inter_execPtr; char *storedIP = _vm->_global->_inter_execPtr;

View file

@ -715,6 +715,96 @@ const char *Inter_v2::getOpcodeGoblinDesc(int i) {
return ""; return "";
} }
void Inter_v2::checkSwitchTable(char **ppExec) {
int i;
byte cmd;
int16 len;
int32 value;
bool found;
found = false;
*ppExec = 0;
cmd = *_vm->_global->_inter_execPtr;
value = _vm->_parse->parseVarIndex();
switch (cmd) {
case 16:
case 18:
value = (int8) READ_VARO_UINT8(value);
break;
case 23:
case 26:
value = READ_VARO_UINT32(value);
break;
default:
value = READ_VARO_UINT16(value);
break;
}
if (_terminate)
return;
len = (int8) *_vm->_global->_inter_execPtr++;
while (len != -5) {
for (i = 0; i < len; i++) {
cmd = *_vm->_global->_inter_execPtr;
switch(cmd) {
case 19:
_vm->_global->_inter_execPtr++;
if (!found &&
(value == (int32) (READ_LE_UINT32(_vm->_global->_inter_execPtr))))
found = true;
_vm->_global->_inter_execPtr += 5;
break;
case 20:
_vm->_global->_inter_execPtr++;
if (!found &&
(value == (int16) (READ_LE_UINT16(_vm->_global->_inter_execPtr))))
found = true;
_vm->_global->_inter_execPtr += 3;
break;
case 21:
_vm->_global->_inter_execPtr++;
if (!found && (value == (int8) *_vm->_global->_inter_execPtr))
found = true;
_vm->_global->_inter_execPtr += 2;
break;
default:
if (!found) {
evalExpr(0);
if (value == _vm->_global->_inter_resVal)
found = true;
} else
_vm->_parse->skipExpr(99);
break;
}
}
if (found && (*ppExec == 0))
*ppExec = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
len = (int8) *_vm->_global->_inter_execPtr++;
}
if ((*_vm->_global->_inter_execPtr >> 4) != 4)
return;
_vm->_global->_inter_execPtr++;
if (*ppExec == 0)
*ppExec = _vm->_global->_inter_execPtr;
_vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2;
}
void Inter_v2::o2_stub0x54(void) { void Inter_v2::o2_stub0x54(void) {
int16 index = _vm->_parse->parseValExpr(); int16 index = _vm->_parse->parseValExpr();
@ -879,7 +969,7 @@ int16 Inter_v2::loadSound(int16 search) {
} else { } else {
if (id >= 30000) { if (id >= 30000) {
if (!isADL && (_vm->_game->_totFileData[0x29] >= 51)) { // loc_9763 if (!isADL && (_vm->_game->_totFileData[0x29] >= 51)) { // loc_9763
if (_vm->_inter->_terminate != 0) if (_terminate != 0)
return slot; return slot;
soundDesc = new Snd::SoundDesc; soundDesc = new Snd::SoundDesc;
extData = _vm->_game->loadExtData(id, 0, 0); extData = _vm->_game->loadExtData(id, 0, 0);
@ -1869,7 +1959,7 @@ void Inter_v2::o2_initMult(void) {
if (_vm->_mult->_objects == 0) { if (_vm->_mult->_objects == 0) {
_vm->_mult->_renderData2 = new Mult::Mult_Object*[_vm->_mult->_objCount]; _vm->_mult->_renderData2 = new Mult::Mult_Object*[_vm->_mult->_objCount];
memset(_vm->_mult->_renderData2, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object*)); memset(_vm->_mult->_renderData2, 0, _vm->_mult->_objCount * sizeof(Mult::Mult_Object*));
if (_vm->_inter->_terminate) if (_terminate)
return; return;
_vm->_mult->_orderArray = new int8[_vm->_mult->_objCount]; _vm->_mult->_orderArray = new int8[_vm->_mult->_objCount];
memset(_vm->_mult->_orderArray, 0, _vm->_mult->_objCount * sizeof(int8)); memset(_vm->_mult->_orderArray, 0, _vm->_mult->_objCount * sizeof(int8));
@ -2115,15 +2205,15 @@ void Inter_v2::o2_playImd(void) {
} }
void Inter_v2::o2_initScreen(void) { void Inter_v2::o2_initScreen(void) {
int16 start; int16 offY;
int16 videoMode; int16 videoMode;
int16 width; int16 width;
int16 height; int16 height;
start = load16(); offY = load16();
videoMode = start & 0xFF; videoMode = offY & 0xFF;
start = (start >> 8) & 0xFF; offY = (offY >> 8) & 0xFF;
width = _vm->_parse->parseValExpr(); width = _vm->_parse->parseValExpr();
height = _vm->_parse->parseValExpr(); height = _vm->_parse->parseValExpr();
@ -2131,7 +2221,10 @@ void Inter_v2::o2_initScreen(void) {
if ((videoMode == _vm->_global->_videoMode) && (width == -1)) if ((videoMode == _vm->_global->_videoMode) && (width == -1))
return; return;
_vm->_video->_surfWidth = videoMode == 0x14 ? 640 : 320; if (width > 0)
_vm->_video->_surfWidth = width;
if (height > 0)
_vm->_video->_surfHeight = height;
_vm->_draw->closeScreen(); _vm->_draw->closeScreen();
_vm->_util->clearPalette(); _vm->_util->clearPalette();
@ -2153,36 +2246,27 @@ void Inter_v2::o2_initScreen(void) {
_vm->_global->_setAllPalette = 1; _vm->_global->_setAllPalette = 1;
if ((width != -1) && (_vm->_global->_videoMode == 0x14)) { if ((width != -1) && (_vm->_global->_videoMode == 0x14))
_vm->_game->_byte_2FC9B = 1; _vm->_game->_byte_2FC9B = 1;
/*
if (width > 960)
width = 960;
_vm->_draw->_frontSurface->width = width;
_vm->_draw->_frontSurface->height = height;
warning("GOB2 Stub! _vid_setVirtRes(_vm->_draw->_frontSurface);");
_vm->_global->_mouseMaxCol = width;
_vm->_global->_mouseMaxRow = height;
*/
}
_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
_vm->_util->clearPalette(); _vm->_util->clearPalette();
if (start == 0) // Split screen (word_2E51F ^= splitScreenHeight, off_2E51B ^= splitScreenSurf)?
if (offY == 0)
_vm->_draw->_word_2E51F = 0; _vm->_draw->_word_2E51F = 0;
else else
_vm->_draw->_word_2E51F = _vm->_global->_primaryHeight - start; _vm->_draw->_word_2E51F = _vm->_global->_primaryHeight - offY;
_vm->_draw->initScreen(); _vm->_draw->initScreen();
if (_vm->_draw->_off_2E51B != 0) { _vm->_util->setScrollOffset();
_vm->_video->_scrollOffset = 0;
/* /*
warning("_vid_setSplit(%d)", _vm->_global->_primaryHeight - start); if (_vm->_draw->_off_2E51B != 0) {
warning("_vid_setPixelShift(0, %d", start); warning("_vid_setSplit(%d)", _vm->_global->_primaryHeight - offY);
*/ warning("_vid_setPixelShift(0, %d", offY);
} }
*/
} }
void Inter_v2::o2_setScrollOffset(void) { void Inter_v2::o2_setScrollOffset(void) {
@ -2194,20 +2278,24 @@ void Inter_v2::o2_setScrollOffset(void) {
if (_vm->_game->_byte_2FC9B != 0) if (_vm->_game->_byte_2FC9B != 0)
_vm->_game->_byte_2FC9B = 1; _vm->_game->_byte_2FC9B = 1;
_vm->_parse->parseValExpr(); _vm->_parse->parseValExpr();
WRITE_VAR(2, _vm->_draw->_word_2FC9E); WRITE_VAR(2, _vm->_draw->_scrollOffsetX);
WRITE_VAR(3, _vm->_draw->_word_2FC9C); WRITE_VAR(3, _vm->_draw->_scrollOffsetY);
} else { } else {
_vm->_draw->_word_2FC9E = offset; _vm->_draw->_scrollOffsetX = offset;
_vm->_draw->_word_2FC9C = _vm->_parse->parseValExpr(); _vm->_draw->_scrollOffsetY = _vm->_parse->parseValExpr();
} }
_vm->_util->setScrollOffset(_vm->_draw->_word_2FC9E); if (_vm->_draw->_off_2E51B != 0)
_vm->_util->setScrollOffset(_vm->_draw->_scrollOffsetX,
_vm->_draw->_scrollOffsetY + 200 - _vm->_draw->_word_2E51F);
else
_vm->_util->setScrollOffset();
_noBusyWait = true; _noBusyWait = true;
/* /*
if (_vm->_draw->_off_2E51B != 0) if (_vm->_draw->_off_2E51B != 0)
warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C + 200 - _vm->_draw->_word_2E51F); warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_scrollOffsetX, _vm->_draw->_scrollOffsetY + 200 - _vm->_draw->_word_2E51F);
else else
warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_word_2FC9E, _vm->_draw->_word_2FC9C);; warning("_vid_setPixelShift(%d, %d)", _vm->_draw->_scrollOffsetX, _vm->_draw->_scrollOffsetY);;
*/ */
} }
@ -2228,16 +2316,14 @@ void Inter_v2::o2_scroll(void) {
stepX = _vm->_parse->parseValExpr(); stepX = _vm->_parse->parseValExpr();
stepY = _vm->_parse->parseValExpr(); stepY = _vm->_parse->parseValExpr();
if ((stepY != 0) || (startY > 0) || (endY > 0))
warning("GOB2 Stub! Vertical scrolling / high surfaces");
curX = startX; curX = startX;
curY = startY; curY = startY;
while (!_vm->_quitRequested && ((curX != endX) || (curY != endY))) { while (!_vm->_quitRequested && ((curX != endX) || (curY != endY))) {
curX = stepX > 0 ? MIN(curX + stepX, (int) endX) : MAX(curX + stepX, (int) endX); curX = stepX > 0 ? MIN(curX + stepX, (int) endX) : MAX(curX + stepX, (int) endX);
curY = stepY > 0 ? MIN(curY + stepY, (int) endY) : MAX(curY + stepY, (int) endY); curY = stepY > 0 ? MIN(curY + stepY, (int) endY) : MAX(curY + stepY, (int) endY);
_vm->_draw->_word_2FC9E = curX; _vm->_draw->_scrollOffsetX = curX;
_vm->_util->setScrollOffset(_vm->_draw->_word_2FC9E); _vm->_draw->_scrollOffsetY = curY;
_vm->_util->setScrollOffset();
} }
} }

View file

@ -424,7 +424,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_vm->_anim->_areaTop = 0; _vm->_anim->_areaTop = 0;
_vm->_anim->_areaLeft = 0; _vm->_anim->_areaLeft = 0;
_vm->_anim->_areaWidth = _vm->_video->_surfWidth; _vm->_anim->_areaWidth = _vm->_video->_surfWidth;
_vm->_anim->_areaHeight = 200; _vm->_anim->_areaHeight = _vm->_video->_surfHeight;
_objCount = 4; _objCount = 4;
if (_objects) if (_objects)
@ -478,7 +478,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_vm->_draw->_spriteLeft = 0; _vm->_draw->_spriteLeft = 0;
_vm->_draw->_spriteTop = 0; _vm->_draw->_spriteTop = 0;
_vm->_draw->_spriteRight = _vm->_video->_surfWidth; _vm->_draw->_spriteRight = _vm->_video->_surfWidth;
_vm->_draw->_spriteBottom = 200; _vm->_draw->_spriteBottom = _vm->_video->_surfHeight;
_vm->_draw->_transparency = 0; _vm->_draw->_transparency = 0;
_vm->_draw->spriteOperation(0); _vm->_draw->spriteOperation(0);
_animDataAllocated = 1; _animDataAllocated = 1;
@ -609,7 +609,7 @@ char Mult_v2::drawStatics(char stop) {
_vm->_draw->_spriteLeft = 0; _vm->_draw->_spriteLeft = 0;
_vm->_draw->_spriteTop = 0; _vm->_draw->_spriteTop = 0;
_vm->_draw->_spriteRight = _vm->_video->_surfWidth; _vm->_draw->_spriteRight = _vm->_video->_surfWidth;
_vm->_draw->_spriteBottom = 200; _vm->_draw->_spriteBottom = _vm->_video->_surfHeight;
_vm->_draw->_transparency = 0; _vm->_draw->_transparency = 0;
_vm->_draw->spriteOperation(0); _vm->_draw->spriteOperation(0);
} }

View file

@ -494,9 +494,10 @@ void Util::forceMouseUp(void) {
_mouseButtons = 0; _mouseButtons = 0;
} }
void Util::setScrollOffset(int16 scrollOffset) { void Util::setScrollOffset(int16 x, int16 y) {
processInput(); processInput();
_vm->_video->_scrollOffset = scrollOffset; _vm->_video->_scrollOffsetX = x >= 0 ? x : _vm->_draw->_scrollOffsetX;
_vm->_video->_scrollOffsetY = y >= 0 ? y : _vm->_draw->_scrollOffsetY;
_vm->_video->waitRetrace(_vm->_global->_videoMode); _vm->_video->waitRetrace(_vm->_global->_videoMode);
} }

View file

@ -84,7 +84,7 @@ public:
static void prepareStr(char *str); static void prepareStr(char *str);
void waitMouseRelease(char drawMouse); void waitMouseRelease(char drawMouse);
void forceMouseUp(void); void forceMouseUp(void);
void setScrollOffset(int16 scrollOffset); void setScrollOffset(int16 x = -1, int16 y = -1);
static const char trStr1[]; static const char trStr1[];
static const char trStr2[]; static const char trStr2[];

View file

@ -38,7 +38,9 @@ namespace Gob {
Video::Video(GobEngine *vm) : _vm(vm) { Video::Video(GobEngine *vm) : _vm(vm) {
_videoDriver = 0; _videoDriver = 0;
_surfWidth = 320; _surfWidth = 320;
_scrollOffset = 0; _surfHeight = 200;
_scrollOffsetX = 0;
_scrollOffsetY = 0;
} }
char Video::initDriver(int16 vidMode) { char Video::initDriver(int16 vidMode) {
@ -396,7 +398,7 @@ void Video::initPrimary(int16 mode) {
Video::initDriver(mode); Video::initDriver(mode);
if (mode != 3) { if (mode != 3) {
initSurfDesc(mode, _surfWidth, 200, PRIMARY_SURFACE); initSurfDesc(mode, _surfWidth, _vm->_video->_surfHeight, PRIMARY_SURFACE);
if (_vm->_global->_dontSetPalette) if (_vm->_global->_dontSetPalette)
return; return;

View file

@ -91,7 +91,9 @@ public:
}; };
int16 _surfWidth; int16 _surfWidth;
int16 _scrollOffset; int16 _surfHeight;
int16 _scrollOffsetX;
int16 _scrollOffsetY;
Video(class GobEngine *vm); Video(class GobEngine *vm);
virtual ~Video() {}; virtual ~Video() {};

View file

@ -45,8 +45,9 @@ void Video_v2::waitRetrace(int16, bool mouse) {
CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0); CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
if (_vm->_draw->_frontSurface) { if (_vm->_draw->_frontSurface) {
time = _vm->_util->getTimeKey(); time = _vm->_util->getTimeKey();
g_system->copyRectToScreen(_vm->_draw->_frontSurface->vidPtr + _scrollOffset, g_system->copyRectToScreen(_vm->_draw->_frontSurface->vidPtr +
_surfWidth, 0, 0, 320, 200); _scrollOffsetY * _surfWidth + _scrollOffsetX, _surfWidth,
0, 0, 320, 200);
g_system->updateScreen(); g_system->updateScreen();
_vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time))); _vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time)));
} }
@ -136,8 +137,8 @@ Video::SurfaceDesc *Video_v2::initSurfDesc(int16 vidMode, int16 width, int16 hei
assert(descPtr); assert(descPtr);
if (descPtr->vidPtr != 0) if (descPtr->vidPtr != 0)
delete[] descPtr->vidPtr; delete[] descPtr->vidPtr;
vidMem = new byte[_surfWidth * 200]; vidMem = new byte[_surfWidth * _surfHeight];
memset(vidMem, 0, _surfWidth * 200); memset(vidMem, 0, _surfWidth * _surfHeight);
} else { } else {
if (flags & DISABLE_SPR_ALLOC) { if (flags & DISABLE_SPR_ALLOC) {
descPtr = new SurfaceDesc; descPtr = new SurfaceDesc;