Ticket #8484: kyra_chat_plus_plus_v3.patch

File kyra_chat_plus_plus_v3.patch, 58.8 KB (added by vinterstum, 18 years ago)

KYRA: chat++

  • kyra/kyra.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/kyra.cpp scummvm/kyra/kyra.cpp
    old new  
    285285        _animStates = new AnimObject[31];
    286286        assert(_animStates);
    287287        _charactersAnimState = &_animStates[0];
    288         _animObjects =  &_animStates[5];
     288        _sprites->_animObjects =  &_animStates[5];
    289289        _animItems = &_animStates[16];
    290290       
    291291        _scriptInterpreter = new ScriptHelper(this);
     
    308308        memset(_shapes, 0, sizeof(_shapes));
    309309        memset(_wsaObjects, 0, sizeof(_wsaObjects));
    310310
     311        memset(_flagsTable, 0, sizeof(_flagsTable));
     312
    311313        _fastMode = false;
    312314        _talkCoords.y = 0x88;
    313315        _talkCoords.x = 0;
     
    315317        _talkMessageY = 0xC;
    316318        _talkMessageH = 0;
    317319        _talkMessagePrinted = false;
    318        
     320        _charSayUnk1 = -1;
     321        _charSayUnk3 = -1;
    319322        _mouseX = _mouseY = -1;
    320         _needMouseUpdate = true;
    321323       
    322324        _brandonPosX = _brandonPosY = -1;
    323325        _brandonDrawFrame = 113;
     
    326328        memset(_exitList, 0xFFFF, sizeof(_exitList));
    327329        _exitListPtr = 0;
    328330        _pathfinderFlag = 0;
    329        
     331        _lastFindWayRet = 0;
    330332        _sceneChangeState = _loopFlag2 = 0;
    331333       
    332334        _movFacingTable = new int[150];
    333335        assert(_movFacingTable);
    334336        _movFacingTable[0] = 8;
    335337
     338        _configTalkspeed = 1;
     339
    336340        return 0;
    337341}
    338342
     
    368372        for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) {
    369373                free(_sceneAnimTable[i]);
    370374        }
     375
    371376}
    372377
    373378void KyraEngine::errorString(const char *buf1, char *buf2) {
     
    390395        if (_features & GF_DEMO) {
    391396                seq_demo();
    392397        } else {
    393                 seq_intro();
     398                setGameFlag(0xF3);
     399                setGameFlag(0xFD);
     400                setGameFlag(0xEF);
     401                //seq_intro();
    394402                startup();
     403                resetGameFlag(0xEF);
    395404                mainLoop();
    396405        }
    397         res_unloadResources();
     406        quitGame();
    398407        return 0;
    399408}
    400409
     
    445454        // XXX
    446455        initAnimStateList();
    447456        setCharactersInDefaultScene();
    448        
     457
    449458        _gameSpeed = 50;
    450         memset(_flagsTable, 0, sizeof(_flagsTable));
    451459       
    452460        if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, _opcodeTable, _opcodeTableSize, 0)) {
    453461                error("Could not load \"_STARTUP.EMC\" script");
     
    488496                        case OSystem::EVENT_MOUSEMOVE:
    489497                                _mouseX = event.mouse.x;
    490498                                _mouseY = event.mouse.y;
    491                                 _needMouseUpdate = true;
    492499                                break;
    493500                        case OSystem::EVENT_QUIT:
    494501                                _quitFlag = true;
     
    506513void KyraEngine::mainLoop() {
    507514        debug(9, "KyraEngine::mainLoop()");
    508515
     516        //enterNewScene(0x0, _currentCharacter->facing, 0, 0, 1);
     517
    509518        while (!_quitFlag) {
    510519                int32 frameTime = (int32)_system->getMillis();
    511520
    512                 if (_needMouseUpdate) {
    513                         _screen->hideMouse();
    514                         _screen->showMouse();
    515                         _needMouseUpdate = false;
    516                 }
    517                 _screen->updateScreen();
     521                _sprites->updateSceneAnims();
     522                updateAllObjectShapes();
    518523
    519524                delay((frameTime + _gameSpeed) - _system->getMillis());
    520525        }
    521526}
    522527
     528void KyraEngine::quitGame() {
     529        res_unloadResources();
     530
     531        for (int i = 0; i < 10; i++)
     532                wsa_close(_wsaObjects[i]);
     533
     534        _system->quit();
     535}
     536
    523537void KyraEngine::loadPalette(const char *filename, uint8 *palData) {
    524538        debug(9, "KyraEngine::loadPalette('%s' 0x%X)", filename, palData);
    525539        uint32 fileSize = 0;
     
    529543                debug(9, "Loading a palette of size %i from '%s'", fileSize, filename);
    530544                memcpy(palData, srcData, fileSize);             
    531545        }
     546        delete[] srcData;
    532547}
    533548
    534549void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) {
     
    561576        delete[] srcData;
    562577}
    563578
    564 void KyraEngine::setTalkCoords(uint16 y) {
    565         debug(9, "KyraEngine::setTalkCoords(%d)", y);
    566         _talkCoords.y = y;
    567 }
    568 
    569 int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
    570         debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
    571         _screen->_charWidth = -2;
    572         Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
    573         int strWidth = _screen->getTextWidth(str);
    574         _screen->setFont(curFont);
    575         _screen->_charWidth = 0;
    576         int w = x2 - x1 + 1;
    577         return x1 + (w - strWidth) / 2;
    578 }
    579 
    580 int KyraEngine::getCharLength(const char *str, int len) {
    581         debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
    582         int charsCount = 0;
    583         if (*str) {
    584                 _screen->_charWidth = -2;
    585                 Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
    586                 int i = 0;
    587                 while (i <= len && *str) {
    588                         i += _screen->getCharWidth(*str++);
    589                         ++charsCount;
    590                 }
    591                 _screen->setFont(curFont);
    592                 _screen->_charWidth = 0;
    593         }
    594         return charsCount;
    595 }
    596 
    597 int KyraEngine::dropCRIntoString(char *str, int offs) {
    598         debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
    599         int pos = 0;
    600         str += offs;
    601         while (*str) {
    602                 if (*str == ' ') {
    603                         *str = '\r';
    604                         return pos;
    605                 }
    606                 ++str;
    607                 ++pos;
    608         }
    609         return 0;
    610 }
    611 
    612 char *KyraEngine::preprocessString(const char *str) {
    613         debug(9, "KyraEngine::preprocessString('%s')", str);
    614         assert(strlen(str) < sizeof(_talkBuffer) - 1);
    615         strcpy(_talkBuffer, str);
    616         char *p = _talkBuffer;
    617         while (*p) {
    618                 if (*p == '\r') {
    619                         return _talkBuffer;
    620                 }
    621                 ++p;
    622         }
    623         p = _talkBuffer;
    624         Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
    625         _screen->_charWidth = -2;
    626         int textWidth = _screen->getTextWidth(p);
    627         _screen->_charWidth = 0;
    628         if (textWidth > 176) {
    629                 if (textWidth > 352) {
    630                         int count = getCharLength(p, textWidth / 3);
    631                         int offs = dropCRIntoString(p, count);
    632                         p += count + offs;
    633                         _screen->_charWidth = -2;
    634                         textWidth = _screen->getTextWidth(p);
    635                         _screen->_charWidth = 0;
    636                         count = getCharLength(p, textWidth / 2);
    637                         dropCRIntoString(p, count);
    638                 } else {
    639                         int count = getCharLength(p, textWidth / 2);
    640                         dropCRIntoString(p, count);
    641                 }
    642         }
    643         _screen->setFont(curFont);
    644         return _talkBuffer;
    645 }
    646 
    647 int KyraEngine::buildMessageSubstrings(const char *str) {
    648         debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
    649         int currentLine = 0;
    650         int pos = 0;
    651         while (*str) {
    652                 if (*str == '\r') {
    653                         assert(currentLine < TALK_SUBSTRING_NUM);
    654                         _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
    655                         ++currentLine;
    656                         pos = 0;
    657                 } else {
    658                         _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
    659                         ++pos;
    660                         if (pos > TALK_SUBSTRING_LEN - 2) {
    661                                 pos = TALK_SUBSTRING_LEN - 2;
    662                         }
    663                 }
    664                 ++str;
    665         }
    666         _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
    667         return currentLine + 1;
    668 }
    669 
    670 int KyraEngine::getWidestLineWidth(int linesCount) {
    671         debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
    672         int maxWidth = 0;
    673         Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
    674         _screen->_charWidth = -2;
    675         for (int l = 0; l < linesCount; ++l) {
    676                 int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
    677                 if (maxWidth < w) {
    678                         maxWidth = w;
    679                 }
    680         }
    681         _screen->setFont(curFont);
    682         _screen->_charWidth = 0;
    683         return maxWidth;
    684 }
    685 
    686 void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
    687         debug(9, "KyraEngine::calcWidestLineBounds(%d, %d)", w, cx);
    688         x1 = cx - w / 2;
    689         if (x1 + w >= Screen::SCREEN_W - 12) {
    690                 x1 = Screen::SCREEN_W - 12 - w - 1;
    691         } else if (x1 < 12) {
    692                 x1 = 12;
    693         }
    694         x2 = x1 + w + 1;
    695 }
    696 
    697 void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
    698         debug(9, "KyraEngine::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
    699         if (_talkMessagePrinted) {
    700                 _talkMessagePrinted = false;
    701                 _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
    702         }
    703 }
    704 
    705 void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
    706         debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
    707         char *str = preprocessString(text);
    708         int lineCount = buildMessageSubstrings(str);
    709         int top = y - lineCount * 10;
    710         if (top < 0) {
    711                 top = 0;
    712         }
    713         _talkMessageY = top;
    714         _talkMessageH = lineCount * 10;
    715         int w = getWidestLineWidth(lineCount);
    716         int x1, x2;
    717         calcWidestLineBounds(x1, x2, w, x);
    718         _talkCoords.x = x1;
    719         _talkCoords.w = w + 2;
    720         _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
    721         int curPage = _screen->_curPage;
    722         _screen->_curPage = srcPage;
    723         for (int i = 0; i < lineCount; ++i) {
    724                 top = i * 10 + _talkMessageY;
    725                 char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
    726                 int left = getCenterStringX(msg, x1, x2);
    727                 printText(msg, left, top, color, 0xC, 0);
    728         }
    729         _screen->_curPage = curPage;
    730         _talkMessagePrinted = true;
    731 }
    732 
    733 void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
    734         uint8 colorMap[] = { 0, 15, 12, 12 };
    735         colorMap[3] = c1;
    736         _screen->setTextColor(colorMap, 0, 3);
    737         Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
    738         _screen->_charWidth = -2;
    739         _screen->printText(str, x, y, c0, c2);
    740         _screen->_charWidth = 0;
    741         _screen->setFont(curFont);
    742 }
    743 
    744579void KyraEngine::waitTicks(int ticks) {
    745580        debug(9, "KyraEngine::waitTicks(%d)", ticks);
    746581        const uint32 end = _system->getMillis() + ticks * 1000 / 60;
     
    750585                        switch (event.type) {
    751586                        case OSystem::EVENT_QUIT:
    752587                                _quitFlag = true;
     588                                quitGame();
    753589                                break;
    754590                        case OSystem::EVENT_KEYDOWN:
    755591                                if (event.kbd.flags == OSystem::KBD_CTRL) {
     
    13311167        char datFileNameBuffer[32];
    13321168        strcpy(datFileNameBuffer, _roomFilenameTable[tableId]);
    13331169        strcat(datFileNameBuffer, ".DAT");
    1334         _sprites->loadDAT(datFileNameBuffer);
     1170        _sprites->loadDAT(datFileNameBuffer, _sceneExits);
     1171        _sprites->setupSceneAnims();
    13351172        _scriptInterpreter->unloadScript(_scriptClickData);
    13361173        loadSceneMSC();
    13371174       
     
    19401777        }
    19411778       
    19421779        for (int i = 0; i < 11; ++i) {
    1943                 curAnimState = &_animObjects[i];
    1944                 curAnimState->active = 0;
    1945                 curAnimState->refreshFlag = 0;
    1946                 curAnimState->bkgdChangeFlag = 0;
    1947                 // XXX this needs the dat loader
     1780                curAnimState = &_sprites->_animObjects[i];
     1781
     1782                if (_sprites->_anims[i].play) {
     1783                        curAnimState->active = 1;
     1784                        curAnimState->refreshFlag = 1;
     1785                        curAnimState->bkgdChangeFlag = 1;
     1786                }
     1787                else {
     1788                        curAnimState->active = 0;
     1789                        curAnimState->refreshFlag = 0;
     1790                        curAnimState->bkgdChangeFlag = 0;
     1791                }
     1792                curAnimState->height = _sprites->_anims[i].height;
     1793                curAnimState->height2 = _sprites->_anims[i].height2;
     1794                curAnimState->width = _sprites->_anims[i].width + 1;
     1795                curAnimState->width2 = _sprites->_anims[i].width2;
     1796                curAnimState->drawY = _sprites->_anims[i].drawY;
     1797                curAnimState->x1 = curAnimState->x2 = _sprites->_anims[i].x;
     1798                curAnimState->y1 = curAnimState->y2 = _sprites->_anims[i].y;
     1799                curAnimState->background = _sprites->_anims[i].background;
     1800                curAnimState->sceneAnimPtr = _sprites->_sceneShapes[_sprites->_anims[i].sprite];
     1801               
     1802                if(_sprites->_anims[i].unk2)
     1803                        curAnimState->flags = 0x800;
     1804                else
     1805                        curAnimState->flags = 0;
     1806
     1807                if (_sprites->_anims[i].flipX)
     1808                        curAnimState->flags |= 0x1;
     1809               
     1810                _objectQueue = objectQueue(_objectQueue, curAnimState);
     1811
    19481812        }
    19491813       
    19501814        for (int i = 0; i < 12; ++i) {
     
    19911855        preserveAnyChangedBackgrounds();
    19921856        prepDrawAllObjects();
    19931857        _screen->hideMouse();
    1994         // XXX game_unkScreen
     1858        initSceneScreen(brandonAlive);
    19951859        _screen->showMouse();
    19961860        copyChangedObjectsForward(0);
    19971861}
    19981862
     1863void KyraEngine::initSceneScreen(int brandonAlive) {
     1864        // XXX (Pointless?) Palette stuff
     1865        //_screen->shuffleScreen(8, 8, 0x130, 0x80, 2, 0, byte_2EE1C);
     1866        _screen->copyRegion(1, 8, 1, 8, 304, 0x80, 2, 0);
     1867        // XXX More (pointless?) palette stuff
     1868
     1869        if (!_scriptInterpreter->startScript(_scriptClick, 2))
     1870                error("Could not start script function 2 of scene script");
     1871
     1872        _scriptClick->variables[7] = brandonAlive;
     1873
     1874        while (_scriptInterpreter->validScript(_scriptClick))
     1875                _scriptInterpreter->runScript(_scriptClick);
     1876
     1877        if (_currentCharacter->sceneId == 0xD2) {
     1878                // XXX
     1879        }
     1880}
     1881
    19991882#pragma mark -
    20001883#pragma mark - Item handling
    20011884#pragma mark -
    20021885
    2003 void KyraEngine::addToNoDropRects(int x, int y, int w, int h) {
    2004         debug(9, "addToNoDropRects(%d, %d, %d, %d)", x, y, w, h);
    2005         for (int rect = 0; rect < 11; ++rect) {
    2006                 if (_noDropRects[rect].x == -1) {
    2007                         _noDropRects[rect].x = x;
    2008                         _noDropRects[rect].y = y;
    2009                         _noDropRects[rect].x2 = x + w - 1;
    2010                         _noDropRects[rect].y2 = y + h - 1;
    2011                         break;
    2012                 }
    2013         }
     1886void KyraEngine::setTalkCoords(uint16 y) {
     1887        debug(9, "KyraEngine::setTalkCoords(%d)", y);
     1888        _talkCoords.y = y;
    20141889}
    20151890
    2016 void KyraEngine::clearNoDropRects() {
    2017         debug(9, "clearNoDropRects()");
    2018         memset(_noDropRects, -1, sizeof(_noDropRects));
     1891int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
     1892        debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
     1893        _screen->_charWidth = -2;
     1894        Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
     1895        int strWidth = _screen->getTextWidth(str);
     1896        _screen->setFont(curFont);
     1897        _screen->_charWidth = 0;
     1898        int w = x2 - x1 + 1;
     1899        return x1 + (w - strWidth) / 2;
    20191900}
    20201901
    2021 byte KyraEngine::findFreeItemInScene(int scene) {
    2022         debug(9, "findFreeItemInScene(%d)", scene);
    2023         assert(scene < _roomTableSize);
    2024         Room *room = &_roomTable[scene];
     1902int KyraEngine::getCharLength(const char *str, int len) {
     1903        debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
     1904        int charsCount = 0;
     1905        if (*str) {
     1906                _screen->_charWidth = -2;
     1907                Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
     1908                int i = 0;
     1909                while (i <= len && *str) {
     1910                        i += _screen->getCharWidth(*str++);
     1911                        ++charsCount;
     1912                }
     1913                _screen->setFont(curFont);
     1914                _screen->_charWidth = 0;
     1915        }
     1916        return charsCount;
     1917}
     1918
     1919int KyraEngine::dropCRIntoString(char *str, int offs) {
     1920        debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
     1921        int pos = 0;
     1922        str += offs;
     1923        while (*str) {
     1924                if (*str == ' ') {
     1925                        *str = '\r';
     1926                        return pos;
     1927                }
     1928                ++str;
     1929                ++pos;
     1930        }
     1931        return 0;
     1932}
     1933
     1934char *KyraEngine::preprocessString(const char *str) {
     1935        debug(9, "KyraEngine::preprocessString('%s')", str);
     1936        assert(strlen(str) < sizeof(_talkBuffer) - 1);
     1937        strcpy(_talkBuffer, str);
     1938        char *p = _talkBuffer;
     1939        while (*p) {
     1940                if (*p == '\r') {
     1941                        return _talkBuffer;
     1942                }
     1943                ++p;
     1944        }
     1945        p = _talkBuffer;
     1946        Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
     1947        _screen->_charWidth = -2;
     1948        int textWidth = _screen->getTextWidth(p);
     1949        _screen->_charWidth = 0;
     1950        if (textWidth > 176) {
     1951                if (textWidth > 352) {
     1952                        int count = getCharLength(p, textWidth / 3);
     1953                        int offs = dropCRIntoString(p, count);
     1954                        p += count + offs;
     1955                        _screen->_charWidth = -2;
     1956                        textWidth = _screen->getTextWidth(p);
     1957                        _screen->_charWidth = 0;
     1958                        count = getCharLength(p, textWidth / 2);
     1959                        dropCRIntoString(p, count);
     1960                } else {
     1961                        int count = getCharLength(p, textWidth / 2);
     1962                        dropCRIntoString(p, count);
     1963                }
     1964        }
     1965        _screen->setFont(curFont);
     1966        return _talkBuffer;
     1967}
     1968
     1969int KyraEngine::buildMessageSubstrings(const char *str) {
     1970        debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
     1971        int currentLine = 0;
     1972        int pos = 0;
     1973        while (*str) {
     1974                if (*str == '\r') {
     1975                        assert(currentLine < TALK_SUBSTRING_NUM);
     1976                        _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
     1977                        ++currentLine;
     1978                        pos = 0;
     1979                } else {
     1980                        _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
     1981                        ++pos;
     1982                        if (pos > TALK_SUBSTRING_LEN - 2) {
     1983                                pos = TALK_SUBSTRING_LEN - 2;
     1984                        }
     1985                }
     1986                ++str;
     1987        }
     1988        _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
     1989        return currentLine + 1;
     1990}
     1991
     1992int KyraEngine::getWidestLineWidth(int linesCount) {
     1993        debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
     1994        int maxWidth = 0;
     1995        Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
     1996        _screen->_charWidth = -2;
     1997        for (int l = 0; l < linesCount; ++l) {
     1998                int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
     1999                if (maxWidth < w) {
     2000                        maxWidth = w;
     2001                }
     2002        }
     2003        _screen->setFont(curFont);
     2004        _screen->_charWidth = 0;
     2005        return maxWidth;
     2006}
     2007
     2008void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
     2009        debug(9, "KyraEngine::calcWidestLineBounds(%d, %d)", w, cx);
     2010        x1 = cx - w / 2;
     2011        if (x1 + w >= Screen::SCREEN_W - 12) {
     2012                x1 = Screen::SCREEN_W - 12 - w - 1;
     2013        } else if (x1 < 12) {
     2014                x1 = 12;
     2015        }
     2016        x2 = x1 + w + 1;
     2017}
     2018
     2019void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
     2020        debug(9, "KyraEngine::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
     2021        if (_talkMessagePrinted) {
     2022                _talkMessagePrinted = false;
     2023                _screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
     2024        }
     2025}
     2026
     2027void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
     2028        debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
     2029        char *str = preprocessString(text);
     2030        int lineCount = buildMessageSubstrings(str);
     2031        int top = y - lineCount * 10;
     2032        if (top < 0) {
     2033                top = 0;
     2034        }
     2035        _talkMessageY = top;
     2036        _talkMessageH = lineCount * 10;
     2037        int w = getWidestLineWidth(lineCount);
     2038        int x1, x2;
     2039        calcWidestLineBounds(x1, x2, w, x);
     2040        _talkCoords.x = x1;
     2041        _talkCoords.w = w + 2;
     2042        _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
     2043        int curPage = _screen->_curPage;
     2044        _screen->_curPage = srcPage;
     2045        for (int i = 0; i < lineCount; ++i) {
     2046                top = i * 10 + _talkMessageY;
     2047                char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
     2048                int left = getCenterStringX(msg, x1, x2);
     2049                printText(msg, left, top, color, 0xC, 0);
     2050        }
     2051        _screen->_curPage = curPage;
     2052        _talkMessagePrinted = true;
     2053}
     2054
     2055void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
     2056        uint8 colorMap[] = { 0, 15, 12, 12 };
     2057        colorMap[3] = c1;
     2058        _screen->setTextColor(colorMap, 0, 3);
     2059        Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
     2060        _screen->_charWidth = -2;
     2061        _screen->printText(str, x, y, c0, c2);
     2062        _screen->_charWidth = 0;
     2063        _screen->setFont(curFont);
     2064}
     2065
     2066void KyraEngine::waitForChatToFinish(int16 chatDuration, char *chatStr, uint8 charNum) {
     2067        debug(9, "KyraEngine::waitForChatToFinish(%i, %s, %i)", chatDuration, chatStr, charNum);
     2068        bool hasUpdatedNPCs = false;
     2069        bool runLoop = true;
     2070        uint8 currPage;
     2071        OSystem::Event event;
     2072        uint8 tickLength = (uint8)(1000.0 / _gameSpeed);
     2073
     2074        //while( towns_isEscKeyPressed() )
     2075                //towns_getKey();
     2076
     2077        uint32 timeToEnd = strlen(chatStr) * 8 * tickLength + _system->getMillis();
     2078
     2079        if (chatDuration != -1 ) {
     2080                switch ( _configTalkspeed) {
     2081                        case 0: chatDuration *= 2;
     2082                                        break;
     2083                        case 2: chatDuration /= 4;
     2084                                        break;
     2085                        case 3: chatDuration = -1;
     2086                }
     2087        }
     2088
     2089        if (chatDuration != -1)
     2090                chatDuration *= tickLength;
     2091
     2092        //disableTimer(0x13);
     2093        //disableTimer(0x0E);
     2094        //disableTimer(0x12);
     2095        //towns_flushKeyb();
     2096
     2097        uint32 timeAtStart = _system->getMillis();
     2098        uint32 loopStart;
     2099        while (runLoop) {
     2100                loopStart = _system->getMillis();
     2101                /*
     2102                if (_currentCharacter.sceneId == 0xD2)
     2103                        if (seq_playEnd())
     2104                                break;
     2105                */
     2106
     2107                if( _system->getMillis() < timeToEnd && !hasUpdatedNPCs) {
     2108                        hasUpdatedNPCs = true;
     2109                        //disableTimer(0x0F);
     2110                        _charSayUnk4 = 4;
     2111                        animRefreshNPC(0);
     2112                        animRefreshNPC(_charSayUnk1);
     2113
     2114                        if (_charSayUnk2 != -1) {
     2115                                _sprites->_animObjects[_charSayUnk2].active = 0;
     2116                                _sprites->_anims[_charSayUnk2].play = false;
     2117                                _charSayUnk2 = -1;
     2118                        }
     2119                }
     2120
     2121                //updateGameTimers();
     2122                _sprites->updateSceneAnims();
     2123                restoreAllObjectBackgrounds();
     2124                preserveAnyChangedBackgrounds();
     2125                prepDrawAllObjects();
     2126
     2127                currPage = _screen->_curPage;
     2128                _screen->_curPage = 2;
     2129                printCharacterText(chatStr, charNum);
     2130                _screen->_curPage = currPage;
     2131
     2132                copyChangedObjectsForward(0);
     2133                //processPalette();
     2134
     2135                if ((chatDuration < (int16)(_system->getMillis() - timeAtStart)) && chatDuration != -1)
     2136                        break;
     2137
     2138                while (_system->pollEvent(event)) {
     2139                        switch (event.type) {
     2140                        case OSystem::EVENT_KEYDOWN:
     2141                                if (event.kbd.keycode == 0x20 || event.kbd.keycode == 0xC6)
     2142                                        runLoop = false;
     2143                                break;
     2144                        case OSystem::EVENT_QUIT:
     2145                                quitGame();
     2146                        case OSystem::EVENT_LBUTTONDOWN:
     2147                                runLoop = false;
     2148                                break;
     2149                        default:
     2150                                break;
     2151                        }
     2152                }
     2153                delay((loopStart + _gameSpeed) - _system->getMillis());
     2154        }
     2155
     2156        /*enableTimer(0x13);
     2157        enableTimer(0x0E);
     2158        enableTimer(0x12);
     2159        enableTimer(0x0F);
     2160        clearKyrandiaButtonIO();*/
     2161}
     2162
     2163void KyraEngine::endCharacterChat(int8 charNum, int16 convoInitialized) {
     2164        _charSayUnk3 = -1;
     2165
     2166        if (charNum > 4 && charNum < 11) {
     2167                //TODO: weird _game_inventory stuff here
     2168        }
     2169
     2170        if (convoInitialized != 0) {
     2171                _charSayUnk1 = -1;
     2172                _currentCharacter->currentAnimFrame = 7;
     2173                animRefreshNPC(0);
     2174                updateAllObjectShapes();
     2175        }
     2176}
     2177
     2178void KyraEngine::restoreChatPartnerAnimFrame(int8 charNum) {
     2179        _charSayUnk1 = -1;
     2180
     2181        if (charNum > 0 && charNum < 5) {
     2182                _characterList[charNum].currentAnimFrame = _currentChatPartnerBackupFrame;
     2183                animRefreshNPC(charNum);
     2184        }
     2185
     2186        _currentCharacter->currentAnimFrame = 7;
     2187        animRefreshNPC(0);
     2188        updateAllObjectShapes();
     2189}
     2190
     2191void KyraEngine::backupChatPartnerAnimFrame(int8 charNum) {
     2192        _charSayUnk1 = 0;
     2193
     2194        if (charNum < 5 && charNum > 0)
     2195                _currentChatPartnerBackupFrame = _characterList[charNum].currentAnimFrame;
     2196
     2197        if (_scaleMode != 0)
     2198                _currentCharacter->currentAnimFrame = 7;
     2199        else
     2200                _currentCharacter->currentAnimFrame = _currentCharAnimFrame;
     2201
     2202        animRefreshNPC(0);
     2203        updateAllObjectShapes();
     2204}
     2205
     2206int8 KyraEngine::getChatPartnerNum() {
     2207        uint8 sceneTable[] = {0x2, 0x5, 0x2D, 0x7, 0x1B, 0x8, 0x22, 0x9, 0x30, 0x0A};
     2208        int pos = 0;
     2209        int partner = -1;
     2210
     2211        for (int i = 1; i < 6; i++) {
     2212                if (_currentCharacter->sceneId == sceneTable[pos]) {
     2213                        partner = sceneTable[pos+1];
     2214                        break;
     2215                }
     2216                pos += 2;
     2217        }
     2218
     2219        for (int i = 1; i < 5; i++) {
     2220                if (_characterList[i].sceneId == _currentCharacter->sceneId) {
     2221                        partner = i;
     2222                        break;
     2223                }
     2224        }
     2225        return partner;
     2226}
     2227
     2228int KyraEngine::initCharacterChat(int8 charNum) {
     2229        if (_charSayUnk1 == -1) {
     2230                _charSayUnk1 = 0;
     2231
     2232                if (_scaleMode != 0)
     2233                        _currentCharacter->currentAnimFrame = 7;
     2234                else
     2235                        _currentCharacter->currentAnimFrame = 16;
     2236
     2237                animRefreshNPC(0);
     2238                updateAllObjectShapes();
     2239        }
     2240
     2241        _charSayUnk2 = -1;
     2242        flagAllObjectsForBkgdChange();
     2243        restoreAllObjectBackgrounds();
     2244
     2245        if( charNum > 4 && charNum < 11 ) {
     2246                // TODO: Fill in weird _game_inventory stuff here
     2247        }
     2248
     2249        flagAllObjectsForRefresh();
     2250        flagAllObjectsForBkgdChange();
     2251        preserveAnyChangedBackgrounds();
     2252        _charSayUnk3 = charNum;
     2253
     2254        return 1;
     2255}
     2256
     2257void KyraEngine::printCharacterText(char *text, int8 charNum) {
     2258        uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
     2259        int top, left, x1, x2, w, x;
     2260        char *msg;
     2261
     2262        uint8 color = colorTable[charNum];
     2263        text = preprocessString(text);
     2264        int lineCount = buildMessageSubstrings(text);
     2265        w = getWidestLineWidth(lineCount);
     2266        x = _characterList[charNum].x1;
     2267        calcWidestLineBounds(x1, x2, w, x);
     2268
     2269        for (int i = 0; i < lineCount; ++i) {
     2270                top = i * 10 + _talkMessageY;
     2271                msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
     2272                left = getCenterStringX(msg, x1, x2);
     2273                printText(msg, left, top, color, 0xC, 0);
     2274        }
     2275}
     2276
     2277void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
     2278        debug(9, "KyraEngine:::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
     2279        uint8 startAnimFrames[] =  { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 };
     2280
     2281        uint16 chatTicks;
     2282        int16 convoInitialized;
     2283        int8 chatPartnerNum;
     2284
     2285        if (_currentCharacter->sceneId == 0xD2)
     2286                return;
     2287
     2288        convoInitialized = initCharacterChat(charNum); 
     2289        chatPartnerNum = getChatPartnerNum();
     2290
     2291        if(chatPartnerNum != -1 && chatPartnerNum < 5)
     2292                backupChatPartnerAnimFrame(chatPartnerNum);
     2293
     2294        if (charNum < 5) {
     2295                _characterList[charNum].currentAnimFrame = startAnimFrames[charNum];
     2296                _charSayUnk3 = charNum;
     2297                _charSayUnk1 = charNum;
     2298                animRefreshNPC(charNum);
     2299        }
     2300
     2301        char *processedString = preprocessString(chatStr);
     2302        int lineNum = buildMessageSubstrings(processedString);
     2303
     2304        int16 YPos = _characterList[charNum].y1;
     2305        YPos -= _scaleTable[charNum] * _characterList[charNum].height;
     2306        YPos -= 8;
     2307        YPos -= lineNum * 10;
     2308
     2309        if (YPos < 11)
     2310                YPos = 11;
     2311
     2312        if (YPos > 100 )
     2313                YPos = 100;
     2314
     2315        _talkMessageY = YPos;
     2316        _talkMessageH = lineNum * 10;
     2317        restoreAllObjectBackgrounds();
     2318
     2319        _screen->copyRegion(1, _talkMessageY, 1, 136, 319, _talkMessageH, 2, 2);
     2320        _screen->hideMouse();
     2321
     2322        printCharacterText(processedString, charNum);
     2323        _screen->showMouse();
     2324
     2325        if (chatDuration == -2)
     2326                chatTicks = strlen(processedString) * 9;
     2327        else
     2328                chatTicks = chatDuration;
     2329
     2330        waitForChatToFinish(chatTicks, chatStr, charNum);
     2331
     2332        restoreAllObjectBackgrounds();
     2333
     2334        _screen->copyRegion(1, 136, 1, _talkMessageY, 319, _talkMessageH, 2, 2);
     2335        preserveAllBackgrounds();
     2336        prepDrawAllObjects();
     2337        _screen->hideMouse();
     2338
     2339        _screen->copyRegion(1, _talkMessageY, 1, _talkMessageY, 319, _talkMessageH, 2, 0);
     2340        _screen->showMouse();
     2341        flagAllObjectsForRefresh();
     2342        copyChangedObjectsForward(0);
     2343
     2344        if (chatPartnerNum != -1 && chatPartnerNum < 5)
     2345                restoreChatPartnerAnimFrame(chatPartnerNum);
     2346
     2347        endCharacterChat(charNum, convoInitialized);
     2348}
     2349
     2350void KyraEngine::drawSentenceCommand(char *sentence, int unk1) {
     2351        _screen->hideMouse();
     2352        _screen->fillRect(8, 143, 311, 152, 12);
     2353        // XXX: palette stuff
     2354
     2355        printText(sentence, 8, 143, 0xFF, 12, 0);
     2356        _screen->showMouse();
     2357        //setTextFadeTimerCountdown(_textFadeTimerCountdown);
     2358        //_palScrollEnabled = 0;
     2359}
     2360
     2361#pragma mark -
     2362#pragma mark - Item handling
     2363#pragma mark -
     2364
     2365void KyraEngine::addToNoDropRects(int x, int y, int w, int h) {
     2366        debug(9, "addToNoDropRects(%d, %d, %d, %d)", x, y, w, h);
     2367        for (int rect = 0; rect < 11; ++rect) {
     2368                if (_noDropRects[rect].x == -1) {
     2369                        _noDropRects[rect].x = x;
     2370                        _noDropRects[rect].y = y;
     2371                        _noDropRects[rect].x2 = x + w - 1;
     2372                        _noDropRects[rect].y2 = y + h - 1;
     2373                        break;
     2374                }
     2375        }
     2376}
     2377
     2378void KyraEngine::clearNoDropRects() {
     2379        debug(9, "clearNoDropRects()");
     2380        memset(_noDropRects, -1, sizeof(_noDropRects));
     2381}
     2382
     2383byte KyraEngine::findFreeItemInScene(int scene) {
     2384        debug(9, "findFreeItemInScene(%d)", scene);
     2385        assert(scene < _roomTableSize);
     2386        Room *room = &_roomTable[scene];
    20252387        for (int i = 0; i < 12; ++i) {
    20262388                if (room->itemsTable[i] != 0xFF)
    20272389                        return i;
     
    21272489#pragma mark - Animation specific code
    21282490#pragma mark -
    21292491
     2492void KyraEngine::preserveAllBackgrounds() {
     2493        uint8 currPage = _screen->_curPage;
     2494        _screen->_curPage = 2;
     2495
     2496        AnimObject *curObject = _objectQueue;
     2497        while (curObject) {
     2498                if (!curObject->active && curObject->flags) {
     2499                        preserveOrRestoreBackground(curObject, false);
     2500                        curObject->bkgdChangeFlag = 0;
     2501                }
     2502                curObject = curObject->nextAnimObject;
     2503        }
     2504        _screen->_curPage = currPage;
     2505}
     2506
     2507void KyraEngine::flagAllObjectsForBkgdChange() {
     2508        AnimObject *curObject = _objectQueue;
     2509        while (curObject) {
     2510                curObject->bkgdChangeFlag = 1;
     2511                curObject = curObject->nextAnimObject;
     2512        }
     2513}
     2514
     2515void KyraEngine::flagAllObjectsForRefresh() {
     2516        AnimObject *curObject = _objectQueue;
     2517        while (curObject) {
     2518                curObject->refreshFlag = 1;
     2519                curObject = curObject->nextAnimObject;
     2520        }
     2521}
     2522
    21302523void KyraEngine::restoreAllObjectBackgrounds() {
    21312524        debug(9, "restoreAllObjectBackground()");
    21322525        AnimObject *curObject = _objectQueue;
     
    22072600                flagUnk1 = 0x200;
    22082601        if (_brandonStatusBit & 0x40)
    22092602                flagUnk2 = 0x4000;
    2210        
     2603
    22112604        while (curObject) {
    22122605                if (curObject->active) {
    22132606                        int xpos = curObject->x1;
     
    22762669void KyraEngine::copyChangedObjectsForward(int refreshFlag) {
    22772670        debug(9, "copyChangedObjectsForward(%d)", refreshFlag);
    22782671        AnimObject *curObject = _objectQueue;
     2672
    22792673        while (curObject) {
    22802674                if (curObject->active) {
    22812675                        if (curObject->refreshFlag || refreshFlag) {
     
    22912685                }
    22922686                curObject = curObject->nextAnimObject;
    22932687        }
     2688        _screen->updateScreen();
    22942689}
    22952690
    22962691void KyraEngine::updateAllObjectShapes() {
     
    22992694        preserveAnyChangedBackgrounds();
    23002695        prepDrawAllObjects();
    23012696        copyChangedObjectsForward(0);
    2302 
    2303         _screen->updateScreen();
    23042697}
    23052698
    23062699void KyraEngine::animRefreshNPC(int character) {
    23072700        debug(9, "animRefreshNPC(%d)", character);
    23082701        AnimObject *animObj = &_charactersAnimState[character];
    23092702        Character *ch = &_characterList[character];
    2310        
     2703
    23112704        animObj->refreshFlag = 1;
    23122705        animObj->bkgdChangeFlag = 1;
    23132706        int facing = ch->facing;
     
    23522745        }
    23532746        animObj->width2 = 4;
    23542747        animObj->height2 = 3;
    2355        
     2748
    23562749        _objectQueue = objectRemoveQueue(_objectQueue, animObj);
    23572750        if (_objectQueue) {
    2358                
     2751                _objectQueue = objectQueue(_objectQueue, animObj);
    23592752        } else {
    2360                 _objectQueue = objectAddHead(_objectQueue, animObj);
     2753                _objectQueue = objectAddHead(0, animObj);
    23612754        }
    23622755}
    23632756
     
    23682761AnimObject *KyraEngine::objectRemoveQueue(AnimObject *queue, AnimObject *rem) {
    23692762        AnimObject *cur = queue;
    23702763        AnimObject *prev = queue;
     2764
    23712765        while (cur != rem && cur) {
    23722766                AnimObject *temp = cur->nextAnimObject;
    23732767                if (!temp)
     
    23832777        }
    23842778       
    23852779        if (!cur->nextAnimObject) {
    2386                 if (!prev) {
    2387                         return 0;
    2388                 } else {
    2389                         prev->nextAnimObject = 0;
     2780                if (cur == rem) {
     2781                        if (!prev) {
     2782                                return 0;
     2783                        } else {
     2784                                prev->nextAnimObject = 0;
     2785                        }
    23902786                }
    23912787        } else {
    23922788                if (cur == rem) {
     
    24242820                cur->nextAnimObject = add;
    24252821                add->nextAnimObject = 0;
    24262822        }
    2427         return 0;
     2823        return queue;
    24282824}
    24292825
    24302826#pragma mark -
     
    29373333                if (!temp)
    29383334                        continue;
    29393335                ++table;
    2940                 // XXX updateAnimFlags
     3336                _sprites->updateSceneAnims();
    29413337                // XXX updateMousePointer
    29423338                // XXX updateGameTimers
    29433339                updateAllObjectShapes();
  • kyra/kyra.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/kyra.h scummvm/kyra/kyra.h
    old new  
    8787        uint32 flags;
    8888        int16 drawY;
    8989        uint8 *sceneAnimPtr;
    90         uint16 animFrameNumber;
     90        int16 animFrameNumber;
    9191        uint8 *background;
    9292        uint16 rectSize;
    9393        int16 x1, y1;
     
    167167
    168168        uint8 game() const { return _game; }
    169169        uint32 features() const { return _features; }
    170         SceneExits sceneExits() const { return _sceneExits; }
    171         // ugly hack used by the dat loader
    172         SceneExits &sceneExits() { return _sceneExits; }
    173170       
    174171        Common::RandomSource _rnd;
    175172        int16 _northExitHeight;
    176173
     174        Character *_currentCharacter;
     175
    177176        typedef void (KyraEngine::*IntroProc)();
    178177        typedef int (KyraEngine::*OpcodeProc)(ScriptState *script);
    179178
     
    183182        const char **seqTextsTable() { return (const char **)_seq_textsTable; }
    184183
    185184        bool seq_skipSequence() const;
    186        
     185        void quitGame();
    187186        void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData);
    188187
    189188        void snd_playTheme(int file, int track = 0);
    190189        void snd_playTrack(int track);
    191190        void snd_playVoiceFile(int id);
    192191        bool snd_voicePlaying();
     192        void snd_playSoundEffect(int track);
    193193
    194194        void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
    195195        void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
     196        void drawSentenceCommand(char *sentence, int unk1);
    196197
    197198        WSAMovieV1 *wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf);
    198199        void wsa_close(WSAMovieV1 *wsa);
     
    200201        void wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum);
    201202
    202203        void waitTicks(int ticks);
     204        void updateAllObjectShapes();
     205        void flagAllObjectsForRefresh();
     206        void animRefreshNPC(int character);
     207        int16 fetchAnimWidth(const uint8 *shape, int16 mult);
     208        int8 fetchAnimHeight(const uint8 *shape, int8 mult);
    203209       
    204210        int mouseX() { return _mouseX; }
    205211        int mouseY() { return _mouseY; }
     
    377383        int getWidestLineWidth(int linesCount);
    378384        void calcWidestLineBounds(int &x1, int &x2, int w, int cx);
    379385        void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2);
     386        void characterSays(char *msg, int8 charNum, int8 chatDuration);
     387        int initCharacterChat(int8 charNum);
     388        int8 getChatPartnerNum();
     389        void backupChatPartnerAnimFrame(int8 charNum);
     390        void restoreChatPartnerAnimFrame(int8 charNum);
     391        void endCharacterChat(int8 charNum, int16 arg_4);
     392        void waitForChatToFinish(int16 chatDuration, char *str, uint8 charNum);
     393        void printCharacterText(char *text, int8 charNum);
     394
    380395        void setCharacterDefaultFrame(int character);
    381396        void setCharactersPositions(int character);
    382397        void setCharactersHeight();
     
    401416        byte findItemAtPos(int x, int y);
    402417        void placeItemInGenericMapScene(int item, int index);
    403418        void initSceneObjectList(int brandonAlive);
     419        void initSceneScreen(int brandonAlive);
     420        void preserveAllBackgrounds();
     421        void flagAllObjectsForBkgdChange();
    404422        void restoreAllObjectBackgrounds();
    405423        void preserveAnyChangedBackgrounds();
    406424        void preserveOrRestoreBackground(AnimObject *obj, bool restore);
    407425        void prepDrawAllObjects();
    408426        void copyChangedObjectsForward(int refreshFlag);
    409         void updateAllObjectShapes();
    410         void animRefreshNPC(int character);
    411427        int findDuplicateItemShape(int shape);
    412         int16 fetchAnimWidth(const uint8 *shape, int16 mult);
    413         int8 fetchAnimHeight(const uint8 *shape, int8 mult);
    414428        int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize);
    415429        int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end);
    416430        int getFacingFromPointToPoint(int x, int y, int toX, int toY);
     
    424438        AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem);
    425439        AnimObject *objectAddHead(AnimObject *queue, AnimObject *head);
    426440        AnimObject *objectQueue(AnimObject *queue, AnimObject *add);
    427        
     441        AnimObject *_animStates;
    428442        void seq_demo();
    429443        void seq_intro();
    430444        void seq_introLogos();
     
    438452        void snd_startTrack();
    439453        void snd_haltTrack();
    440454        void snd_setSoundEffectFile(int file);
    441         void snd_playSoundEffect(int track);
     455
    442456       
    443457        static OpcodeProc _opcodeTable[];
    444458        static const int _opcodeTableSize;
     
    509523        int16 _brandonScaleX;
    510524        int16 _brandonScaleY;
    511525        int _brandonDrawFrame;
     526
     527        uint16 _currentChatPartnerBackupFrame;
     528        uint16 _currentCharAnimFrame;
    512529       
    513530        int8 *_sceneAnimTable[50];
    514531       
     
    528545        int _lastFindWayRet;
    529546        int *_movFacingTable;
    530547       
     548        int8 _charSayUnk1; // this is byte_2EE24
     549        int8 _charSayUnk2;
     550        int8 _charSayUnk3; // this is byte_2EE25
     551        int8 _charSayUnk4; // this is byte_2EE26
     552
     553        uint8 _configTalkspeed;
    531554        AnimObject *_objectQueue;
    532         AnimObject *_animStates;
    533555        AnimObject *_charactersAnimState;
    534         AnimObject *_animObjects;
    535556        AnimObject *_animItems;
    536557       
    537558        int _curMusicTheme;
     
    553574        ScriptData *_scriptClickData;
    554575       
    555576        Character *_characterList;
    556         Character *_currentCharacter;
    557577       
    558578        uint8 *_seq_Forest;
    559579        uint8 *_seq_KallakWriting;
  • kyra/screen.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/screen.cpp scummvm/kyra/screen.cpp
    old new  
    6262        _decodeShapeBufferSize = 0;
    6363        _animBlockPtr = NULL;
    6464        _animBlockSize = 0;
    65         _mouseShape = NULL;
    66         _mouseShapeSize = 0;
    67         _mouseRect = NULL;
    68         _mouseRectSize = 0;
    69         _mouseDrawWidth = 0;
    7065}
    7166
    7267Screen::~Screen() {
     
    7570                _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0;
    7671        }
    7772        for (int f = 0; f < ARRAYSIZE(_fonts); ++f) {
    78                 free(_fonts[f].fontData);
     73                delete[] _fonts[f].fontData;
    7974                _fonts[f].fontData = NULL;
    8075        }
    8176        free(_currentPalette);
    8277        free(_screenPalette);
    8378        free(_decodeShapeBuffer);
    8479        free(_animBlockPtr);
    85         free(_mouseShape);
    86         free(_mouseRect);
    8780        for (int i = 0; i < 3; ++i) {
    8881                free(_palettes[i]);
    8982        }
     
    305298
    306299void Screen::copyCurPageBlock(int x, int y, int h, int w, uint8 *dst) {
    307300        debug(9, "Screen::copyCurPageBlock(%d, %d, %d, %d, 0x%X)", x, y, w, h, dst);
     301        assert(dst);
    308302        if (x < 0) {
    309303                x = 0; 
    310304        } else if (x >= 40) {
     
    389383        debug(9, "Screen::setAnimBlockPtr(%d)", size);
    390384        free(_animBlockPtr);
    391385        _animBlockPtr = (uint8 *)malloc(size);
     386        assert(_animBlockPtr);
     387        memset(_animBlockPtr, 0, size);
    392388        _animBlockSize = size;
    393389}
    394390
     
    15901586        debug(9, "hideMouse()");
    15911587        // if mouseDisabled
    15921588        //      return
    1593         restoreMouseRect();
     1589        _system->showMouse(false);
    15941590}
    15951591
    15961592void Screen::showMouse() {
    15971593        debug(9, "showMouse()");
    15981594        // if mouseDisabled
    15991595        //      return
    1600         copyMouseToScreen();
     1596        _system->showMouse(true);
    16011597}
    16021598
    16031599void Screen::setShapePages(int page1, int page2) {
     
    16061602        _shapePages[1] = _pagePtrs[page2];
    16071603}
    16081604
    1609 byte *Screen::setMouseCursor(int x, int y, byte *shape) {
     1605void Screen::setMouseCursor(int x, int y, byte *shape) {
    16101606        debug(9, "setMouseCursor(%d, %d, 0x%X)", x, y, shape);
    16111607        if (!shape)
    1612                 return _mouseShape;
     1608                return;
    16131609        // if mouseDisabled
    16141610        //      return _mouseShape
    1615        
    1616         restoreMouseRect();
    1617        
     1611
    16181612        if (_vm->features() & GF_TALKIE)
    16191613                shape += 2;
    1620        
    1621         int mouseRectSize = getRectSize((READ_LE_UINT16(shape + 3) >> 3) + 2, shape[5]);
    1622         if (_mouseRectSize < mouseRectSize) {
    1623                 free(_mouseRect);
    1624                 _mouseRect = (uint8*)malloc(mouseRectSize << 3);
    1625                 assert(_mouseRect);
    1626                 _mouseRectSize = mouseRectSize;
    1627         }
    1628        
    1629         int shapeSize = READ_LE_UINT16(shape + 8) + 10;
    1630         if (_vm->features() & GF_TALKIE)
    1631                 shapeSize += 2;
    1632         if (READ_LE_UINT16(shape) & 1)
    1633                 shapeSize += 16;
    1634        
    1635         if (_mouseShapeSize < shapeSize) {
    1636                 free(_mouseShape);
    1637                 _mouseShape = (uint8*)malloc(shapeSize);
    1638                 assert(_mouseShape);
    1639                 _mouseShapeSize = shapeSize;
    1640         }
    1641        
    1642         byte *dst = _mouseShape;
    1643         byte *src = shape;
    1644         if (_vm->features() & GF_TALKIE)
    1645                 dst += 2;
    1646        
    1647         if (!(READ_LE_UINT16(shape) & 2)) {
    1648                 uint16 newFlags = 0;
    1649                 newFlags = READ_LE_UINT16(src) | 2; src += 2;
    1650                 WRITE_LE_UINT16(dst, newFlags); dst += 2;
    1651                 memcpy(dst, src, 6);
    1652                 dst += 6;
    1653                 src += 6;
    1654                 int size = READ_LE_UINT16(src); src += 2;
    1655                 WRITE_LE_UINT16(dst, size); dst += 2;
    1656                 if (newFlags & 1) {
    1657                         memcpy(dst, src, 8);
    1658                         dst += 16;
    1659                         src += 16;
    1660                 }
    1661                 decodeFrame4(src, _animBlockPtr, size);
    1662                 memcpy(dst, _animBlockPtr, size);
    1663         } else {
    1664                 int size = READ_LE_UINT16(shape + 6);
    1665                 memcpy(dst, src, size);
    1666         }
    1667        
    1668         _mouseXOffset = x; _mouseYOffset = y;
    1669         if (_vm->features() & GF_TALKIE) {
    1670                 _mouseHeight = _mouseShape[7];
    1671                 _mouseWidth = (READ_LE_UINT16(_mouseShape + 5) >> 3) + 2;
    1672         } else {
    1673                 _mouseHeight = _mouseShape[5];
    1674                 _mouseWidth = (READ_LE_UINT16(_mouseShape + 3) >> 3) + 2;
    1675         }
    1676        
    1677         copyMouseToScreen();
    1678        
    1679         return _mouseShape;
    1680 }
    16811614
    1682 void Screen::restoreMouseRect() {
    1683         debug(9, "restoreMouseRect()");
    1684         // if disableMouse
    1685         //      return
     1615        int mouseHeight = *(shape+2);
     1616        int mouseWidth = (READ_LE_UINT16(shape + 3)) + 2;
    16861617       
    1687         if (_mouseDrawWidth && _mouseRect) {
    1688                 copyScreenFromRect(_mouseDrawX, _mouseDrawY, _mouseDrawWidth, _mouseDrawHeight, _mouseRect);
    1689         }
    1690         _mouseDrawWidth = 0;
    1691 }
     1618        uint8 *cursor = (uint8 *)malloc(mouseHeight * mouseWidth);
     1619        fillRect(0, 0, mouseWidth, mouseHeight, 0, 3);
     1620        drawShape(3, shape, 0, 0, 0, 0);
     1621
     1622        copyRegionToBuffer(3, 0, 0, mouseWidth, mouseHeight, cursor);
     1623        _system->setMouseCursor(cursor, mouseWidth, mouseHeight, 0, 0, 0);
     1624        _system->showMouse(true);
     1625        free(cursor);
     1626
     1627        return;
    16921628
    1693 void Screen::copyMouseToScreen() {
    1694         debug(9, "copyMouseToScreen()");
    1695         // if disableMouse
    1696         //      return
    1697        
    1698         restoreMouseRect();
    1699        
    1700         int width = _mouseWidth;
    1701         int height = _mouseHeight;
    1702         int xpos = _vm->mouseX() - _mouseXOffset;
    1703         int ypos = _vm->mouseY() - _mouseYOffset;
    1704         if (xpos < -1 || ypos < -1) {
    1705                 return;
    1706         }
    1707        
    1708         int xposTemp = xpos;
    1709         int yposTemp = ypos;
    1710        
    1711         if (xposTemp < 0) {
    1712                 xposTemp = 0;
    1713         }
    1714         if (yposTemp < 0) {
    1715                 height += ypos;
    1716                 yposTemp = 0;
    1717         }
    1718        
    1719         xposTemp >>= 3;
    1720         _mouseDrawX = xposTemp;
    1721         _mouseDrawY = yposTemp;
    1722        
    1723         xposTemp += width;
    1724         xposTemp -= 40;
    1725         if (xposTemp >= 0) {
    1726                 width -= xposTemp;
    1727         }
    1728        
    1729         yposTemp += height;
    1730         yposTemp -= 200;
    1731         if (yposTemp >= 0) {
    1732                 height -= yposTemp;
    1733         }
    1734        
    1735         _mouseDrawWidth = width;
    1736         _mouseDrawHeight = height;
    1737        
    1738         if (_mouseRect) {
    1739                 copyScreenToRect(_mouseDrawX, _mouseDrawY, width, height, _mouseRect);
    1740         }
    1741        
    1742         drawShape(0, _mouseShape, xpos, ypos, 0, 0, 0);
    17431629}
    17441630
    17451631void Screen::copyScreenFromRect(int x, int y, int w, int h, uint8 *ptr) {
  • kyra/screen.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/screen.h scummvm/kyra/screen.h
    old new  
    123123        void hideMouse();
    124124        void showMouse();
    125125        void setShapePages(int page1, int page2);
    126         byte *setMouseCursor(int x, int y, byte *shape);
     126        void setMouseCursor(int x, int y, byte *shape);
    127127        uint8 *getPalette(int num);
    128128       
    129129        byte getShapeFlag1(int x, int y);
     
    152152        int _decodeShapeBufferSize;
    153153        uint8 *_animBlockPtr;
    154154        int _animBlockSize;
    155        
    156         uint8 *_mouseShape;
    157         uint8 *_mouseRect;
    158         int _mouseShapeSize;
    159         int _mouseRectSize;
    160         int _mouseDrawX, _mouseDrawY;
    161         int _mouseDrawWidth, _mouseDrawHeight;
    162         int _mouseWidth, _mouseHeight;
    163         int _mouseXOffset, _mouseYOffset;
    164155
    165156        OSystem *_system;
    166157        KyraEngine *_vm;
  • kyra/script_v1.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/script_v1.cpp scummvm/kyra/script_v1.cpp
    old new  
    122122}
    123123
    124124void ScriptHelper::c1_ifNotJmp() {
    125         if (_curScript->stack[++_curScript->sp-1] != 0) {
     125        if (!_curScript->stack[++_curScript->sp-1] != 0) {
    126126                _parameter &= 0x7FFF;
    127127                _curScript->ip = _curScript->dataPtr->data + (_parameter << 1);
    128128        }
     
    296296#pragma mark -
    297297
    298298#define stackPos(x) script->stack[script->sp+x]
     299#define stackPosString(x) (char *)&script->dataPtr->text[READ_BE_UINT16( &((uint16 *)script->dataPtr->text)[stackPos(x)])]
    299300
    300301int KyraEngine::cmd_magicInMouseItem(ScriptState *script) {
    301302        warning("STUB: cmd_magicInMouseItem");
     
    303304}
    304305
    305306int KyraEngine::cmd_characterSays(ScriptState *script) {
    306         warning("STUB: cmd_characterSays");
     307        debug(9, "cmd_characterSays(0x%X)", script);
     308        // Japanese version?
     309        /*const char *str1 = "âuâëâôââôüAé?é¢ùêé¢é+é®üH";
     310        const char *str2 = "âuâëâôâ\\âôüAé?é¢ùêé¢é+é®üH";
     311
     312        if (strcmp(stackPosString(0), str1) == 0)
     313                characterSays((char *)str2, stackPos(1), stackPos(2));
     314        else*/
     315        characterSays(stackPosString(0), stackPos(1), stackPos(2));
     316
    307317        return 0;
    308318}
    309319
     
    314324
    315325int KyraEngine::cmd_drawSceneAnimShape(ScriptState *script) {
    316326        debug(9, "cmd_drawSceneAnimShape(0x%X)", script);
    317         _screen->drawShape(stackPos(4), _sprites->getSceneShape(stackPos(0)), stackPos(1), stackPos(2), 0, stackPos(3));
     327        _screen->drawShape( stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, stackPos(3) );
    318328        return 0;
    319329}
    320330
     
    417427
    418428int KyraEngine::cmd_sceneAnimOn(ScriptState *script) {
    419429        debug(9, "cmd_sceneAnimOn(0x%X)", script);
    420         _sprites->enableAnim(stackPos(0));
     430        _sprites->_anims[stackPos(0)].play = true;
    421431        return 0;
    422432}
    423433
    424434int KyraEngine::cmd_sceneAnimOff(ScriptState *script) {
    425435        debug(9, "cmd_sceneAnimOff(0x%X)", script);
    426         _sprites->disableAnim(stackPos(0));
     436        _sprites->_anims[stackPos(0)].play = false;
    427437        return 0;
    428438}
    429439
     
    530540}
    531541
    532542int KyraEngine::cmd_internalAnimOn(ScriptState *script) {
    533         warning("STUB: cmd_internalAnimOn");
     543        debug(9, "cmd_internalAnimOn(0x%X)", script);
     544        _sprites->_animObjects[stackPos(0)].active = 1;
    534545        return 0;
    535546}
    536547
     
    552563int KyraEngine::cmd_openWSAFile(ScriptState *script) {
    553564        debug(9, "cmd_openWSAFile(0x%X)", script);
    554565       
    555         int wsaIndex = stackPos(0);
    556         uint16 offset = READ_BE_UINT16(&script->dataPtr->text[wsaIndex]);
    557         char *filename = (char*)&script->dataPtr->text[offset];
    558        
    559         wsaIndex = stackPos(1);
     566        char *filename = stackPosString(0);
     567        int wsaIndex = stackPos(1);
    560568        // stackPos(2) is NOT used whyever
    561569        int offscreenDecode = 0;
    562570        if (!stackPos(3)) {
     
    646654}
    647655
    648656int KyraEngine::cmd_restoreAllObjectBackgrounds(ScriptState *script) {
    649         warning("STUB: cmd_restoreAllObjectBackgrounds");
     657        debug(9, "cmd_restoreAllObjectBackgrounds(0x%X)", script);
     658        restoreAllObjectBackgrounds();
    650659        return 0;
    651660}
    652661
     
    747756}
    748757
    749758int KyraEngine::cmd_internalAnimOff(ScriptState *script) {
    750         warning("STUB: cmd_internalAnimOff");
     759        debug(9, "cmd_internalAnimOff(0x%X)", script);
     760        _sprites->_animObjects[stackPos(0)].active = 0;
    751761        return 0;
    752762}
    753763
     
    916926                ++curPos;
    917927                // XXX
    918928                waitTicks(10);
    919                 // XXX updateAnimFlags();
     929                _sprites->updateSceneAnims();
    920930                // XXX updateMouseCursor();
    921931                // XXX updateGameTimers();
    922932                updateAllObjectShapes();
     
    951961}
    952962
    953963int KyraEngine::cmd_updateSceneAnimations(ScriptState *script) {
    954         warning("STUB: cmd_updateSceneAnimations");
     964        debug(9, "cmd_updateSceneAnimations(0x%X)", script);
     965        if (stackPos(0)) {
     966                _sprites->updateSceneAnims();
     967                updateAllObjectShapes();
     968        }
    955969        return 0;
    956970}
    957971
    958972int KyraEngine::cmd_sceneAnimationActive(ScriptState *script) {
    959         warning("STUB: cmd_sceneAnimationActive");
    960         return 0;
     973        debug(9, "cmd_sceneAnimationActive(0x%X)", script);
     974        return _sprites->_anims[stackPos(0)].play;
    961975}
    962976
    963977int KyraEngine::cmd_setCharactersMovementDelay(ScriptState *script) {
     
    10621076}
    10631077
    10641078int KyraEngine::cmd_setSceneAnimCurrXY(ScriptState *script) {
    1065         warning("STUB: cmd_setSceneAnimCurrXY");
     1079        debug(9, "cmd_setSceneAnimCurrXY(0x%X)", script);
     1080        _sprites->_anims[stackPos(0)].x = stackPos(1);
     1081        _sprites->_anims[stackPos(0)].y = stackPos(2);
    10661082        return 0;
    10671083}
    10681084
     
    12181234}
    12191235
    12201236int KyraEngine::cmd_message(ScriptState *script) {
    1221         warning("STUB: cmd_message");
     1237        debug(9, "cmd_message(0x%X)", script);
     1238        drawSentenceCommand(stackPosString(0), stackPos(1));
    12221239        return 0;
    12231240}
    12241241
  • kyra/sprites.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/sprites.cpp scummvm/kyra/sprites.cpp
    old new  
    4646Sprites::~Sprites() {
    4747        delete[] _dat;
    4848        freeSceneShapes();
     49        for (int i = 0; i < MAX_NUM_ANIMS; i++) {
     50                if (_anims[i].background)
     51                        free(_anims[i].background);
     52        }
    4953}
    5054
    51 uint8 *Sprites::getSceneShape(uint8 sceneShapeID) {
    52         assert( sceneShapeID < ARRAYSIZE(_sceneShapes));
    53         return _sceneShapes[sceneShapeID];
    54 }
    55 
    56 void Sprites::drawSprites(uint8 srcPage, uint8 dstPage) {
    57         int flags;
     55void Sprites::setupSceneAnims() {
     56        debug(9, "Sprites::setupSceneAnims()");
     57        uint8 *data;
    5858
    5959        for (int i = 0; i < MAX_NUM_ANIMS; i++) {
    60                 if (_anims[i].script == 0 || !_anims[i].play)
    61                         break;
    62                 if (_anims[i].sprite >= 0) {
    63                         assert( _anims[i].sprite < ARRAYSIZE(_sceneShapes));
    64                         uint8 *sprite = _sceneShapes[_anims[i].sprite];
    65 
    66                         //debug(1, "Drawing from X %i, Y %i, to X %i, Y %i, width %i, height %i, srcPage %i, dstPage %i",
    67                         //      sprite.x, sprite.y, _anims[i].x, _anims[i].y, sprite.width, sprite.height, srcPage, dstPage);
    68                         flags = Screen::CR_CLIPPED;
    69                         if (_anims[i].flipX)
    70                                 flags |= Screen::CR_X_FLIPPED;
     60                if (_anims[i].background) {
     61                        free(_anims[i].background);
     62                        _anims[i].background = 0;
     63                }
     64
     65                if (_anims[i].script != 0) {
     66                        data = _anims[i].script;
     67
     68                        assert( READ_LE_UINT16(data) == 0xFF86 );
     69                        data += 4;
    7170
    72                         //_screen->copyRegion(sprite.x, sprite.y, _anims[i].x, _anims[i].y, sprite.width, sprite.height, srcPage, dstPage, flags);
    73                         _screen->drawShape(0, sprite, _anims[i].x, _anims[i].y, 0, 0, 0);
     71                        //sceneUnk16[i] = READ_LE_UINT16(data);
     72                        data += 4;
     73                        _anims[i].unk2 = READ_LE_UINT16(data);
     74                        data += 4;
     75
     76                        if (_engine->_northExitHeight > READ_LE_UINT16(data))
     77                                _anims[i].drawY = _engine->_northExitHeight;
     78                        else
     79                                _anims[i].drawY = READ_LE_UINT16(data);
     80                        data += 4;
     81
     82                        //sceneUnk2[i] = READ_LE_UINT16(data);
     83                        data += 4;
     84                       
     85                        _anims[i].x = READ_LE_UINT16(data);
     86                        data += 4;
     87                        _anims[i].y = READ_LE_UINT16(data);
     88                        data += 4;
     89                        _anims[i].width = *(data);
     90                        data += 4;
     91                        _anims[i].height = *(data);
     92                        data += 4;
     93                        _anims[i].sprite = READ_LE_UINT16(data);
     94                        data += 4;
     95                        _anims[i].flipX = READ_LE_UINT16(data);
     96                        data += 4;
     97                        _anims[i].width2 = *(data);
     98                        data += 4;
     99                        _anims[i].height2 = *(data);
     100                        data += 4;
     101                        _anims[i].unk1 = READ_LE_UINT16(data);
     102                        data += 4;
     103                        _anims[i].play = READ_LE_UINT16(data);
     104                        data += 2;
     105
     106                        _anims[i].script = data;
     107
     108                        int bkgdWidth = _anims[i].width;
     109                        int bkgdHeight = _anims[i].height;
     110
     111                        if (_anims[i].width2)
     112                                bkgdWidth += (_anims[i].width2 >> 3) + 1;
     113
     114                        if (_anims[i].height2)
     115                                bkgdHeight += _anims[i].height2;
     116
     117                        _anims[i].background = (uint8 *)malloc(_screen->getRectSize(bkgdWidth + 1, bkgdHeight));
     118                        //_anims[i].background = (uint8 *)malloc(100*100);
     119                        assert(_anims[i].background);
    74120                }
    75121        }
    76122}
    77123
    78 void Sprites::doAnims() {
    79         debug(9, "Sprites::doAnims()");
     124void Sprites::updateSceneAnims() {
     125        debug(9, "Sprites::updateSceneAnims()");
    80126        uint32 currTime = _system->getMillis();
     127        uint8 *data;
     128        bool endLoop;
     129
    81130        for (int i = 0; i < MAX_NUM_ANIMS; i++) {
    82131                if (_anims[i].script == 0 || !_anims[i].play || _anims[i].nextRun != 0 && _anims[i].nextRun > currTime)
    83132                        continue;
    84133
    85                 uint8 *data;
    86 
    87134                if (_anims[i].reentry == 0) {
    88135                        data = _anims[i].script;
    89 
    90                         //debug(1, "---Start of anim script---");
    91                         assert( READ_LE_UINT16(data) == 0xFF86 );
    92                         data += 2;
    93 
    94                         //debug(1, "Default X of sprite: %i", READ_LE_UINT16(data + 0x12) );
    95                         _anims[i].x = READ_LE_UINT16(data + 0x12);
    96                         //debug(1, "Default Y of sprite: %i", READ_LE_UINT16(data + 0x16) );
    97                         _anims[i].y = READ_LE_UINT16(data + 0x16);
    98 
    99                         //debug(1, "Anim %i flags: 22h: %i, 1ah: %i", i, READ_LE_UINT16(data + 0x22), READ_LE_UINT16(data + 0x1a));
    100 
    101                         /*
    102                         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),
    103                         READ_LE_UINT16(data + 0x2), READ_LE_UINT16(data + 0x4),READ_LE_UINT16(data + 0x6),READ_LE_UINT16(data + 0x8),
    104                         READ_LE_UINT16(data + 0xa),READ_LE_UINT16(data + 0xc));
    105 
    106                         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),
    107                         READ_LE_UINT16(data + 0x10), READ_LE_UINT16(data + 0x12),READ_LE_UINT16(data + 0x14),READ_LE_UINT16(data + 0x16),
    108                         READ_LE_UINT16(data + 0x18),READ_LE_UINT16(data + 0x1a));
    109 
    110                         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),
    111                         READ_LE_UINT16(data + 0x1f), READ_LE_UINT16(data + 0x22),READ_LE_UINT16(data + 0x24),READ_LE_UINT16(data + 0x26),
    112                         READ_LE_UINT16(data + 0x28),READ_LE_UINT16(data + 0x2a));
    113                         */
    114 
    115 
    116                         // TODO: Find out what the rest of this data (next 38h bytes) does.
    117                         data += 0x38;
    118136                } else {
    119137                        data = _anims[i].reentry;
    120138                        _anims[i].reentry = 0;
    121139                }
    122140
    123                 bool endLoop = false;
    124                
     141                endLoop = false;
    125142                while (READ_LE_UINT16(data) != 0xFF87 && !endLoop) {
    126143                        uint16 rndNr;
    127144                        uint16 anim;
     
    142159                                _anims[i].y = READ_LE_UINT16(data);
    143160                                data += 2;
    144161                                _anims[i].flipX = false;
     162                                refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
    145163                                break;
    146164                        case 0xFF8D:
    147165                                data += 2;
     
    158176                                _anims[i].y = READ_LE_UINT16(data);
    159177                                data += 2;
    160178                                _anims[i].flipX = true;
     179                                refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
    161180                                break;
    162181                        case 0xFF8A:
    163182                                data += 2;
     
    174193                                data += 2;
    175194                                debug(5, "Maximum time %i", READ_LE_UINT16(data));
    176195                                data += 2;
    177                                 _anims[i].nextRun = _system->getMillis() + rndNr * _animDelay;                                                         
     196                                _anims[i].nextRun = _system->getMillis() + rndNr * _animDelay;
    178197                                break;
    179198                        case 0xFF8C:
    180199                                data += 2;
     
    185204                                break;
    186205                        case 0xFF99:
    187206                                data += 2;
    188                                 debug(1, "TODO func: Set value of animation property 32h to 1");
     207                                debug(1, "func: Set value of unknown animation property to 1");
     208                                _anims[i].unk1 = 1;
    189209                                break;
    190210                        case 0xFF9A:
    191211                                data += 2;
    192                                 debug(1, "TODO func: Set value of animation property 32h to 0");
     212                                debug(1, "func: Set value of unknown animation property to 0");
     213                                _anims[i].unk1 = 0;
    193214                                break;         
    194215                        case 0xFF97:
    195216                                data += 2;
     
    234255                                _anims[i].sprite = READ_LE_UINT16(data);
    235256                                _anims[i].flipX = false;
    236257                                data += 2;
     258                                refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
    237259                                break;
    238260                        case 0xFF91:
    239261                                data += 2;
     
    242264                                _anims[i].sprite = READ_LE_UINT16(data);
    243265                                _anims[i].flipX = true;
    244266                                data += 2;
     267                                refreshSceneAnimObject(i, _anims[i].sprite, _anims[i].x, _anims[i].y, _anims[i].flipX, _anims[i].unk1);
    245268                                break;
    246269                        case 0xFF92:
    247270                                data += 2;
     
    279302                                data += 2;
    280303                                _anims[anim].play = false;
    281304                                _anims[anim].sprite = -1;
    282                                 //debug(1, "Arg2 %i", READ_LE_UINT16(data));
    283                                 //data += 2;
    284305                                break;
    285306/*                      case 0xFF97:
    286307                                data += 2;
     
    288309                                break;*/
    289310                        case 0xFFAD:
    290311                                data += 2;
    291                                 debug(1, "TODO func: Set Brandon's X coordinate");
    292                                 debug(1, "X %i", READ_LE_UINT16(data));
     312                                debug(5, "func: Set Brandon's X coordinate");
     313                                debug(5, "X %i", READ_LE_UINT16(data));
     314                                _engine->_currentCharacter->x1 = READ_LE_UINT16(data);
    293315                                data += 2;
    294316                                break;
    295317                        case 0xFFAE:
    296318                                data += 2;
    297                                 debug(1, "TODO func: Set Brandon's Y coordinate");
    298                                 debug(1, "Y %i", READ_LE_UINT16(data));
     319                                debug(5, "func: Set Brandon's Y coordinate");
     320                                debug(5, "Y %i", READ_LE_UINT16(data));
     321                                _engine->_currentCharacter->y1 = READ_LE_UINT16(data);
    299322                                data += 2;
    300323                                break;
    301324                        case 0xFFAF:
    302325                                data += 2;
    303                                 debug(1, "TODO func: Set Brandon's X sprite");
    304                                 debug(1, "Sprite %i", READ_LE_UINT16(data));
     326                                debug(5, "func: Set Brandon's sprite");
     327                                debug(5, "Sprite %i", READ_LE_UINT16(data));
     328                                _engine->_currentCharacter->currentAnimFrame = READ_LE_UINT16(data);
    305329                                data += 2;
    306330                                break;
    307331                        case 0xFFAA:
     
    310334                                break;
    311335                        case 0xFFAB:
    312336                                data += 2;
    313                                 debug(1, "TODO func: Update Brandon's sprite");
     337                                debug(5, "func: Update Brandon's sprite");
     338                                _engine->animRefreshNPC(0);
     339                                _engine->flagAllObjectsForRefresh();
     340                                _engine->updateAllObjectShapes();
    314341                                break;
    315342                        case 0xFFB0:
    316343                                data += 2;
    317                                 debug(1, "TODO func: Play sound");
    318                                 debug(1, "Sound index %i", READ_LE_UINT16(data));
     344                                debug(5, "func: Play sound");
     345                                debug(5, "Sound index %i", READ_LE_UINT16(data));
     346                                _engine->snd_playSoundEffect(READ_LE_UINT16(data));
    319347                                data += 2;
    320348                                break;
    321349                        case 0xFFB1:
    322350                                data += 2;
    323                                 debug(1, "TODO func: Set unknown global bit");
     351                                debug(1, "TODO func: Set animator beacon flag");
    324352                                break;
    325353                        case 0xFFB2:
    326354                                data += 2;
    327                                 debug(1, "TODO func: Reset unknown global bit");
     355                                debug(1, "TODO func: Reset animator beacon flag");
    328356                                break;
    329357                        case 0xFFB4:
    330358                                data += 2;
    331                                 debug(1, "TODO func: Play (at random) a certain sound at a certain percentage of time");
    332                                 debug(1, "Sound index %i", READ_LE_UINT16(data));
    333                                 data += 2;
    334                                 debug(1, "Percentage %i", READ_LE_UINT16(data));
     359                                debug(5, "func: Play (at random) a certain sound at a certain percentage of time");
     360                                debug(5, "Sound index %i", READ_LE_UINT16(data));
     361                                int sound = READ_LE_UINT16(data);
     362                                data += 2;
     363                                debug(5, "Percentage %i", READ_LE_UINT16(data));
     364                                rndNr = _rnd.getRandomNumber(100);
     365                                if (rndNr <= READ_LE_UINT16(data))
     366                                        _engine->snd_playSoundEffect(sound);
    335367                                data += 2;
    336368                                break;
    337369                        case 0xFFA7:
     
    341373                                data += 2;
    342374                                break;
    343375                        default:
    344                                 debug(1, "Unsupported anim command %X", READ_LE_UINT16(data));
     376                                debug(1, "Unsupported anim command %X in script %i", READ_LE_UINT16(data), i);
    345377                                //endLoop = true;
    346378                                data += 1;
    347379                                break;
     
    350382
    351383                if (READ_LE_UINT16(data) == 0xFF87)
    352384                        _anims[i].play = false;
    353 
    354                 //debug(1, "---End of anim script---");
    355385        }
    356386}
    357387
    358 void Sprites::loadDAT(const char *filename) {
     388void Sprites::loadDAT(const char *filename, SceneExits &exits) {
    359389        debug(9, "Sprites::loadDat('%s')", filename);
    360390        uint32 fileSize;
    361         uint8 spritesLoaded = 0;
    362391
    363392        delete[] _dat;
     393        _spriteDefStart = 0;
    364394
    365395        _dat = _res->fileData(filename, &fileSize);
    366396
    367         memset(_anims, 0, sizeof(Anim) * MAX_NUM_ANIMS);
     397        memset(_anims, 0, sizeof(_anims));
    368398        uint8 nextAnim = 0;
    369399
    370400        assert(fileSize > 0x6D);
     
    380410        uint16 length = READ_LE_UINT16(data);
    381411        data += 2;
    382412
    383         //debug(1, "DAT body length: %i, filesize %i, current spot %i", length, fileSize, data - _dat);
    384 
    385413        if (length > 2) {
    386414                assert( length < fileSize);
    387415                uint8 *animstart;
     
    440468                data += 2;
    441469        }
    442470
    443         debug(1, "Room DAT file loaded. Found %i sprite and %i animation scripts.", spritesLoaded, nextAnim);
    444        
    445         //debug(1, "Remainder after script: %i", fileSize - (data - _dat));
    446471        assert(fileSize - (data - _dat) == 0xC);
    447472
    448         //TODO: Read in character entry coords here
    449         SceneExits &exits = _engine->sceneExits();
    450 
    451473        exits.northXPos = READ_LE_UINT16(data) & 0xFFFC; data += 2;
    452474        exits.northYPos = *data++ & 0xFFFE;
    453475        exits.eastXPos = READ_LE_UINT16(data) & 0xFFFC; data += 2;
     
    459481}
    460482
    461483void Sprites::freeSceneShapes() {
    462         for (int i = 0; i < ARRAYSIZE(_sceneShapes); i++ )
     484        debug(9, "Sprites::freeSceneShapes()");
     485        for (int i = 0; i < ARRAYSIZE(_sceneShapes); i++ ) {
    463486                free(_sceneShapes[i]);
    464        
     487                _sceneShapes[i] = 0;
     488        }
    465489}
    466490
    467491void Sprites::loadSceneShapes() {
     
    469493        uint8 *data = _spriteDefStart;
    470494        int spriteNum, x, y, width, height;
    471495
    472         assert(_spriteDefStart);
    473 
    474496        freeSceneShapes();
    475497        memset( _sceneShapes, 0, sizeof(_sceneShapes));
    476498
     499        if (_spriteDefStart == 0)
     500                return;
     501
     502        int bakPage = _screen->_curPage;
     503        _screen->_curPage = 3;
     504
    477505        while (READ_LE_UINT16(data) != 0xFF85) {
    478506                spriteNum = READ_LE_UINT16(data);
    479507                assert(spriteNum < ARRAYSIZE(_sceneShapes));
     
    486514                data += 2;
    487515                height = READ_LE_UINT16(data);
    488516                data += 2;
    489                 _sceneShapes[spriteNum] = _screen->encodeShape(x, y, width, height, 0);
     517                _sceneShapes[spriteNum] = _screen->encodeShape(x, y, width, height, 2);
     518                debug(9, "Sprite %i is at (%i, %i), width %i, height %i", spriteNum, x, y, width, height);
    490519        }
     520        _screen->_curPage = bakPage;
     521}
     522
     523void Sprites::refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag) {
     524        debug(9, "Sprites::refreshSceneAnimObject(%i, %i, %i, %i, %i, %i", animNum, shapeNum, x, y, flipX, unkFlag);
     525        _animObjects[animNum].refreshFlag = 1;
     526        _animObjects[animNum].bkgdChangeFlag = 1;
     527
     528        if (unkFlag)
     529                _animObjects[animNum].flags |= 0x0200;
     530        else
     531                _animObjects[animNum].flags &= 0xFD00;
     532
     533        if (flipX)
     534                _animObjects[animNum].flags |= 1;
     535        else
     536                _animObjects[animNum].flags &= 0xFE;
     537
     538        _animObjects[animNum].sceneAnimPtr = _sceneShapes[shapeNum];
     539        _animObjects[animNum].animFrameNumber = -1;
     540        _animObjects[animNum].x1 = x;
     541        _animObjects[animNum].y1 = y;
    491542}
    492543
    493544} // end of namespace Kyra
  • kyra/sprites.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/sprites.h scummvm/kyra/sprites.h
    old new  
    4545        uint8 *reentry;
    4646        uint32 nextRun;
    4747        bool play;
     48        uint16 width;
     49        uint16 height;
     50        uint16 width2;
     51        uint16 height2;
     52        uint16 unk1;
     53        uint16 drawY;
     54        uint16 unk2;
     55        uint8 *background;
    4856};
    4957
    5058class Sprites {
     
    5361        Sprites(KyraEngine *engine, OSystem *system);
    5462        ~Sprites();
    5563
    56         void doAnims();
    57         void loadDAT(const char *filename);
    58         uint8 *getSceneShape(uint8 sceneShapeID);
    59         void drawSprites(uint8 srcPage, uint8 dstPage);
     64        void updateSceneAnims();
     65        void setupSceneAnims();
     66        void loadDAT(const char *filename, SceneExits &exits);
    6067        void loadSceneShapes();
    6168       
    62         void enableAnim(uint8 anim) { _anims[anim].play = true; }
    63         void disableAnim(uint8 anim) { _anims[anim].play = false; }
     69        Anim _anims[MAX_NUM_ANIMS];
     70        AnimObject *_animObjects;
     71        uint8 *_sceneShapes[50];
     72
     73        void refreshSceneAnimObject(uint8 animNum, uint8 shapeNum, uint16 x, uint16 y, bool flipX, bool unkFlag);
    6474
    6575protected:
    6676        void freeSceneShapes();
     
    6979        Resource *_res;
    7080        OSystem *_system;
    7181        Screen *_screen;
    72         uint8 *_sceneShapes[50];
    7382        uint8 *_dat;
    74         Anim _anims[MAX_NUM_ANIMS];
    7583        Common::RandomSource _rnd;
    7684        uint8 _animDelay;
    7785        uint8 *_spriteDefStart;