Ticket #8485: kyra_timers_v1.patch

File kyra_timers_v1.patch, 16.7 KB (added by vinterstum, 14 years ago)

KYRA: timers (against 11. nov CVS)

  • kyra/kyra.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/kyra.cpp scummvm/kyra/kyra.cpp
    old new  
    330330        _pathfinderFlag = 0;
    331331        _lastFindWayRet = 0;
    332332        _sceneChangeState = _loopFlag2 = 0;
    333        
     333        _timerNextRun = 0;
     334
    334335        _movFacingTable = new int[150];
    335336        assert(_movFacingTable);
    336337        _movFacingTable[0] = 8;
     
    449450        loadSpecialEffectShapes();
    450451        loadItems();
    451452        loadMainScreen();
     453        setupTimers();
    452454        loadPalette("PALETTE.COL", _screen->_currentPalette);
    453         _screen->setScreenPalette(_screen->_currentPalette);
     455
    454456        // XXX
    455457        initAnimStateList();
    456458        setCharactersInDefaultScene();
    457459
    458460        _gameSpeed = 50;
    459        
     461        _tickLength = (uint8)(1000.0 / _gameSpeed);
     462
    460463        if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, _opcodeTable, _opcodeTableSize, 0)) {
    461464                error("Could not load \"_STARTUP.EMC\" script");
    462465        }
     
    498501                                _mouseY = event.mouse.y;
    499502                                break;
    500503                        case OSystem::EVENT_QUIT:
    501                                 _quitFlag = true;
     504                                quitGame();
    502505                                break;
    503506                        default:
    504507                                break;
    505508                        }
    506509                }
     510                _sprites->updateSceneAnims();
     511                updateAllObjectShapes();
     512
     513                if (_currentCharacter->sceneId == 210) {
     514                        //XXX
     515                }
     516
    507517                if (amount > 0) {
    508518                        _system->delayMillis((amount > 10) ? 10 : amount);
    509519                }
     
    516526        while (!_quitFlag) {
    517527                int32 frameTime = (int32)_system->getMillis();
    518528
    519                 _sprites->updateSceneAnims();
    520                 updateAllObjectShapes();
     529                updateGameTimers();
    521530
    522531                delay((frameTime + _gameSpeed) - _system->getMillis());
    523532        }
     
    12441253
    12451254void KyraEngine::setCharacterPositionWithUpdate(int character) {
    12461255        debug(9, "setCharacterPositionWithUpdate(%d)", character);
    1247         // XXX game_updateAnimsFlags
     1256        _sprites->updateSceneAnims();
    12481257        setCharacterPosition(character, 0);
    12491258        updateAllObjectShapes();
    12501259        // XXX processPalette
     
    14451454        loadBitmap(fileNameBuffer, 3, 3, 0);
    14461455
    14471456        _sprites->loadSceneShapes();
    1448         // TODO: check there it is done normally
     1457
     1458        _screen->fillRect(4, 4, 312, 136, 0, 0);
     1459        _screen->updateScreen();
    14491460        _screen->setScreenPalette(_screen->_currentPalette);
    14501461        _screen->copyRegion(4, 4, 4, 4, 308, 132, 3, 0);
    14511462
     
    20672078        bool runLoop = true;
    20682079        uint8 currPage;
    20692080        OSystem::Event event;
    2070         uint8 tickLength = (uint8)(1000.0 / _gameSpeed);
     2081        int16 delayTime;
    20712082
    20722083        //while( towns_isEscKeyPressed() )
    20732084                //towns_getKey();
    20742085
    2075         uint32 timeToEnd = strlen(chatStr) * 8 * tickLength + _system->getMillis();
     2086        uint32 timeToEnd = strlen(chatStr) * 8 * _tickLength + _system->getMillis();
    20762087
    20772088        if (chatDuration != -1 ) {
    20782089                switch ( _configTalkspeed) {
     
    20852096        }
    20862097
    20872098        if (chatDuration != -1)
    2088                 chatDuration *= tickLength;
     2099                chatDuration *= _tickLength;
    20892100
    2090         //disableTimer(0x13);
    2091         //disableTimer(0x0E);
    2092         //disableTimer(0x12);
    2093         //towns_flushKeyb();
     2101        disableTimer(14);
     2102        disableTimer(18);
     2103        disableTimer(19);
    20942104
    20952105        uint32 timeAtStart = _system->getMillis();
    20962106        uint32 loopStart;
     
    21042114
    21052115                if( _system->getMillis() < timeToEnd && !hasUpdatedNPCs) {
    21062116                        hasUpdatedNPCs = true;
    2107                         //disableTimer(0x0F);
     2117                        disableTimer(16);
    21082118                        _charSayUnk4 = 4;
    21092119                        animRefreshNPC(0);
    21102120                        animRefreshNPC(_charSayUnk1);
     
    21162126                        }
    21172127                }
    21182128
    2119                 //updateGameTimers();
     2129                updateGameTimers();
    21202130                _sprites->updateSceneAnims();
    21212131                restoreAllObjectBackgrounds();
    21222132                preserveAnyChangedBackgrounds();
     
    21482158                                break;
    21492159                        }
    21502160                }
    2151                 delay((loopStart + _gameSpeed) - _system->getMillis());
     2161
     2162                delayTime = (loopStart + _gameSpeed) - _system->getMillis();
     2163                if (delayTime > 0)
     2164                        _system->delayMillis(delayTime);
    21522165        }
    21532166
    2154         /*enableTimer(0x13);
    2155         enableTimer(0x0E);
    2156         enableTimer(0x12);
    2157         enableTimer(0x0F);
    2158         clearKyrandiaButtonIO();*/
     2167        enableTimer(14);
     2168        enableTimer(16);
     2169        enableTimer(18);
     2170        enableTimer(19);
     2171        //clearKyrandiaButtonIO();
    21592172}
    21602173
    21612174void KyraEngine::endCharacterChat(int8 charNum, int16 convoInitialized) {
     
    27602773void KyraEngine::copyChangedObjectsForward(int refreshFlag) {
    27612774        debug(9, "copyChangedObjectsForward(%d)", refreshFlag);
    27622775        AnimObject *curObject = _objectQueue;
     2776        bool changed = false;
    27632777
    27642778        while (curObject) {
    27652779                if (curObject->active) {
     
    27722786                               
    27732787                                _screen->copyRegion(xpos, ypos, xpos, ypos, width<<3, height, 2, 0, Screen::CR_CLIPPED);
    27742788                                curObject->refreshFlag = 0;
     2789                                changed = true;
    27752790                        }
    27762791                }
    27772792                curObject = curObject->nextAnimObject;
    27782793        }
    2779         _screen->updateScreen();
     2794        if (changed)
     2795                _screen->updateScreen();
    27802796}
    27812797
    27822798void KyraEngine::updateAllObjectShapes() {
     
    34263443                _sprites->updateSceneAnims();
    34273444                waitTicks(10);
    34283445                // XXX updateMousePointer
    3429                 // XXX updateGameTimers
     3446                updateGameTimers();
    34303447                updateAllObjectShapes();
    34313448                // XXX processPalette
    34323449                if (_currentCharacter->sceneId == 210) {
     
    35593576        enterNewScene(sceneId, facing, 1, 1, 0);
    35603577        return returnValue;
    35613578}
     3579
     3580#pragma mark -
     3581#pragma mark - Timer handling
     3582#pragma mark -
     3583
     3584void KyraEngine::setupTimers() {
     3585        debug(9, "KyraEngine::setupTimers()");
     3586        memset(_timers, 0, sizeof(_timers));
     3587
     3588        for (int i = 0; i < 34; i++)
     3589                _timers[i].active = 1;
     3590
     3591        _timers[0].func = _timers[1].func = _timers[2].func = _timers[3].func = _timers[4].func = 0; //Unused.
     3592        _timers[5].func = _timers[6].func = _timers[7].func = _timers[8].func = _timers[9].func = 0; //_nullsub51;
     3593        _timers[10].func = _timers[11].func = _timers[12].func = _timers[13].func = 0; //_nullsub50;
     3594        _timers[14].func = &Kyra::KyraEngine::timerCheckAnimFlag2;; //_nullsub52;
     3595        _timers[15].func = &Kyra::KyraEngine::timerUpdateHeadAnims; //_nullsub48;
     3596        _timers[16].func = &Kyra::KyraEngine::timerSetFlags1; //_nullsub47;
     3597        _timers[17].func = 0; //sub_15120;
     3598        _timers[18].func = &Kyra::KyraEngine::timerCheckAnimFlag1; //_nullsub53;
     3599        _timers[19].func = &Kyra::KyraEngine::timerRedrawAmulet; //_nullsub54;
     3600        _timers[20].func = 0; //offset _timerDummy1
     3601        _timers[21].func = 0; //sub_1517C;
     3602        _timers[22].func = 0; //offset _timerDummy2
     3603        _timers[23].func = 0; //offset _timerDummy3,
     3604        _timers[24].func = 0; //_nullsub45;
     3605        _timers[25].func = 0; //offset _timerDummy4
     3606        _timers[26].func = 0; //_nullsub46;
     3607        _timers[27].func = 0; //offset _timerDummy5,
     3608        _timers[28].func = 0; //offset _timerDummy6
     3609        _timers[29].func = 0; //offset _timerDummy7,
     3610        _timers[30].func = 0; //offset _timerDummy8,
     3611        _timers[31].func = 0; //sub_151F8;
     3612        _timers[32].func = 0; //_nullsub61;
     3613        _timers[33].func = 0; //_nullsub62;
     3614
     3615        _timers[0].countdown = _timers[1].countdown = _timers[2].countdown = _timers[3].countdown = _timers[4].countdown = -1;
     3616        _timers[5].countdown = 5;
     3617        _timers[6].countdown = 7;
     3618        _timers[7].countdown = 8;
     3619        _timers[8].countdown = 9;
     3620        _timers[9].countdown = 7;
     3621        _timers[10].countdown = _timers[11].countdown = _timers[12].countdown = _timers[13].countdown = 420;
     3622        _timers[14].countdown = 600;
     3623        _timers[15].countdown = 11;
     3624        _timers[16].countdown = _timers[17].countdown = 7200;
     3625        _timers[18].countdown = _timers[19].countdown = 600;
     3626        _timers[20].countdown = 7200;
     3627        _timers[21].countdown = 18000;
     3628        _timers[22].countdown = 7200;
     3629        _timers[23].countdown = _timers[24].countdown = _timers[25].countdown = _timers[26].countdown = _timers[27].countdown = 10800;
     3630        _timers[28].countdown = 21600;
     3631        _timers[29].countdown = 7200;
     3632        _timers[30].countdown = 10800;
     3633        _timers[31].countdown = -1;
     3634        _timers[32].countdown = 9;
     3635        _timers[33].countdown = 3;
     3636
     3637}
     3638
     3639void KyraEngine::updateGameTimers() {
     3640        debug(9, "KyraEngine::updateGameTimers()");
     3641        void (Kyra::KyraEngine::*callback)(int timerNum);
     3642       
     3643        if (_system->getMillis() < _timerNextRun)
     3644                return;
     3645
     3646        _timerNextRun += 99999;
     3647
     3648        for (int i = 0; i < 34; i++) {
     3649                if (_timers[i].active && _timers[i].countdown > -1) {
     3650                        if (_timers[i].nextRun <=_system->getMillis()) {
     3651                                if (i < 5)
     3652                                        callback = 0;
     3653                                else
     3654                                        callback = _timers[i].func;
     3655
     3656                                if (callback)
     3657                                        (*this.*callback)(i);
     3658
     3659                                _timers[i].nextRun = _system->getMillis() + _timers[i].countdown * _tickLength;
     3660
     3661                        }
     3662                }
     3663                if (_timers[i].nextRun < _timerNextRun)
     3664                        _timerNextRun = _timers[i].nextRun;
     3665        }
     3666}
     3667
     3668void KyraEngine::clearNextEventTickCount() {
     3669        debug(9, "KyraEngine::clearNextEventTickCount()");
     3670        _timerNextRun = 0;
     3671}
     3672
     3673int16 KyraEngine::getTimerDelay(uint8 timer) {
     3674        return _timers[timer].countdown;
     3675}
     3676
     3677void KyraEngine::setTimerCountdown(uint8 timer, int16 countdown) {
     3678        debug(9, "KyraEngine::setTimerCountdown(%i, %i)", timer, countdown);
     3679        _timers[timer].countdown = countdown;
     3680
     3681        uint32 nextRun = _system->getMillis() + countdown;
     3682        if (nextRun < _timerNextRun)
     3683                _timerNextRun = nextRun;
     3684}
     3685
     3686void KyraEngine::enableTimer(uint8 timer) {
     3687        debug(9, "KyraEngine::enableTimer(%i)", timer);
     3688        _timers[timer].active = 1;
     3689}
     3690
     3691void KyraEngine::disableTimer(uint8 timer) {
     3692        debug(9, "KyraEngine::disableTimer(%i)", timer);
     3693        _timers[timer].active = 0;
     3694}
     3695
     3696void KyraEngine::timerUpdateHeadAnims(int timerNum) {
     3697        debug(9, "KyraEngine::timerUpdateHeadAnims(%i)", timerNum);
     3698        static int8 currentFrame = 0;
     3699        static const int8 frameTable[] = {4, 5, 4, 5, 4, 5, 0, 1, 4, 5,
     3700                                                                4, 4, 6, 4, 8, 1, 9, 4, -1};
     3701
     3702        if (_charSayUnk1 < 0)
     3703                return;
     3704
     3705        _charSayUnk4 = frameTable[currentFrame];
     3706        currentFrame++;
     3707
     3708        if (frameTable[currentFrame] == -1)
     3709                currentFrame = 0;
     3710
     3711        animRefreshNPC(0);
     3712        animRefreshNPC(_charSayUnk1);
     3713}
     3714
     3715void KyraEngine::timerSetFlags1(int timerNum) {
     3716        debug(9, "KyraEngine::timerSetFlags(%i)", timerNum);
     3717        if (_currentCharacter->sceneId == 0x1C)
     3718                return;
     3719
     3720        int rndNr = _rnd.getRandomNumberRng(0, 3);
     3721
     3722        for (int i = 0; i < 4; i++) {
     3723                if (!queryGameFlag(rndNr + 17)) {
     3724                        setGameFlag(rndNr + 17);
     3725                        break;
     3726                } else {
     3727                        rndNr++;
     3728                        if (rndNr > 3)
     3729                                rndNr = 0;
     3730                }
     3731        }
     3732}
     3733
     3734void KyraEngine::timerSetFlags2(int timerNum) {
     3735        if (!((uint32*)(_flagsTable+0x2D))[timerNum])
     3736                ((uint32*)(_flagsTable+0x2D))[timerNum] = 1;   
     3737}
     3738
     3739void KyraEngine::timerCheckAnimFlag1(int timerNum) {
     3740        debug(9, "KyraEngine::timerCheckAnimFlag1(%i)", timerNum);
     3741        if (_brandonStatusBit & 0x20) {
     3742                checkSpecialAnimFlags();
     3743                setTimerCountdown(18, -1);
     3744        }
     3745}
     3746
     3747void KyraEngine::timerCheckAnimFlag2(int timerNum) {
     3748        debug(9, "KyraEngine::timerCheckAnimFlag1(%i)", timerNum);
     3749        if (_brandonStatusBit & 0x2) {
     3750                checkSpecialAnimFlags();
     3751                setTimerCountdown(14, -1);
     3752        }
     3753}
     3754
     3755void KyraEngine::checkSpecialAnimFlags() {
     3756        debug(9, "KyraEngine::checkSpecialAnimFlags()");
     3757        if (_brandonStatusBit & 2) {
     3758                warning("STUB: playSpecialAnim1");
     3759                // XXX
     3760                setTimerCountdown(19, 300);
     3761        }
     3762
     3763        if (_brandonStatusBit & 0x20) {
     3764                warning("STUB: playSpecialAnim2");
     3765                // XXX
     3766                setTimerCountdown(19, 300);
     3767        }
     3768}
     3769
     3770void KyraEngine::timerRedrawAmulet(int timerNum) {
     3771        if (queryGameFlag(241)) {
     3772                drawAmulet();
     3773                setTimerCountdown(0x13, -1);
     3774        }
     3775}
     3776
     3777void KyraEngine::drawAmulet() {
     3778        static const int16 amuletTable1[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x150, 0x155, 0x15A, 0x15F, 0x164, 0x145, -1};
     3779        static const int16 amuletTable3[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x14F, 0x154, 0x159, 0x15E, 0x163, 0x144, -1};
     3780        static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1};
     3781        static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1};
     3782
     3783        _screen->hideMouse();
     3784
     3785        int i = 0;
     3786        while (amuletTable1[i] != -1) {
     3787                if (queryGameFlag(87))
     3788                        _screen->drawShape(0, _shapes[ 4+amuletTable1[i] ], _amuletX[0], _amuletY[0], 0, 0);
     3789
     3790                if (queryGameFlag(89))
     3791                        _screen->drawShape(0, _shapes[ 4+amuletTable2[i] ], _amuletX[1], _amuletY[1], 0, 0);
     3792
     3793                if (queryGameFlag(86))
     3794                        _screen->drawShape(0, _shapes[ 4+amuletTable3[i] ], _amuletX[2], _amuletY[2], 0, 0);
     3795
     3796                if (queryGameFlag(88))
     3797                        _screen->drawShape(0, _shapes[ 4+amuletTable4[i] ], _amuletX[3], _amuletY[3], 0, 0);
     3798
     3799                delay(3 * _tickLength);
     3800                i++;
     3801        }
     3802        _screen->showMouse();
     3803}
     3804
    35623805} // End of namespace Kyra
  • kyra/kyra.h

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/kyra.h scummvm/kyra/kyra.h
    old new  
    142142struct ScriptState;
    143143struct ScriptData;
    144144class ScriptHelper;
     145class KyraEngine;
     146
     147struct Timer {
     148        bool active;
     149        int16 countdown;
     150        uint32 nextRun;
     151        void (Kyra::KyraEngine::*func)(int timerNum);
     152};
    145153
    146154class KyraEngine : public Engine {
    147155        friend class MusicPlayer;
     
    195203        void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
    196204        void drawSentenceCommand(char *sentence, int unk1);
    197205
     206        void updateGameTimers();
     207        void clearNextEventTickCount();
     208        void setTimerCountdown(uint8 timer, int16 countdown);
     209        int16 getTimerDelay(uint8 timer);
     210        void enableTimer(uint8 timer);
     211        void disableTimer(uint8 timer);
     212
    198213        WSAMovieV1 *wsa_open(const char *filename, int offscreenDecode, uint8 *palBuf);
    199214        void wsa_close(WSAMovieV1 *wsa);
    200215        uint16 wsa_getNumFrames(WSAMovieV1 *wsa) const;
     
    480495        void setCharactersInDefaultScene();
    481496        void resetBrandonPosionFlags();
    482497        void initAnimStateList();
     498       
     499        void setupTimers();
     500        void timerUpdateHeadAnims(int timerNum);
     501        void timerSetFlags1(int timerNum);
     502        void timerSetFlags2(int timerNum);
     503        void timerCheckAnimFlag1(int timerNum);
     504        void timerCheckAnimFlag2(int timerNum);
     505        void checkSpecialAnimFlags();
     506        void timerRedrawAmulet(int timerNum);
     507        void drawAmulet();
    483508
    484509        uint8 _game;
    485510        bool _fastMode;
     
    495520        uint8 _flagsTable[53];
    496521        uint8 *_shapes[377];
    497522        uint16 _gameSpeed;
     523        uint16 _tickLength;
    498524        uint32 _features;
    499525        int _mouseX, _mouseY;
    500526        bool _needMouseUpdate;
     
    606632        int _roomTableSize;     
    607633        char **_roomFilenameTable;
    608634        int _roomFilenameTableSize;
    609        
     635
     636        Timer _timers[34];
     637        uint32 _timerNextRun;   
    610638        static const char *_xmidiFiles[];
    611639        static const int _xmidiFilesCount;
    612640       
     
    614642        static const int8 _addXPosTable[];
    615643        static const int8 _charYPosTable[];
    616644        static const int8 _addYPosTable[];
     645
     646        static const uint16 _amuletX[];
     647        static const uint16 _amuletY[];
     648
    617649};
    618650
    619651} // End of namespace Kyra
  • kyra/script_v1.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/script_v1.cpp scummvm/kyra/script_v1.cpp
    old new  
    373373
    374374int KyraEngine::cmd_walkPlayerToPoint(ScriptState *script) {
    375375        debug(9, "cmd_walkPlayerToPoint(0x%X)", script);
    376         // if !stackPos(2)
    377         // XXX
     376
     377        if (!stackPos(2)) {
     378                disableTimer(19);
     379                disableTimer(14);
     380                disableTimer(18);
     381        }
     382
    378383        int reinitScript = handleSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
    379         // XXX
     384
     385        if (!stackPos(2)) {
     386                enableTimer(19);
     387                enableTimer(14);
     388                enableTimer(18);
     389        }
     390
    380391        if (reinitScript) {
    381392                _scriptInterpreter->initScript(script, script->dataPtr);
    382393        }
     
    520531
    521532int KyraEngine::cmd_pauseSeconds(ScriptState *script) {
    522533        debug(9, "cmd_pauseSeconds(0x%X)", script);
    523         _system->delayMillis(stackPos(0)*1000);
     534        delay(stackPos(0)*1000);
    524535        return 0;
    525536}
    526537
     
    921932        int toX = stackPos(1);
    922933        int toY = stackPos(2);
    923934        _pathfinderFlag2 = 1;
     935        uint32 nextFrame;
    924936        int findWayReturn = findWay(_characterList[character].x1, _characterList[character].y1, toX, toY, _movFacingTable, 150);
    925937        _pathfinderFlag2 = 0;
    926938        if (_lastFindWayRet < findWayReturn) {
     
    980992                        continue;
    981993                }
    982994               
     995                nextFrame = getTimerDelay(5 + character) * _tickLength + _system->getMillis();
    983996                setCharacterPosition(character, 0);
    984997                ++curPos;
    985                 // XXX
    986                 waitTicks(10);
    987                 _sprites->updateSceneAnims();
    988                 // XXX updateMouseCursor();
    989                 // XXX updateGameTimers();
    990                 updateAllObjectShapes();
    991                 // XXX processPalette();
     998
     999                while (_system->getMillis() < nextFrame) {
     1000                        _sprites->updateSceneAnims();
     1001                        // XXX updateMouseCursor();
     1002                        updateGameTimers();
     1003                        updateAllObjectShapes();
     1004                        // XXX processPalette();
     1005                        if ((nextFrame - _system->getMillis()) >= 10)
     1006                                _system->delayMillis(10);
     1007                }
    9921008        }
    9931009        return 0;
    9941010}
  • kyra/sprites.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/sprites.cpp scummvm/kyra/sprites.cpp
    old new  
    405405                _engine->_northExitHeight += 1;
    406406        // XXX 
    407407        memcpy(_screen->_currentPalette + 745 - 0x3D, _dat + 0x17, 0x3D);
    408         _screen->setScreenPalette(_screen->_currentPalette);
    409408        uint8 *data = _dat + 0x6B;
    410409
    411410        uint16 length = READ_LE_UINT16(data);
  • kyra/staticres.cpp

    diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvmcvs/kyra/staticres.cpp scummvm/kyra/staticres.cpp
    old new  
    589589        0, -2, -2, -2, 0, 2, 2, 2
    590590};
    591591
     592const uint16 KyraEngine::_amuletX[] = {231, 275, 253, 253};
     593const uint16 KyraEngine::_amuletY[] = {170, 170, 159, 181};
     594
    592595} // End of namespace Kyra