aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2005-11-10 14:08:50 +0000
committerJohannes Schickel2005-11-10 14:08:50 +0000
commitdd4e750640b7d12b4d5c16483732280459ae80d2 (patch)
tree556271d04e41d8e55b896d00178a8133bfb06626
parent87a868eda55db4af1181d3286e06aa084b6cdb24 (diff)
downloadscummvm-rg350-dd4e750640b7d12b4d5c16483732280459ae80d2.tar.gz
scummvm-rg350-dd4e750640b7d12b4d5c16483732280459ae80d2.tar.bz2
scummvm-rg350-dd4e750640b7d12b4d5c16483732280459ae80d2.zip
Commited patch #1350510 with some little changes. Thanks to vinterstum.
svn-id: r19548
-rw-r--r--kyra/kyra.cpp825
-rw-r--r--kyra/kyra.h48
-rw-r--r--kyra/screen.cpp156
-rw-r--r--kyra/screen.h11
-rw-r--r--kyra/script_v1.cpp55
-rw-r--r--kyra/sprites.cpp235
-rw-r--r--kyra/sprites.h24
7 files changed, 862 insertions, 492 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp
index 9da78b8495..a1f5915bc2 100644
--- a/kyra/kyra.cpp
+++ b/kyra/kyra.cpp
@@ -285,7 +285,7 @@ int KyraEngine::init(GameDetector &detector) {
_animStates = new AnimObject[31];
assert(_animStates);
_charactersAnimState = &_animStates[0];
- _animObjects = &_animStates[5];
+ _sprites->_animObjects = &_animStates[5];
_animItems = &_animStates[16];
_scriptInterpreter = new ScriptHelper(this);
@@ -308,6 +308,8 @@ int KyraEngine::init(GameDetector &detector) {
memset(_shapes, 0, sizeof(_shapes));
memset(_wsaObjects, 0, sizeof(_wsaObjects));
+ memset(_flagsTable, 0, sizeof(_flagsTable));
+
_fastMode = false;
_talkCoords.y = 0x88;
_talkCoords.x = 0;
@@ -315,9 +317,9 @@ int KyraEngine::init(GameDetector &detector) {
_talkMessageY = 0xC;
_talkMessageH = 0;
_talkMessagePrinted = false;
-
+ _charSayUnk1 = -1;
+ _charSayUnk3 = -1;
_mouseX = _mouseY = -1;
- _needMouseUpdate = true;
_brandonPosX = _brandonPosY = -1;
_brandonDrawFrame = 113;
@@ -326,13 +328,15 @@ int KyraEngine::init(GameDetector &detector) {
memset(_exitList, 0xFFFF, sizeof(_exitList));
_exitListPtr = 0;
_pathfinderFlag = 0;
-
+ _lastFindWayRet = 0;
_sceneChangeState = _loopFlag2 = 0;
_movFacingTable = new int[150];
assert(_movFacingTable);
_movFacingTable[0] = 8;
+ _configTalkspeed = 1;
+
return 0;
}
@@ -368,6 +372,7 @@ KyraEngine::~KyraEngine() {
for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) {
free(_sceneAnimTable[i]);
}
+
}
void KyraEngine::errorString(const char *buf1, char *buf2) {
@@ -390,11 +395,15 @@ int KyraEngine::go() {
if (_features & GF_DEMO) {
seq_demo();
} else {
+ setGameFlag(0xF3);
+ setGameFlag(0xFD);
+ setGameFlag(0xEF);
seq_intro();
startup();
+ resetGameFlag(0xEF);
mainLoop();
}
- res_unloadResources();
+ quitGame();
return 0;
}
@@ -445,9 +454,8 @@ void KyraEngine::startup() {
// XXX
initAnimStateList();
setCharactersInDefaultScene();
-
+
_gameSpeed = 50;
- memset(_flagsTable, 0, sizeof(_flagsTable));
if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, _opcodeTable, _opcodeTableSize, 0)) {
error("Could not load \"_STARTUP.EMC\" script");
@@ -488,7 +496,6 @@ void KyraEngine::delay(uint32 amount) {
case OSystem::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
- _needMouseUpdate = true;
break;
case OSystem::EVENT_QUIT:
_quitFlag = true;
@@ -506,20 +513,27 @@ void KyraEngine::delay(uint32 amount) {
void KyraEngine::mainLoop() {
debug(9, "KyraEngine::mainLoop()");
+ //enterNewScene(0x0, _currentCharacter->facing, 0, 0, 1);
+
while (!_quitFlag) {
int32 frameTime = (int32)_system->getMillis();
- if (_needMouseUpdate) {
- _screen->hideMouse();
- _screen->showMouse();
- _needMouseUpdate = false;
- }
- _screen->updateScreen();
+ _sprites->updateSceneAnims();
+ updateAllObjectShapes();
delay((frameTime + _gameSpeed) - _system->getMillis());
}
}
+void KyraEngine::quitGame() {
+ res_unloadResources();
+
+ for (int i = 0; i < 10; i++)
+ wsa_close(_wsaObjects[i]);
+
+ _system->quit();
+}
+
void KyraEngine::loadPalette(const char *filename, uint8 *palData) {
debug(9, "KyraEngine::loadPalette('%s' 0x%X)", filename, palData);
uint32 fileSize = 0;
@@ -529,6 +543,7 @@ void KyraEngine::loadPalette(const char *filename, uint8 *palData) {
debug(9, "Loading a palette of size %i from '%s'", fileSize, filename);
memcpy(palData, srcData, fileSize);
}
+ delete[] srcData;
}
void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) {
@@ -561,186 +576,6 @@ void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uin
delete[] srcData;
}
-void KyraEngine::setTalkCoords(uint16 y) {
- debug(9, "KyraEngine::setTalkCoords(%d)", y);
- _talkCoords.y = y;
-}
-
-int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
- debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
- _screen->_charWidth = -2;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- int strWidth = _screen->getTextWidth(str);
- _screen->setFont(curFont);
- _screen->_charWidth = 0;
- int w = x2 - x1 + 1;
- return x1 + (w - strWidth) / 2;
-}
-
-int KyraEngine::getCharLength(const char *str, int len) {
- debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
- int charsCount = 0;
- if (*str) {
- _screen->_charWidth = -2;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- int i = 0;
- while (i <= len && *str) {
- i += _screen->getCharWidth(*str++);
- ++charsCount;
- }
- _screen->setFont(curFont);
- _screen->_charWidth = 0;
- }
- return charsCount;
-}
-
-int KyraEngine::dropCRIntoString(char *str, int offs) {
- debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
- int pos = 0;
- str += offs;
- while (*str) {
- if (*str == ' ') {
- *str = '\r';
- return pos;
- }
- ++str;
- ++pos;
- }
- return 0;
-}
-
-char *KyraEngine::preprocessString(const char *str) {
- debug(9, "KyraEngine::preprocessString('%s')", str);
- assert(strlen(str) < sizeof(_talkBuffer) - 1);
- strcpy(_talkBuffer, str);
- char *p = _talkBuffer;
- while (*p) {
- if (*p == '\r') {
- return _talkBuffer;
- }
- ++p;
- }
- p = _talkBuffer;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- _screen->_charWidth = -2;
- int textWidth = _screen->getTextWidth(p);
- _screen->_charWidth = 0;
- if (textWidth > 176) {
- if (textWidth > 352) {
- int count = getCharLength(p, textWidth / 3);
- int offs = dropCRIntoString(p, count);
- p += count + offs;
- _screen->_charWidth = -2;
- textWidth = _screen->getTextWidth(p);
- _screen->_charWidth = 0;
- count = getCharLength(p, textWidth / 2);
- dropCRIntoString(p, count);
- } else {
- int count = getCharLength(p, textWidth / 2);
- dropCRIntoString(p, count);
- }
- }
- _screen->setFont(curFont);
- return _talkBuffer;
-}
-
-int KyraEngine::buildMessageSubstrings(const char *str) {
- debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
- int currentLine = 0;
- int pos = 0;
- while (*str) {
- if (*str == '\r') {
- assert(currentLine < TALK_SUBSTRING_NUM);
- _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
- ++currentLine;
- pos = 0;
- } else {
- _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
- ++pos;
- if (pos > TALK_SUBSTRING_LEN - 2) {
- pos = TALK_SUBSTRING_LEN - 2;
- }
- }
- ++str;
- }
- _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
- return currentLine + 1;
-}
-
-int KyraEngine::getWidestLineWidth(int linesCount) {
- debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
- int maxWidth = 0;
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- _screen->_charWidth = -2;
- for (int l = 0; l < linesCount; ++l) {
- int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
- if (maxWidth < w) {
- maxWidth = w;
- }
- }
- _screen->setFont(curFont);
- _screen->_charWidth = 0;
- return maxWidth;
-}
-
-void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
- debug(9, "KyraEngine::calcWidestLineBounds(%d, %d)", w, cx);
- x1 = cx - w / 2;
- if (x1 + w >= Screen::SCREEN_W - 12) {
- x1 = Screen::SCREEN_W - 12 - w - 1;
- } else if (x1 < 12) {
- x1 = 12;
- }
- x2 = x1 + w + 1;
-}
-
-void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
- debug(9, "KyraEngine::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
- if (_talkMessagePrinted) {
- _talkMessagePrinted = false;
- _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
- }
-}
-
-void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
- debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
- char *str = preprocessString(text);
- int lineCount = buildMessageSubstrings(str);
- int top = y - lineCount * 10;
- if (top < 0) {
- top = 0;
- }
- _talkMessageY = top;
- _talkMessageH = lineCount * 10;
- int w = getWidestLineWidth(lineCount);
- int x1, x2;
- calcWidestLineBounds(x1, x2, w, x);
- _talkCoords.x = x1;
- _talkCoords.w = w + 2;
- _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
- int curPage = _screen->_curPage;
- _screen->_curPage = srcPage;
- for (int i = 0; i < lineCount; ++i) {
- top = i * 10 + _talkMessageY;
- char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
- int left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, color, 0xC, 0);
- }
- _screen->_curPage = curPage;
- _talkMessagePrinted = true;
-}
-
-void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
- uint8 colorMap[] = { 0, 15, 12, 12 };
- colorMap[3] = c1;
- _screen->setTextColor(colorMap, 0, 3);
- Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
- _screen->_charWidth = -2;
- _screen->printText(str, x, y, c0, c2);
- _screen->_charWidth = 0;
- _screen->setFont(curFont);
-}
-
void KyraEngine::waitTicks(int ticks) {
debug(9, "KyraEngine::waitTicks(%d)", ticks);
const uint32 end = _system->getMillis() + ticks * 1000 / 60;
@@ -750,6 +585,7 @@ void KyraEngine::waitTicks(int ticks) {
switch (event.type) {
case OSystem::EVENT_QUIT:
_quitFlag = true;
+ quitGame();
break;
case OSystem::EVENT_KEYDOWN:
if (event.kbd.flags == OSystem::KBD_CTRL) {
@@ -1331,7 +1167,8 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int
char datFileNameBuffer[32];
strcpy(datFileNameBuffer, _roomFilenameTable[tableId]);
strcat(datFileNameBuffer, ".DAT");
- _sprites->loadDAT(datFileNameBuffer);
+ _sprites->loadDAT(datFileNameBuffer, _sceneExits);
+ _sprites->setupSceneAnims();
_scriptInterpreter->unloadScript(_scriptClickData);
loadSceneMSC();
@@ -1940,11 +1777,38 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
}
for (int i = 0; i < 11; ++i) {
- curAnimState = &_animObjects[i];
- curAnimState->active = 0;
- curAnimState->refreshFlag = 0;
- curAnimState->bkgdChangeFlag = 0;
- // XXX this needs the dat loader
+ curAnimState = &_sprites->_animObjects[i];
+
+ if (_sprites->_anims[i].play) {
+ curAnimState->active = 1;
+ curAnimState->refreshFlag = 1;
+ curAnimState->bkgdChangeFlag = 1;
+ }
+ else {
+ curAnimState->active = 0;
+ curAnimState->refreshFlag = 0;
+ curAnimState->bkgdChangeFlag = 0;
+ }
+ curAnimState->height = _sprites->_anims[i].height;
+ curAnimState->height2 = _sprites->_anims[i].height2;
+ curAnimState->width = _sprites->_anims[i].width + 1;
+ curAnimState->width2 = _sprites->_anims[i].width2;
+ curAnimState->drawY = _sprites->_anims[i].drawY;
+ curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x;
+ curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y;
+ curAnimState->background = _sprites->_anims[i].background;
+ curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite];
+
+ if(_sprites->_anims[i].unk2)
+ curAnimState->flags = 0x800;
+ else
+ curAnimState->flags = 0;
+
+ if (_sprites->_anims[i].flipX)
+ curAnimState->flags |= 0x1;
+
+ _objectQueue = objectQueue(_objectQueue, curAnimState);
+
}
for (int i = 0; i < 12; ++i) {
@@ -1991,11 +1855,509 @@ void KyraEngine::initSceneObjectList(int brandonAlive) {
preserveAnyChangedBackgrounds();
prepDrawAllObjects();
_screen->hideMouse();
- // XXX game_unkScreen
+ initSceneScreen(brandonAlive);
_screen->showMouse();
copyChangedObjectsForward(0);
}
+void KyraEngine::initSceneScreen(int brandonAlive) {
+ // XXX (Pointless?) Palette stuff
+ //_screen->shuffleScreen(8, 8, 0x130, 0x80, 2, 0, byte_2EE1C);
+ _screen->copyRegion(1, 8, 1, 8, 304, 0x80, 2, 0);
+ // XXX More (pointless?) palette stuff
+
+ if (!_scriptInterpreter->startScript(_scriptClick, 2))
+ error("Could not start script function 2 of scene script");
+
+ _scriptClick->variables[7] = brandonAlive;
+
+ while (_scriptInterpreter->validScript(_scriptClick))
+ _scriptInterpreter->runScript(_scriptClick);
+
+ if (_currentCharacter->sceneId == 0xD2) {
+ // XXX
+ }
+}
+
+#pragma mark -
+#pragma mark - Item handling
+#pragma mark -
+
+void KyraEngine::setTalkCoords(uint16 y) {
+ debug(9, "KyraEngine::setTalkCoords(%d)", y);
+ _talkCoords.y = y;
+}
+
+int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
+ debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
+ _screen->_charWidth = -2;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ int strWidth = _screen->getTextWidth(str);
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ int w = x2 - x1 + 1;
+ return x1 + (w - strWidth) / 2;
+}
+
+int KyraEngine::getCharLength(const char *str, int len) {
+ debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
+ int charsCount = 0;
+ if (*str) {
+ _screen->_charWidth = -2;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ int i = 0;
+ while (i <= len && *str) {
+ i += _screen->getCharWidth(*str++);
+ ++charsCount;
+ }
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ }
+ return charsCount;
+}
+
+int KyraEngine::dropCRIntoString(char *str, int offs) {
+ debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
+ int pos = 0;
+ str += offs;
+ while (*str) {
+ if (*str == ' ') {
+ *str = '\r';
+ return pos;
+ }
+ ++str;
+ ++pos;
+ }
+ return 0;
+}
+
+char *KyraEngine::preprocessString(const char *str) {
+ debug(9, "KyraEngine::preprocessString('%s')", str);
+ assert(strlen(str) < sizeof(_talkBuffer) - 1);
+ strcpy(_talkBuffer, str);
+ char *p = _talkBuffer;
+ while (*p) {
+ if (*p == '\r') {
+ return _talkBuffer;
+ }
+ ++p;
+ }
+ p = _talkBuffer;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ int textWidth = _screen->getTextWidth(p);
+ _screen->_charWidth = 0;
+ if (textWidth > 176) {
+ if (textWidth > 352) {
+ int count = getCharLength(p, textWidth / 3);
+ int offs = dropCRIntoString(p, count);
+ p += count + offs;
+ _screen->_charWidth = -2;
+ textWidth = _screen->getTextWidth(p);
+ _screen->_charWidth = 0;
+ count = getCharLength(p, textWidth / 2);
+ dropCRIntoString(p, count);
+ } else {
+ int count = getCharLength(p, textWidth / 2);
+ dropCRIntoString(p, count);
+ }
+ }
+ _screen->setFont(curFont);
+ return _talkBuffer;
+}
+
+int KyraEngine::buildMessageSubstrings(const char *str) {
+ debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
+ int currentLine = 0;
+ int pos = 0;
+ while (*str) {
+ if (*str == '\r') {
+ assert(currentLine < TALK_SUBSTRING_NUM);
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
+ ++currentLine;
+ pos = 0;
+ } else {
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
+ ++pos;
+ if (pos > TALK_SUBSTRING_LEN - 2) {
+ pos = TALK_SUBSTRING_LEN - 2;
+ }
+ }
+ ++str;
+ }
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
+ return currentLine + 1;
+}
+
+int KyraEngine::getWidestLineWidth(int linesCount) {
+ debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
+ int maxWidth = 0;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ for (int l = 0; l < linesCount; ++l) {
+ int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
+ if (maxWidth < w) {
+ maxWidth = w;
+ }
+ }
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ return maxWidth;
+}
+
+void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
+ debug(9, "KyraEngine::calcWidestLineBounds(%d, %d)", w, cx);
+ x1 = cx - w / 2;
+ if (x1 + w >= Screen::SCREEN_W - 12) {
+ x1 = Screen::SCREEN_W - 12 - w - 1;
+ } else if (x1 < 12) {
+ x1 = 12;
+ }
+ x2 = x1 + w + 1;
+}
+
+void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
+ debug(9, "KyraEngine::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
+ if (_talkMessagePrinted) {
+ _talkMessagePrinted = false;
+ _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
+ }
+}
+
+void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
+ debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
+ char *str = preprocessString(text);
+ int lineCount = buildMessageSubstrings(str);
+ int top = y - lineCount * 10;
+ if (top < 0) {
+ top = 0;
+ }
+ _talkMessageY = top;
+ _talkMessageH = lineCount * 10;
+ int w = getWidestLineWidth(lineCount);
+ int x1, x2;
+ calcWidestLineBounds(x1, x2, w, x);
+ _talkCoords.x = x1;
+ _talkCoords.w = w + 2;
+ _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
+ int curPage = _screen->_curPage;
+ _screen->_curPage = srcPage;
+ for (int i = 0; i < lineCount; ++i) {
+ top = i * 10 + _talkMessageY;
+ char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
+ int left = getCenterStringX(msg, x1, x2);
+ printText(msg, left, top, color, 0xC, 0);
+ }
+ _screen->_curPage = curPage;
+ _talkMessagePrinted = true;
+}
+
+void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
+ uint8 colorMap[] = { 0, 15, 12, 12 };
+ colorMap[3] = c1;
+ _screen->setTextColor(colorMap, 0, 3);
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ _screen->printText(str, x, y, c0, c2);
+ _screen->_charWidth = 0;
+ _screen->setFont(curFont);
+}
+
+void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 charNum) {
+ debug(9, "KyraEngine::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum);
+ bool hasUpdatedNPCs = false;
+ bool runLoop = true;
+ uint8 currPage;
+ OSystem::Event event;
+ uint8 tickLength = (uint8)(1000.0 / _gameSpeed);
+
+ //while( towns_isEscKeyPressed() )
+ //towns_getKey();
+
+ uint32 timeToEnd = strlen(chatStr) * 8 * tickLength + _system->getMillis();
+
+ if (chatDuration != -1 ) {
+ switch ( _configTalkspeed) {
+ case 0: chatDuration *= 2;
+ break;
+ case 2: chatDuration /= 4;
+ break;
+ case 3: chatDuration = -1;
+ }
+ }
+
+ if (chatDuration != -1)
+ chatDuration *= tickLength;
+
+ //disableTimer(0x13);
+ //disableTimer(0x0E);
+ //disableTimer(0x12);
+ //towns_flushKeyb();
+
+ uint32 timeAtStart = _system->getMillis();
+ uint32 loopStart;
+ while (runLoop) {
+ loopStart = _system->getMillis();
+ /*
+ if (_currentCharacter.sceneId == 0xD2)
+ if (seq_playEnd())
+ break;
+ */
+
+ if( _system->getMillis() < timeToEnd && !hasUpdatedNPCs) {
+ hasUpdatedNPCs = true;
+ //disableTimer(0x0F);
+ _charSayUnk4 = 4;
+ animRefreshNPC(0);
+ animRefreshNPC(_charSayUnk1);
+
+ if (_charSayUnk2 != -1) {
+ _sprites->_animObjects[_charSayUnk2].active = 0;
+ _sprites->_anims[_charSayUnk2].play = false;
+ _charSayUnk2 = -1;
+ }
+ }
+
+ //updateGameTimers();
+ _sprites->updateSceneAnims();
+ restoreAllObjectBackgrounds();
+ preserveAnyChangedBackgrounds();
+ prepDrawAllObjects();
+
+ currPage = _screen->_curPage;
+ _screen->_curPage = 2;
+ printCharacterText(chatStr, charNum);
+ _screen->_curPage = currPage;
+
+ copyChangedObjectsForward(0);
+ //processPalette();
+
+ if ((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1)
+ break;
+
+ while (_system->pollEvent(event)) {
+ switch (event.type) {
+ case OSystem::EVENT_KEYDOWN:
+ if (event.kbd.keycode == 0x20 || event.kbd.keycode == 0xC6)
+ runLoop = false;
+ break;
+ case OSystem::EVENT_QUIT:
+ quitGame();
+ case OSystem::EVENT_LBUTTONDOWN:
+ runLoop = false;
+ break;
+ default:
+ break;
+ }
+ }
+ delay((loopStart + _gameSpeed) - _system->getMillis());
+ }
+
+ /*enableTimer(0x13);
+ enableTimer(0x0E);
+ enableTimer(0x12);
+ enableTimer(0x0F);
+ clearKyrandiaButtonIO();*/
+}
+
+void KyraEngine::endCharacterChat(int8 charNum, int16 convoInitialized) {
+ _charSayUnk3 = -1;
+
+ if (charNum > 4 && charNum < 11) {
+ //TODO: weird _game_inventory stuff here
+ }
+
+ if (convoInitialized != 0) {
+ _charSayUnk1 = -1;
+ _currentCharacter->currentAnimFrame = 7;
+ animRefreshNPC(0);
+ updateAllObjectShapes();
+ }
+}
+
+void KyraEngine::restoreChatPartnerAnimFrame(int8 charNum) {
+ _charSayUnk1 = -1;
+
+ if (charNum > 0 && charNum < 5) {
+ _characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame;
+ animRefreshNPC(charNum);
+ }
+
+ _currentCharacter->currentAnimFrame = 7;
+ animRefreshNPC(0);
+ updateAllObjectShapes();
+}
+
+void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
+ _charSayUnk1 = 0;
+
+ if (charNum < 5 && charNum > 0)
+ _currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame;
+
+ if (_scaleMode != 0)
+ _currentCharacter->currentAnimFrame = 7;
+ else
+ _currentCharacter->currentAnimFrame = _currentCharAnimFrame;
+
+ animRefreshNPC(0);
+ updateAllObjectShapes();
+}
+
+int8 KyraEngine::getChatPartnerNum() {
+ uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A};
+ int pos = 0;
+ int partner = -1;
+
+ for (int i = 1; i < 6; i++) {
+ if (_currentCharacter->sceneId == sceneTable[pos]) {
+ partner = sceneTable[pos+1];
+ break;
+ }
+ pos += 2;
+ }
+
+ for (int i = 1; i < 5; i++) {
+ if (_characterList[i].sceneId == _currentCharacter->sceneId) {
+ partner = i;
+ break;
+ }
+ }
+ return partner;
+}
+
+int KyraEngine::initCharacterChat(int8 charNum) {
+ if (_charSayUnk1 == -1) {
+ _charSayUnk1 = 0;
+
+ if (_scaleMode != 0)
+ _currentCharacter->currentAnimFrame = 7;
+ else
+ _currentCharacter->currentAnimFrame = 16;
+
+ animRefreshNPC(0);
+ updateAllObjectShapes();
+ }
+
+ _charSayUnk2 = -1;
+ flagAllObjectsForBkgdChange();
+ restoreAllObjectBackgrounds();
+
+ if( charNum > 4 && charNum < 11 ) {
+ // TODO: Fill in weird _game_inventory stuff here
+ }
+
+ flagAllObjectsForRefresh();
+ flagAllObjectsForBkgdChange();
+ preserveAnyChangedBackgrounds();
+ _charSayUnk3 = charNum;
+
+ return 1;
+}
+
+void KyraEngine::printCharacterText(char *text, int8 charNum) {
+ uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
+ int top, left, x1, x2, w, x;
+ char *msg;
+
+ uint8 color = colorTable[charNum];
+ text = preprocessString(text);
+ int lineCount = buildMessageSubstrings(text);
+ w = getWidestLineWidth(lineCount);
+ x = _characterList[charNum].x1;
+ calcWidestLineBounds(x1, x2, w, x);
+
+ for (int i = 0; i < lineCount; ++i) {
+ top = i * 10 + _talkMessageY;
+ msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
+ left = getCenterStringX(msg, x1, x2);
+ printText(msg, left, top, color, 0xC, 0);
+ }
+}
+
+void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
+ debug(9, "KyraEngine:::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
+ uint8 startAnimFrames[] = { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 };
+
+ uint16 chatTicks;
+ int16 convoInitialized;
+ int8 chatPartnerNum;
+
+ if (_currentCharacter->sceneId == 0xD2)
+ return;
+
+ convoInitialized = initCharacterChat(charNum);
+ chatPartnerNum = getChatPartnerNum();
+
+ if(chatPartnerNum != -1 && chatPartnerNum < 5)
+ backupChatPartnerAnimFrame(chatPartnerNum);
+
+ if (charNum < 5) {
+ _characterList[charNum].currentAnimFrame = startAnimFrames[charNum];
+ _charSayUnk3 = charNum;
+ _charSayUnk1 = charNum;
+ animRefreshNPC(charNum);
+ }
+
+ char *processedString = preprocessString(chatStr);
+ int lineNum = buildMessageSubstrings(processedString);
+
+ int16 YPos = _characterList[charNum].y1;
+ YPos -= _scaleTable[charNum] * _characterList[charNum].height;
+ YPos -= 8;
+ YPos -= lineNum * 10;
+
+ if (YPos < 11)
+ YPos = 11;
+
+ if (YPos > 100 )
+ YPos = 100;
+
+ _talkMessageY = YPos;
+ _talkMessageH = lineNum * 10;
+ restoreAllObjectBackgrounds();
+
+ _screen->copyRegion(1, _talkMessageY, 1, 136, 319, _talkMessageH, 2, 2);
+ _screen->hideMouse();
+
+ printCharacterText(processedString, charNum);
+ _screen->showMouse();
+
+ if (chatDuration == -2)
+ chatTicks = strlen(processedString) * 9;
+ else
+ chatTicks = chatDuration;
+
+ waitForChatToFinish(chatTicks, chatStr, charNum);
+
+ restoreAllObjectBackgrounds();
+
+ _screen->copyRegion(1, 136, 1, _talkMessageY, 319, _talkMessageH, 2, 2);
+ preserveAllBackgrounds();
+ prepDrawAllObjects();
+ _screen->hideMouse();
+
+ _screen->copyRegion(1, _talkMessageY, 1, _talkMessageY, 319, _talkMessageH, 2, 0);
+ _screen->showMouse();
+ flagAllObjectsForRefresh();
+ copyChangedObjectsForward(0);
+
+ if (chatPartnerNum != -1 && chatPartnerNum < 5)
+ restoreChatPartnerAnimFrame(chatPartnerNum);
+
+ endCharacterChat(charNum, convoInitialized);
+}
+
+void KyraEngine::drawSentenceCommand(char *sentence, int unk1) {
+ _screen->hideMouse();
+ _screen->fillRect(8, 143, 311, 152, 12);
+ // XXX: palette stuff
+
+ printText(sentence, 8, 143, 0xFF, 12, 0);
+ _screen->showMouse();
+ //setTextFadeTimerCountdown(_textFadeTimerCountdown);
+ //_palScrollEnabled = 0;
+}
+
#pragma mark -
#pragma mark - Item handling
#pragma mark -
@@ -2127,6 +2489,37 @@ void KyraEngine::placeItemInGenericMapScene(int item, int index) {
#pragma mark - Animation specific code
#pragma mark -
+void KyraEngine::preserveAllBackgrounds() {
+ uint8 currPage = _screen->_curPage;
+ _screen->_curPage = 2;
+
+ AnimObject *curObject = _objectQueue;
+ while (curObject) {
+ if (!curObject->active && curObject->flags) {
+ preserveOrRestoreBackground(curObject, false);
+ curObject->bkgdChangeFlag = 0;
+ }
+ curObject = curObject->nextAnimObject;
+ }
+ _screen->_curPage = currPage;
+}
+
+void KyraEngine::flagAllObjectsForBkgdChange() {
+ AnimObject *curObject = _objectQueue;
+ while (curObject) {
+ curObject->bkgdChangeFlag = 1;
+ curObject = curObject->nextAnimObject;
+ }
+}
+
+void KyraEngine::flagAllObjectsForRefresh() {
+ AnimObject *curObject = _objectQueue;
+ while (curObject) {
+ curObject->refreshFlag = 1;
+ curObject = curObject->nextAnimObject;
+ }
+}
+
void KyraEngine::restoreAllObjectBackgrounds() {
debug(9, "restoreAllObjectBackground()");
AnimObject *curObject = _objectQueue;
@@ -2207,7 +2600,7 @@ void KyraEngine::prepDrawAllObjects() {
flagUnk1 = 0x200;
if (_brandonStatusBit & 0x40)
flagUnk2 = 0x4000;
-
+
while (curObject) {
if (curObject->active) {
int xpos = curObject->x1;
@@ -2276,6 +2669,7 @@ void KyraEngine::prepDrawAllObjects() {
void KyraEngine::copyChangedObjectsForward(int refreshFlag) {
debug(9, "copyChangedObjectsForward(%d)", refreshFlag);
AnimObject *curObject = _objectQueue;
+
while (curObject) {
if (curObject->active) {
if (curObject->refreshFlag || refreshFlag) {
@@ -2291,6 +2685,7 @@ void KyraEngine::copyChangedObjectsForward(int refreshFlag) {
}
curObject = curObject->nextAnimObject;
}
+ _screen->updateScreen();
}
void KyraEngine::updateAllObjectShapes() {
@@ -2299,15 +2694,13 @@ void KyraEngine::updateAllObjectShapes() {
preserveAnyChangedBackgrounds();
prepDrawAllObjects();
copyChangedObjectsForward(0);
-
- _screen->updateScreen();
}
void KyraEngine::animRefreshNPC(int character) {
debug(9, "animRefreshNPC(%d)", character);
AnimObject *animObj = &_charactersAnimState[character];
Character *ch = &_characterList[character];
-
+
animObj->refreshFlag = 1;
animObj->bkgdChangeFlag = 1;
int facing = ch->facing;
@@ -2352,12 +2745,12 @@ void KyraEngine::animRefreshNPC(int character) {
}
animObj->width2 = 4;
animObj->height2 = 3;
-
+
_objectQueue = objectRemoveQueue(_objectQueue, animObj);
if (_objectQueue) {
-
+ _objectQueue = objectQueue(_objectQueue, animObj);
} else {
- _objectQueue = objectAddHead(_objectQueue, animObj);
+ _objectQueue = objectAddHead(0, animObj);
}
}
@@ -2368,6 +2761,7 @@ void KyraEngine::animRefreshNPC(int character) {
AnimObject *KyraEngine::objectRemoveQueue(AnimObject *queue, AnimObject *rem) {
AnimObject *cur = queue;
AnimObject *prev = queue;
+
while (cur != rem && cur) {
AnimObject *temp = cur->nextAnimObject;
if (!temp)
@@ -2383,10 +2777,12 @@ AnimObject *KyraEngine::objectRemoveQueue(AnimObject *queue, AnimObject *rem) {
}
if (!cur->nextAnimObject) {
- if (!prev) {
- return 0;
- } else {
- prev->nextAnimObject = 0;
+ if (cur == rem) {
+ if (!prev) {
+ return 0;
+ } else {
+ prev->nextAnimObject = 0;
+ }
}
} else {
if (cur == rem) {
@@ -2424,7 +2820,7 @@ AnimObject *KyraEngine::objectQueue(AnimObject *queue, AnimObject *add) {
cur->nextAnimObject = add;
add->nextAnimObject = 0;
}
- return 0;
+ return queue;
}
#pragma mark -
@@ -2937,7 +3333,8 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) {
if (!temp)
continue;
++table;
- // XXX updateAnimFlags
+ _sprites->updateSceneAnims();
+ waitTicks(10);
// XXX updateMousePointer
// XXX updateGameTimers
updateAllObjectShapes();
diff --git a/kyra/kyra.h b/kyra/kyra.h
index e90aada5de..1fb409ff7e 100644
--- a/kyra/kyra.h
+++ b/kyra/kyra.h
@@ -87,7 +87,7 @@ struct AnimObject {
uint32 flags;
int16 drawY;
uint8 *sceneAnimPtr;
- uint16 animFrameNumber;
+ int16 animFrameNumber;
uint8 *background;
uint16 rectSize;
int16 x1, y1;
@@ -167,13 +167,12 @@ public:
uint8 game() const { return _game; }
uint32 features() const { return _features; }
- SceneExits sceneExits() const { return _sceneExits; }
- // ugly hack used by the dat loader
- SceneExits &sceneExits() { return _sceneExits; }
Common::RandomSource _rnd;
int16 _northExitHeight;
+ Character *_currentCharacter;
+
typedef void (KyraEngine::*IntroProc)();
typedef int (KyraEngine::*OpcodeProc)(ScriptState *script);
@@ -183,16 +182,18 @@ public:
const char **seqTextsTable() { return (const char **)_seq_textsTable; }
bool seq_skipSequence() const;
-
+ void quitGame();
void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData);
void snd_playTheme(int file, int track = 0);
void snd_playTrack(int track);
void snd_playVoiceFile(int id);
bool snd_voicePlaying();
+ void snd_playSoundEffect(int track);
void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
+ void drawSentenceCommand(char *sentence, int unk1);
WSAMovieV1 *wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf);
void wsa_close(WSAMovieV1 *wsa);
@@ -200,6 +201,11 @@ public:
void wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum);
void waitTicks(int ticks);
+ void updateAllObjectShapes();
+ void flagAllObjectsForRefresh();
+ void animRefreshNPC(int character);
+ int16 fetchAnimWidth(const uint8 *shape, int16 mult);
+ int8 fetchAnimHeight(const uint8 *shape, int8 mult);
int mouseX() { return _mouseX; }
int mouseY() { return _mouseY; }
@@ -377,6 +383,15 @@ protected:
int getWidestLineWidth(int linesCount);
void calcWidestLineBounds(int &x1, int &x2, int w, int cx);
void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
+ void characterSays(char *msg, int8 charNum, int8 chatDuration);
+ int initCharacterChat(int8 charNum);
+ int8 getChatPartnerNum();
+ void backupChatPartnerAnimFrame(int8 charNum);
+ void restoreChatPartnerAnimFrame(int8 charNum);
+ void endCharacterChat(int8 charNum, int16 arg_4);
+ void waitForChatToFinish(int16 chatDuration, char *str, uint8 charNum);
+ void printCharacterText(char *text, int8 charNum);
+
void setCharacterDefaultFrame(int character);
void setCharactersPositions(int character);
void setCharactersHeight();
@@ -401,16 +416,15 @@ protected:
byte findItemAtPos(int x, int y);
void placeItemInGenericMapScene(int item, int index);
void initSceneObjectList(int brandonAlive);
+ void initSceneScreen(int brandonAlive);
+ void preserveAllBackgrounds();
+ void flagAllObjectsForBkgdChange();
void restoreAllObjectBackgrounds();
void preserveAnyChangedBackgrounds();
void preserveOrRestoreBackground(AnimObject *obj, bool restore);
void prepDrawAllObjects();
void copyChangedObjectsForward(int refreshFlag);
- void updateAllObjectShapes();
- void animRefreshNPC(int character);
int findDuplicateItemShape(int shape);
- int16 fetchAnimWidth(const uint8 *shape, int16 mult);
- int8 fetchAnimHeight(const uint8 *shape, int8 mult);
int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize);
int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end);
int getFacingFromPointToPoint(int x, int y, int toX, int toY);
@@ -424,7 +438,7 @@ protected:
AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem);
AnimObject *objectAddHead(AnimObject *queue, AnimObject *head);
AnimObject *objectQueue(AnimObject *queue, AnimObject *add);
-
+ AnimObject *_animStates;
void seq_demo();
void seq_intro();
void seq_introLogos();
@@ -438,7 +452,7 @@ protected:
void snd_startTrack();
void snd_haltTrack();
void snd_setSoundEffectFile(int file);
- void snd_playSoundEffect(int track);
+
static OpcodeProc _opcodeTable[];
static const int _opcodeTableSize;
@@ -509,6 +523,9 @@ protected:
int16 _brandonScaleX;
int16 _brandonScaleY;
int _brandonDrawFrame;
+
+ uint16 _currentChatPartnerBackupFrame;
+ uint16 _currentCharAnimFrame;
int8 *_sceneAnimTable[50];
@@ -528,10 +545,14 @@ protected:
int _lastFindWayRet;
int *_movFacingTable;
+ int8 _charSayUnk1; // this is byte_2EE24
+ int8 _charSayUnk2;
+ int8 _charSayUnk3; // this is byte_2EE25
+ int8 _charSayUnk4; // this is byte_2EE26
+
+ uint8 _configTalkspeed;
AnimObject *_objectQueue;
- AnimObject *_animStates;
AnimObject *_charactersAnimState;
- AnimObject *_animObjects;
AnimObject *_animItems;
int _curMusicTheme;
@@ -553,7 +574,6 @@ protected:
ScriptData *_scriptClickData;
Character *_characterList;
- Character *_currentCharacter;
uint8 *_seq_Forest;
uint8 *_seq_KallakWriting;
diff --git a/kyra/screen.cpp b/kyra/screen.cpp
index 342763dd4b..58eab34910 100644
--- a/kyra/screen.cpp
+++ b/kyra/screen.cpp
@@ -62,11 +62,6 @@ Screen::Screen(KyraEngine *vm, OSystem *system)
_decodeShapeBufferSize = 0;
_animBlockPtr = NULL;
_animBlockSize = 0;
- _mouseShape = NULL;
- _mouseShapeSize = 0;
- _mouseRect = NULL;
- _mouseRectSize = 0;
- _mouseDrawWidth = 0;
}
Screen::~Screen() {
@@ -75,15 +70,13 @@ Screen::~Screen() {
_pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0;
}
for (int f = 0; f < ARRAYSIZE(_fonts); ++f) {
- free(_fonts[f].fontData);
+ delete[] _fonts[f].fontData;
_fonts[f].fontData = NULL;
}
free(_currentPalette);
free(_screenPalette);
free(_decodeShapeBuffer);
free(_animBlockPtr);
- free(_mouseShape);
- free(_mouseRect);
for (int i = 0; i < 3; ++i) {
free(_palettes[i]);
}
@@ -305,6 +298,7 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint
void Screen::copyCurPageBlock(int x, int y, int h, int w, uint8 *dst) {
debug(9, "Screen::copyCurPageBlock(%d, %d, %d, %d, 0x%X)", x, y, w, h, dst);
+ assert(dst);
if (x < 0) {
x = 0;
} else if (x >= 40) {
@@ -389,6 +383,8 @@ void Screen::setAnimBlockPtr(int size) {
debug(9, "Screen::setAnimBlockPtr(%d)", size);
free(_animBlockPtr);
_animBlockPtr = (uint8 *)malloc(size);
+ assert(_animBlockPtr);
+ memset(_animBlockPtr, 0, size);
_animBlockSize = size;
}
@@ -1590,14 +1586,14 @@ void Screen::hideMouse() {
debug(9, "hideMouse()");
// if mouseDisabled
// return
- restoreMouseRect();
+ _system->showMouse(false);
}
void Screen::showMouse() {
debug(9, "showMouse()");
// if mouseDisabled
// return
- copyMouseToScreen();
+ _system->showMouse(true);
}
void Screen::setShapePages(int page1, int page2) {
@@ -1606,140 +1602,30 @@ void Screen::setShapePages(int page1, int page2) {
_shapePages[1] = _pagePtrs[page2];
}
-byte *Screen::setMouseCursor(int x, int y, byte *shape) {
+void Screen::setMouseCursor(int x, int y, byte *shape) {
debug(9, "setMouseCursor(%d, %d, 0x%X)", x, y, shape);
if (!shape)
- return _mouseShape;
+ return;
// if mouseDisabled
// return _mouseShape
-
- restoreMouseRect();
-
+
if (_vm->features() & GF_TALKIE)
shape += 2;
-
- int mouseRectSize = getRectSize((READ_LE_UINT16(shape + 3) >> 3) + 2, shape[5]);
- if (_mouseRectSize < mouseRectSize) {
- free(_mouseRect);
- _mouseRect = (uint8*)malloc(mouseRectSize << 3);
- assert(_mouseRect);
- _mouseRectSize = mouseRectSize;
- }
-
- int shapeSize = READ_LE_UINT16(shape + 8) + 10;
- if (_vm->features() & GF_TALKIE)
- shapeSize += 2;
- if (READ_LE_UINT16(shape) & 1)
- shapeSize += 16;
-
- if (_mouseShapeSize < shapeSize) {
- free(_mouseShape);
- _mouseShape = (uint8*)malloc(shapeSize);
- assert(_mouseShape);
- _mouseShapeSize = shapeSize;
- }
-
- byte *dst = _mouseShape;
- byte *src = shape;
- if (_vm->features() & GF_TALKIE)
- dst += 2;
-
- if (!(READ_LE_UINT16(shape) & 2)) {
- uint16 newFlags = 0;
- newFlags = READ_LE_UINT16(src) | 2; src += 2;
- WRITE_LE_UINT16(dst, newFlags); dst += 2;
- memcpy(dst, src, 6);
- dst += 6;
- src += 6;
- int size = READ_LE_UINT16(src); src += 2;
- WRITE_LE_UINT16(dst, size); dst += 2;
- if (newFlags & 1) {
- memcpy(dst, src, 8);
- dst += 16;
- src += 16;
- }
- decodeFrame4(src, _animBlockPtr, size);
- memcpy(dst, _animBlockPtr, size);
- } else {
- int size = READ_LE_UINT16(shape + 6);
- memcpy(dst, src, size);
- }
-
- _mouseXOffset = x; _mouseYOffset = y;
- if (_vm->features() & GF_TALKIE) {
- _mouseHeight = _mouseShape[7];
- _mouseWidth = (READ_LE_UINT16(_mouseShape + 5) >> 3) + 2;
- } else {
- _mouseHeight = _mouseShape[5];
- _mouseWidth = (READ_LE_UINT16(_mouseShape + 3) >> 3) + 2;
- }
-
- copyMouseToScreen();
-
- return _mouseShape;
-}
-void Screen::restoreMouseRect() {
- debug(9, "restoreMouseRect()");
- // if disableMouse
- // return
+ int mouseHeight = *(shape+2);
+ int mouseWidth = (READ_LE_UINT16(shape + 3)) + 2;
- if (_mouseDrawWidth && _mouseRect) {
- copyScreenFromRect(_mouseDrawX, _mouseDrawY, _mouseDrawWidth, _mouseDrawHeight, _mouseRect);
- }
- _mouseDrawWidth = 0;
-}
+ uint8 *cursor = (uint8 *)malloc(mouseHeight * mouseWidth);
+ fillRect(0, 0, mouseWidth, mouseHeight, 0, 3);
+ drawShape(3, shape, 0, 0, 0, 0);
+
+ copyRegionToBuffer(3, 0, 0, mouseWidth, mouseHeight, cursor);
+ _system->setMouseCursor(cursor, mouseWidth, mouseHeight, 0, 0, 0);
+ _system->showMouse(true);
+ free(cursor);
+
+ return;
-void Screen::copyMouseToScreen() {
- debug(9, "copyMouseToScreen()");
- // if disableMouse
- // return
-
- restoreMouseRect();
-
- int width = _mouseWidth;
- int height = _mouseHeight;
- int xpos = _vm->mouseX() - _mouseXOffset;
- int ypos = _vm->mouseY() - _mouseYOffset;
- if (xpos < -1 || ypos < -1) {
- return;
- }
-
- int xposTemp = xpos;
- int yposTemp = ypos;
-
- if (xposTemp < 0) {
- xposTemp = 0;
- }
- if (yposTemp < 0) {
- height += ypos;
- yposTemp = 0;
- }
-
- xposTemp >>= 3;
- _mouseDrawX = xposTemp;
- _mouseDrawY = yposTemp;
-
- xposTemp += width;
- xposTemp -= 40;
- if (xposTemp >= 0) {
- width -= xposTemp;
- }
-
- yposTemp += height;
- yposTemp -= 200;
- if (yposTemp >= 0) {
- height -= yposTemp;
- }
-
- _mouseDrawWidth = width;
- _mouseDrawHeight = height;
-
- if (_mouseRect) {
- copyScreenToRect(_mouseDrawX, _mouseDrawY, width, height, _mouseRect);
- }
-
- drawShape(0, _mouseShape, xpos, ypos, 0, 0, 0);
}
void Screen::copyScreenFromRect(int x, int y, int w, int h, uint8 *ptr) {
diff --git a/kyra/screen.h b/kyra/screen.h
index 67bf4f138c..1933382fa7 100644
--- a/kyra/screen.h
+++ b/kyra/screen.h
@@ -123,7 +123,7 @@ public:
void hideMouse();
void showMouse();
void setShapePages(int page1, int page2);
- byte *setMouseCursor(int x, int y, byte *shape);
+ void setMouseCursor(int x, int y, byte *shape);
uint8 *getPalette(int num);
byte getShapeFlag1(int x, int y);
@@ -152,15 +152,6 @@ private:
int _decodeShapeBufferSize;
uint8 *_animBlockPtr;
int _animBlockSize;
-
- uint8 *_mouseShape;
- uint8 *_mouseRect;
- int _mouseShapeSize;
- int _mouseRectSize;
- int _mouseDrawX, _mouseDrawY;
- int _mouseDrawWidth, _mouseDrawHeight;
- int _mouseWidth, _mouseHeight;
- int _mouseXOffset, _mouseYOffset;
OSystem *_system;
KyraEngine *_vm;
diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp
index caaecfaf51..ce5dcd28c4 100644
--- a/kyra/script_v1.cpp
+++ b/kyra/script_v1.cpp
@@ -122,7 +122,7 @@ void ScriptHelper::c1_execOpcode() {
}
void ScriptHelper::c1_ifNotJmp() {
- if (_curScript->stack[++_curScript->sp-1] != 0) {
+ if (!_curScript->stack[_curScript->sp++]) {
_parameter &= 0x7FFF;
_curScript->ip = _curScript->dataPtr->data + (_parameter << 1);
}
@@ -296,6 +296,7 @@ void ScriptHelper::c1_setRetAndJmp() {
#pragma mark -
#define stackPos(x) script->stack[script->sp+x]
+#define stackPosString(x) (char *)&script->dataPtr->text[READ_BE_UINT16( &((uint16 *)script->dataPtr->text)[stackPos(x)])]
int KyraEngine::cmd_magicInMouseItem(ScriptState *script) {
warning("STUB: cmd_magicInMouseItem");
@@ -303,7 +304,16 @@ int KyraEngine::cmd_magicInMouseItem(ScriptState *script) {
}
int KyraEngine::cmd_characterSays(ScriptState *script) {
- warning("STUB: cmd_characterSays");
+ debug(9, "cmd_characterSays(0x%X)", script);
+ // Japanese version?
+ /*const char *str1 = "âuâëâôââôüAé?é¢ùêé¢é+é®üH";
+ const char *str2 = "âuâëâôâ\\âôüAé?é¢ùêé¢é+é®üH";
+
+ if (strcmp(stackPosString(0), str1) == 0)
+ characterSays((char *)str2, stackPos(1), stackPos(2));
+ else*/
+ characterSays(stackPosString(0), stackPos(1), stackPos(2));
+
return 0;
}
@@ -314,7 +324,7 @@ int KyraEngine::cmd_pauseTicks(ScriptState *script) {
int KyraEngine::cmd_drawSceneAnimShape(ScriptState *script) {
debug(9, "cmd_drawSceneAnimShape(0x%X)", script);
- _screen->drawShape(stackPos(4), _sprites->getSceneShape(stackPos(0)), stackPos(1), stackPos(2), 0, stackPos(3));
+ _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, stackPos(3));
return 0;
}
@@ -417,13 +427,13 @@ int KyraEngine::cmd_savePageToDisk(ScriptState *script) {
int KyraEngine::cmd_sceneAnimOn(ScriptState *script) {
debug(9, "cmd_sceneAnimOn(0x%X)", script);
- _sprites->enableAnim(stackPos(0));
+ _sprites->_anims[stackPos(0)].play = true;
return 0;
}
int KyraEngine::cmd_sceneAnimOff(ScriptState *script) {
debug(9, "cmd_sceneAnimOff(0x%X)", script);
- _sprites->disableAnim(stackPos(0));
+ _sprites->_anims[stackPos(0)].play = false;
return 0;
}
@@ -530,7 +540,8 @@ int KyraEngine::cmd_magicOutMouseItem(ScriptState *script) {
}
int KyraEngine::cmd_internalAnimOn(ScriptState *script) {
- warning("STUB: cmd_internalAnimOn");
+ debug(9, "cmd_internalAnimOn(0x%X)", script);
+ _sprites->_animObjects[stackPos(0)].active = 1;
return 0;
}
@@ -552,11 +563,8 @@ int KyraEngine::cmd_setScaleMode(ScriptState *script) {
int KyraEngine::cmd_openWSAFile(ScriptState *script) {
debug(9, "cmd_openWSAFile(0x%X)", script);
- int wsaIndex = stackPos(0);
- uint16 offset = READ_BE_UINT16(&script->dataPtr->text[wsaIndex]);
- char *filename = (char*)&script->dataPtr->text[offset];
-
- wsaIndex = stackPos(1);
+ char *filename = stackPosString(0);
+ int wsaIndex = stackPos(1);
// stackPos(2) is NOT used whyever
int offscreenDecode = 0;
if (!stackPos(3)) {
@@ -646,7 +654,8 @@ int KyraEngine::cmd_popBrandonIntoScene(ScriptState *script) {
}
int KyraEngine::cmd_restoreAllObjectBackgrounds(ScriptState *script) {
- warning("STUB: cmd_restoreAllObjectBackgrounds");
+ debug(9, "cmd_restoreAllObjectBackgrounds(0x%X)", script);
+ restoreAllObjectBackgrounds();
return 0;
}
@@ -747,7 +756,8 @@ int KyraEngine::cmd_drawCharacterStanding(ScriptState *script) {
}
int KyraEngine::cmd_internalAnimOff(ScriptState *script) {
- warning("STUB: cmd_internalAnimOff");
+ debug(9, "cmd_internalAnimOff(0x%X)", script);
+ _sprites->_animObjects[stackPos(0)].active = 0;
return 0;
}
@@ -916,7 +926,7 @@ int KyraEngine::cmd_walkCharacterToPoint(ScriptState *script) {
++curPos;
// XXX
waitTicks(10);
- // XXX updateAnimFlags();
+ _sprites->updateSceneAnims();
// XXX updateMouseCursor();
// XXX updateGameTimers();
updateAllObjectShapes();
@@ -951,13 +961,17 @@ int KyraEngine::cmd_preserveAllObjectBackgrounds(ScriptState *script) {
}
int KyraEngine::cmd_updateSceneAnimations(ScriptState *script) {
- warning("STUB: cmd_updateSceneAnimations");
+ debug(9, "cmd_updateSceneAnimations(0x%X)", script);
+ if (stackPos(0)) {
+ _sprites->updateSceneAnims();
+ updateAllObjectShapes();
+ }
return 0;
}
int KyraEngine::cmd_sceneAnimationActive(ScriptState *script) {
- warning("STUB: cmd_sceneAnimationActive");
- return 0;
+ debug(9, "cmd_sceneAnimationActive(0x%X)", script);
+ return _sprites->_anims[stackPos(0)].play;
}
int KyraEngine::cmd_setCharactersMovementDelay(ScriptState *script) {
@@ -1062,7 +1076,9 @@ int KyraEngine::cmd_createAmuletJewel(ScriptState *script) {
}
int KyraEngine::cmd_setSceneAnimCurrXY(ScriptState *script) {
- warning("STUB: cmd_setSceneAnimCurrXY");
+ debug(9, "cmd_setSceneAnimCurrXY(0x%X)", script);
+ _sprites->_anims[stackPos(0)].x = stackPos(1);
+ _sprites->_anims[stackPos(0)].y = stackPos(2);
return 0;
}
@@ -1218,7 +1234,8 @@ int KyraEngine::cmd_setScaleDepthTableValue(ScriptState *script) {
}
int KyraEngine::cmd_message(ScriptState *script) {
- warning("STUB: cmd_message");
+ debug(9, "cmd_message(0x%X)", script);
+ drawSentenceCommand(stackPosString(0), stackPos(1));
return 0;
}
diff --git a/kyra/sprites.cpp b/kyra/sprites.cpp
index 8f95789459..bea98591b9 100644
--- a/kyra/sprites.cpp
+++ b/kyra/sprites.cpp
@@ -46,82 +46,99 @@ Sprites::Sprites(KyraEngine *engine, OSystem *system) {
Sprites::~Sprites() {
delete[] _dat;
freeSceneShapes();
-}
-
-uint8 *Sprites::getSceneShape(uint8 sceneShapeID) {
- assert( sceneShapeID < ARRAYSIZE(_sceneShapes));
- return _sceneShapes[sceneShapeID];
-}
-
-void Sprites::drawSprites(uint8 srcPage, uint8 dstPage) {
- int flags;
-
for (int i = 0; i < MAX_NUM_ANIMS; i++) {
- if (_anims[i].script == 0 || !_anims[i].play)
- break;
- if (_anims[i].sprite >= 0) {
- assert( _anims[i].sprite < ARRAYSIZE(_sceneShapes));
- uint8 *sprite = _sceneShapes[_anims[i].sprite];
-
- //debug(1, "Drawing from X %i, Y %i, to X %i, Y %i, width %i, height %i, srcPage %i, dstPage %i",
- // sprite.x, sprite.y, _anims[i].x, _anims[i].y, sprite.width, sprite.height, srcPage, dstPage);
- flags = Screen::CR_CLIPPED;
- if (_anims[i].flipX)
- flags |= Screen::CR_X_FLIPPED;
-
- //_screen->copyRegion(sprite.x, sprite.y, _anims[i].x, _anims[i].y, sprite.width, sprite.height, srcPage, dstPage, flags);
- _screen->drawShape(0, sprite, _anims[i].x, _anims[i].y, 0, 0, 0);
- }
+ if (_anims[i].background)
+ free(_anims[i].background);
}
}
-void Sprites::doAnims() {
- debug(9, "Sprites::doAnims()");
- uint32 currTime = _system->getMillis();
- for (int i = 0; i < MAX_NUM_ANIMS; i++) {
- if (_anims[i].script == 0 || !_anims[i].play || _anims[i].nextRun != 0 && _anims[i].nextRun > currTime)
- continue;
+void Sprites::setupSceneAnims() {
+ debug(9, "Sprites::setupSceneAnims()");
+ uint8 *data;
- uint8 *data;
+ for (int i = 0; i < MAX_NUM_ANIMS; i++) {
+ if (_anims[i].background) {
+ free(_anims[i].background);
+ _anims[i].background = 0;
+ }
- if (_anims[i].reentry == 0) {
+ if (_anims[i].script != 0) {
data = _anims[i].script;
- //debug(1, "---Start of anim script---");
assert( READ_LE_UINT16(data) == 0xFF86 );
+ data += 4;
+
+ //sceneUnk16[i] = READ_LE_UINT16(data);
+ data += 4;
+ _anims[i].unk2 = READ_LE_UINT16(data);
+ data += 4;
+
+ if (_engine->_northExitHeight > READ_LE_UINT16(data))
+ _anims[i].drawY = _engine->_northExitHeight;
+ else
+ _anims[i].drawY = READ_LE_UINT16(data);
+ data += 4;
+
+ //sceneUnk2[i] = READ_LE_UINT16(data);
+ data += 4;
+
+ _anims[i].x = READ_LE_UINT16(data);
+ data += 4;
+ _anims[i].y = READ_LE_UINT16(data);
+ data += 4;
+ _anims[i].width = *(data);
+ data += 4;
+ _anims[i].height = *(data);
+ data += 4;
+ _anims[i].sprite = READ_LE_UINT16(data);
+ data += 4;
+ _anims[i].flipX = READ_LE_UINT16(data);
+ data += 4;
+ _anims[i].width2 = *(data);
+ data += 4;
+ _anims[i].height2 = *(data);
+ data += 4;
+ _anims[i].unk1 = READ_LE_UINT16(data);
+ data += 4;
+ _anims[i].play = READ_LE_UINT16(data);
data += 2;
- //debug(1, "Default X of sprite: %i", READ_LE_UINT16(data + 0x12) );
- _anims[i].x = READ_LE_UINT16(data + 0x12);
- //debug(1, "Default Y of sprite: %i", READ_LE_UINT16(data + 0x16) );
- _anims[i].y = READ_LE_UINT16(data + 0x16);
+ _anims[i].script = data;
- //debug(1, "Anim %i flags: 22h: %i, 1ah: %i", i, READ_LE_UINT16(data + 0x22), READ_LE_UINT16(data + 0x1a));
+ int bkgdWidth = _anims[i].width;
+ int bkgdHeight = _anims[i].height;
- /*
- debug(1, "Anim %i data: 0h: %i, 2h: %i,4h: %i,6h: %i,8h: %i,ah: %i,ch: %i", i, READ_LE_UINT16(data + 0x0),
- READ_LE_UINT16(data + 0x2), READ_LE_UINT16(data + 0x4),READ_LE_UINT16(data + 0x6),READ_LE_UINT16(data + 0x8),
- READ_LE_UINT16(data + 0xa),READ_LE_UINT16(data + 0xc));
+ if (_anims[i].width2)
+ bkgdWidth += (_anims[i].width2 >> 3) + 1;
- debug(1, "Anim %i data: eh: %i, 10h: %i,12h: %i,14h: %i,16h: %i,18h: %i,1ah: %i", i, READ_LE_UINT16(data + 0xe),
- READ_LE_UINT16(data + 0x10), READ_LE_UINT16(data + 0x12),READ_LE_UINT16(data + 0x14),READ_LE_UINT16(data + 0x16),
- READ_LE_UINT16(data + 0x18),READ_LE_UINT16(data + 0x1a));
+ if (_anims[i].height2)
+ bkgdHeight += _anims[i].height2;
- debug(1, "Anim %i data: 1ch: %i, 1fh: %i,22h: %i,24h: %i,26h: %i,28h: %i,2ah: %i", i, READ_LE_UINT16(data + 0x1c),
- READ_LE_UINT16(data + 0x1f), READ_LE_UINT16(data + 0x22),READ_LE_UINT16(data + 0x24),READ_LE_UINT16(data + 0x26),
- READ_LE_UINT16(data + 0x28),READ_LE_UINT16(data + 0x2a));
- */
+ _anims[i].background = (uint8 *)malloc(_screen->getRectSize(bkgdWidth + 1, bkgdHeight));
+ //_anims[i].background = (uint8 *)malloc(100*100);
+ assert(_anims[i].background);
+ }
+ }
+}
+
+void Sprites::updateSceneAnims() {
+ debug(9, "Sprites::updateSceneAnims()");
+ uint32 currTime = _system->getMillis();
+ uint8 *data;
+ bool endLoop;
+ for (int i = 0; i < MAX_NUM_ANIMS; i++) {
+ if (_anims[i].script == 0 || !_anims[i].play || _anims[i].nextRun != 0 && _anims[i].nextRun > currTime)
+ continue;
- // TODO: Find out what the rest of this data (next 38h bytes) does.
- data += 0x38;
+ if (_anims[i].reentry == 0) {
+ data = _anims[i].script;
} else {
data = _anims[i].reentry;
_anims[i].reentry = 0;
}
- bool endLoop = false;
-
+ endLoop = false;
while (READ_LE_UINT16(data) != 0xFF87 && !endLoop) {
uint16 rndNr;
uint16 anim;
@@ -142,6 +159,7 @@ void Sprites::doAnims() {
_anims[i].y = READ_LE_UINT16(data);
data += 2;
_anims[i].flipX = false;
+ refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
break;
case 0xFF8D:
data += 2;
@@ -158,6 +176,7 @@ void Sprites::doAnims() {
_anims[i].y = READ_LE_UINT16(data);
data += 2;
_anims[i].flipX = true;
+ refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
break;
case 0xFF8A:
data += 2;
@@ -174,7 +193,7 @@ void Sprites::doAnims() {
data += 2;
debug(5, "Maximum time %i", READ_LE_UINT16(data));
data += 2;
- _anims[i].nextRun = _system->getMillis() + rndNr * _animDelay;
+ _anims[i].nextRun = _system->getMillis() + rndNr * _animDelay;
break;
case 0xFF8C:
data += 2;
@@ -185,11 +204,13 @@ void Sprites::doAnims() {
break;
case 0xFF99:
data += 2;
- debug(1, "TODO func: Set value of animation property 32h to 1");
+ debug(1, "func: Set value of unknown animation property to 1");
+ _anims[i].unk1 = 1;
break;
case 0xFF9A:
data += 2;
- debug(1, "TODO func: Set value of animation property 32h to 0");
+ debug(1, "func: Set value of unknown animation property to 0");
+ _anims[i].unk1 = 0;
break;
case 0xFF97:
data += 2;
@@ -234,6 +255,7 @@ void Sprites::doAnims() {
_anims[i].sprite = READ_LE_UINT16(data);
_anims[i].flipX = false;
data += 2;
+ refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
break;
case 0xFF91:
data += 2;
@@ -242,6 +264,7 @@ void Sprites::doAnims() {
_anims[i].sprite = READ_LE_UINT16(data);
_anims[i].flipX = true;
data += 2;
+ refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
break;
case 0xFF92:
data += 2;
@@ -279,8 +302,6 @@ void Sprites::doAnims() {
data += 2;
_anims[anim].play = false;
_anims[anim].sprite = -1;
- //debug(1, "Arg2 %i", READ_LE_UINT16(data));
- //data += 2;
break;
/* case 0xFF97:
data += 2;
@@ -288,20 +309,23 @@ void Sprites::doAnims() {
break;*/
case 0xFFAD:
data += 2;
- debug(1, "TODO func: Set Brandon's X coordinate");
- debug(1, "X %i", READ_LE_UINT16(data));
+ debug(5, "func: Set Brandon's X coordinate");
+ debug(5, "X %i", READ_LE_UINT16(data));
+ _engine->_currentCharacter->x1 = READ_LE_UINT16(data);
data += 2;
break;
case 0xFFAE:
data += 2;
- debug(1, "TODO func: Set Brandon's Y coordinate");
- debug(1, "Y %i", READ_LE_UINT16(data));
+ debug(5, "func: Set Brandon's Y coordinate");
+ debug(5, "Y %i", READ_LE_UINT16(data));
+ _engine->_currentCharacter->y1 = READ_LE_UINT16(data);
data += 2;
break;
case 0xFFAF:
data += 2;
- debug(1, "TODO func: Set Brandon's X sprite");
- debug(1, "Sprite %i", READ_LE_UINT16(data));
+ debug(5, "func: Set Brandon's sprite");
+ debug(5, "Sprite %i", READ_LE_UINT16(data));
+ _engine->_currentCharacter->currentAnimFrame = READ_LE_UINT16(data);
data += 2;
break;
case 0xFFAA:
@@ -310,28 +334,36 @@ void Sprites::doAnims() {
break;
case 0xFFAB:
data += 2;
- debug(1, "TODO func: Update Brandon's sprite");
+ debug(5, "func: Update Brandon's sprite");
+ _engine->animRefreshNPC(0);
+ _engine->flagAllObjectsForRefresh();
+ _engine->updateAllObjectShapes();
break;
case 0xFFB0:
data += 2;
- debug(1, "TODO func: Play sound");
- debug(1, "Sound index %i", READ_LE_UINT16(data));
+ debug(5, "func: Play sound");
+ debug(5, "Sound index %i", READ_LE_UINT16(data));
+ _engine->snd_playSoundEffect(READ_LE_UINT16(data));
data += 2;
break;
case 0xFFB1:
data += 2;
- debug(1, "TODO func: Set unknown global bit");
+ debug(1, "TODO func: Set animator beacon flag");
break;
case 0xFFB2:
data += 2;
- debug(1, "TODO func: Reset unknown global bit");
+ debug(1, "TODO func: Reset animator beacon flag");
break;
case 0xFFB4:
data += 2;
- debug(1, "TODO func: Play (at random) a certain sound at a certain percentage of time");
- debug(1, "Sound index %i", READ_LE_UINT16(data));
+ debug(5, "func: Play (at random) a certain sound at a certain percentage of time");
+ debug(5, "Sound index %i", READ_LE_UINT16(data));
+ int sound = READ_LE_UINT16(data);
data += 2;
- debug(1, "Percentage %i", READ_LE_UINT16(data));
+ debug(5, "Percentage %i", READ_LE_UINT16(data));
+ rndNr = _rnd.getRandomNumber(100);
+ if (rndNr <= READ_LE_UINT16(data))
+ _engine->snd_playSoundEffect(sound);
data += 2;
break;
case 0xFFA7:
@@ -341,7 +373,7 @@ void Sprites::doAnims() {
data += 2;
break;
default:
- debug(1, "Unsupported anim command %X", READ_LE_UINT16(data));
+ debug(1, "Unsupported anim command %X in script %i", READ_LE_UINT16(data), i);
//endLoop = true;
data += 1;
break;
@@ -350,21 +382,19 @@ void Sprites::doAnims() {
if (READ_LE_UINT16(data) == 0xFF87)
_anims[i].play = false;
-
- //debug(1, "---End of anim script---");
}
}
-void Sprites::loadDAT(const char *filename) {
+void Sprites::loadDAT(const char *filename, SceneExits &exits) {
debug(9, "Sprites::loadDat('%s')", filename);
uint32 fileSize;
- uint8 spritesLoaded = 0;
delete[] _dat;
+ _spriteDefStart = 0;
_dat = _res->fileData(filename, &fileSize);
- memset(_anims, 0, sizeof(Anim) * MAX_NUM_ANIMS);
+ memset(_anims, 0, sizeof(_anims));
uint8 nextAnim = 0;
assert(fileSize > 0x6D);
@@ -380,8 +410,6 @@ void Sprites::loadDAT(const char *filename) {
uint16 length = READ_LE_UINT16(data);
data += 2;
- //debug(1, "DAT body length: %i, filesize %i, current spot %i", length, fileSize, data - _dat);
-
if (length > 2) {
assert( length < fileSize);
uint8 *animstart;
@@ -440,14 +468,8 @@ void Sprites::loadDAT(const char *filename) {
data += 2;
}
- debug(1, "Room DAT file loaded. Found %i sprite and %i animation scripts.", spritesLoaded, nextAnim);
-
- //debug(1, "Remainder after script: %i", fileSize - (data - _dat));
assert(fileSize - (data - _dat) == 0xC);
- //TODO: Read in character entry coords here
- SceneExits &exits = _engine->sceneExits();
-
exits.northXPos = READ_LE_UINT16(data) & 0xFFFC; data += 2;
exits.northYPos = *data++ & 0xFFFE;
exits.eastXPos = READ_LE_UINT16(data) & 0xFFFC; data += 2;
@@ -459,9 +481,11 @@ void Sprites::loadDAT(const char *filename) {
}
void Sprites::freeSceneShapes() {
- for (int i = 0; i < ARRAYSIZE(_sceneShapes); i++ )
+ debug(9, "Sprites::freeSceneShapes()");
+ for (int i = 0; i < ARRAYSIZE(_sceneShapes); i++ ) {
free(_sceneShapes[i]);
-
+ _sceneShapes[i] = 0;
+ }
}
void Sprites::loadSceneShapes() {
@@ -469,11 +493,15 @@ void Sprites::loadSceneShapes() {
uint8 *data = _spriteDefStart;
int spriteNum, x, y, width, height;
- assert(_spriteDefStart);
-
freeSceneShapes();
memset( _sceneShapes, 0, sizeof(_sceneShapes));
+ if (_spriteDefStart == 0)
+ return;
+
+ int bakPage = _screen->_curPage;
+ _screen->_curPage = 3;
+
while (READ_LE_UINT16(data) != 0xFF85) {
spriteNum = READ_LE_UINT16(data);
assert(spriteNum < ARRAYSIZE(_sceneShapes));
@@ -486,8 +514,31 @@ void Sprites::loadSceneShapes() {
data += 2;
height = READ_LE_UINT16(data);
data += 2;
- _sceneShapes[spriteNum] = _screen->encodeShape(x, y, width, height, 0);
+ _sceneShapes[spriteNum] = _screen->encodeShape(x, y, width, height, 2);
+ debug(9, "Sprite %i is at (%i, %i), width %i, height %i", spriteNum, x, y, width, height);
}
+ _screen->_curPage = bakPage;
+}
+
+void Sprites::refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag) {
+ debug(9, "Sprites::refreshSceneAnimObject(%i, %i, %i, %i, %i, %i", animNum, shapeNum, x, y, flipX, unkFlag);
+ _animObjects[animNum].refreshFlag = 1;
+ _animObjects[animNum].bkgdChangeFlag = 1;
+
+ if (unkFlag)
+ _animObjects[animNum].flags |= 0x0200;
+ else
+ _animObjects[animNum].flags &= 0xFD00;
+
+ if (flipX)
+ _animObjects[animNum].flags |= 1;
+ else
+ _animObjects[animNum].flags &= 0xFE;
+
+ _animObjects[animNum].sceneAnimPtr = _sceneShapes[shapeNum];
+ _animObjects[animNum].animFrameNumber = -1;
+ _animObjects[animNum].x1 = x;
+ _animObjects[animNum].y1 = y;
}
} // end of namespace Kyra
diff --git a/kyra/sprites.h b/kyra/sprites.h
index c64bf045cc..8f4102e7eb 100644
--- a/kyra/sprites.h
+++ b/kyra/sprites.h
@@ -45,6 +45,14 @@ struct Anim {
uint8 *reentry;
uint32 nextRun;
bool play;
+ uint16 width;
+ uint16 height;
+ uint16 width2;
+ uint16 height2;
+ uint16 unk1;
+ uint16 drawY;
+ uint16 unk2;
+ uint8 *background;
};
class Sprites {
@@ -53,14 +61,16 @@ public:
Sprites(KyraEngine *engine, OSystem *system);
~Sprites();
- void doAnims();
- void loadDAT(const char *filename);
- uint8 *getSceneShape(uint8 sceneShapeID);
- void drawSprites(uint8 srcPage, uint8 dstPage);
+ void updateSceneAnims();
+ void setupSceneAnims();
+ void loadDAT(const char *filename, SceneExits &exits);
void loadSceneShapes();
- void enableAnim(uint8 anim) { _anims[anim].play = true; }
- void disableAnim(uint8 anim) { _anims[anim].play = false; }
+ Anim _anims[MAX_NUM_ANIMS];
+ AnimObject *_animObjects;
+ uint8 *_sceneShapes[50];
+
+ void refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag);
protected:
void freeSceneShapes();
@@ -69,9 +79,7 @@ protected:
Resource *_res;
OSystem *_system;
Screen *_screen;
- uint8 *_sceneShapes[50];
uint8 *_dat;
- Anim _anims[MAX_NUM_ANIMS];
Common::RandomSource _rnd;
uint8 _animDelay;
uint8 *_spriteDefStart;