diff options
author | Joseph-Eugene Winzer | 2017-07-25 02:11:00 +0200 |
---|---|---|
committer | Thierry Crozat | 2018-01-23 00:29:34 +0000 |
commit | 0462bd0184edf230b92e6513eb4f6ca0804ec73f (patch) | |
tree | 340fa6da4737d9d31aa702b5665001dd89f2a641 | |
parent | 97ef7cbe871791a48dbcaf3d0b983ff85afe3640 (diff) | |
download | scummvm-rg350-0462bd0184edf230b92e6513eb4f6ca0804ec73f.tar.gz scummvm-rg350-0462bd0184edf230b92e6513eb4f6ca0804ec73f.tar.bz2 scummvm-rg350-0462bd0184edf230b92e6513eb4f6ca0804ec73f.zip |
SUPERNOVA: Implements animation
The original game's time was stored in 55ms ticks but we just run on
milliseconds. setAnimationTimer() sets the ticks the currrent room's
animation() function will not be called.
-rw-r--r-- | engines/supernova/state.cpp | 187 | ||||
-rw-r--r-- | engines/supernova/state.h | 5 | ||||
-rw-r--r-- | engines/supernova/supernova.cpp | 12 |
3 files changed, 129 insertions, 75 deletions
diff --git a/engines/supernova/state.cpp b/engines/supernova/state.cpp index 8ee7cd51b4..9066ac400a 100644 --- a/engines/supernova/state.cpp +++ b/engines/supernova/state.cpp @@ -118,11 +118,9 @@ void GuiElement::setHighlight(bool isHighlighted) { } -static const char *timeToString(int t) { - // TODO: Does ScummVM emulate PIT timings for DOS? - - static char s[9]; - strcpy(s," 0:00:00"); +static Common::String timeToString(int t) { + char s[9] = " 0:00:00"; + t /= 1000; s[7] = t % 10 + '0'; t /= 10; s[6] = t % 6 + '0'; @@ -134,9 +132,9 @@ static const char *timeToString(int t) { s[1] = t % 10 + '0'; t /= 10; if (t) - s[0] = t+48; + s[0] = t + '0'; - return(s); + return Common::String(s); } GameManager::GameManager(SupernovaEngine *vm) { @@ -197,8 +195,40 @@ GameManager::GameManager(SupernovaEngine *vm) { Object::setObjectNull(_inputObject[1]); _inputVerb = ACTION_WALK; _processInput = false; + _guiEnabled = true; + _animationEnabled = true; _mouseField = -1; _inventoryScroll = 0; + _timer1 = 0; + _animationTimer = 0; + + _state.time = 14200; + _state.timeSleep = 0; + _state.timeStarting = 50400000; + _state.timeAlarm = 25200000; + _state.timeAlarmSystem = _state.timeAlarm + _state.timeStarting; + _state.eventTime = 0xffffffff; + _state.shipEnergy = 2135; + _state.landingModuleEnergy = 923; + _state.greatF = 0; + _state.timeRobot = 0; + _state.money = 0; + _state.coins = 0; + _state.shoes = 0; + _state.nameSeen = 0; + _state.destination = 255; + _state.benOverlay = 0; + _state.language = 0; + _state.corridorSearch = false; + _state.alarmOn = false; + _state.terminalStripConnected = false; + _state.terminalStripWire = false; + _state.cableConnected = false; + _state.powerOff = false; + _state.cockpitSeen = false; + _state.airlockSeen = false; + _state.holdSeen = false; + _state.dream = false; initGui(); } @@ -218,7 +248,6 @@ void GameManager::initGui() { x += width + 2; } - // Inventory + Inventory Arrows for (int i = 0; i < ARRAYSIZE(_guiInventory); ++i) { int x = 136 * (i % 2); int y = 161 + 10 * (i / 2); @@ -226,12 +255,9 @@ void GameManager::initGui() { _guiInventory[i].setSize(x, y, x + 135, y + 9); _guiInventory[i].setColor(kColorWhite25, kColorDarkRed, kColorWhite35, kColorRed); } - - // Minimap - - // Status (?) } + void GameManager::processInput(Common::KeyState &state) { switch (state.keycode) { case Common::KEYCODE_F1: @@ -267,27 +293,28 @@ void GameManager::resetInputState() { Object::setObjectNull(_inputObject[1]); _inputVerb = ACTION_WALK; _processInput = false; + _mouseClicked = false; + _key = 0; + _mouseClickType = Common::EVENT_MOUSEMOVE; - processInput(Common::EVENT_MOUSEMOVE, _mouseX, _mouseY); + processInput(); } -void GameManager::processInput(Common::EventType eventType, int x, int y) { - _mouseClickType = eventType; - _mouseX = x; - _mouseY = y; - +void GameManager::processInput() { if (_mouseClickType == Common::EVENT_LBUTTONUP) { _vm->removeMessage(); if (((_mouseField >= 0) && (_mouseField < 256)) || ((_mouseField >= 512) && (_mouseField < 768))) { if (_inputVerb == ACTION_GIVE || _inputVerb == ACTION_USE) { - // TODO: There are cases where here is no second object needed - // for example, putting on the space suit - if (Object::isNullObject(_inputObject[0])) + if (Object::isNullObject(_inputObject[0])) { _inputObject[0] = _currentInputObject; - else + if (!_inputObject[0]->hasProperty(COMBINABLE)) + _processInput = true; + } else { _inputObject[1] = _currentInputObject; + _processInput = true; + } } else { _inputObject[0] = _currentInputObject; if (!Object::isNullObject(_currentInputObject)) @@ -296,12 +323,11 @@ void GameManager::processInput(Common::EventType eventType, int x, int y) { } else if (_mouseField >= 256 && _mouseField < 512) { resetInputState(); _inputVerb = static_cast<Action>(_mouseField - 256); - drawStatus(); } else if (_mouseField == 768) { - if (_inventoryScroll >= 0) - --_inventoryScroll; + if (_inventoryScroll >= 2) + _inventoryScroll -= 2; } else if (_mouseField == 769) { - ++_inventoryScroll; + _inventoryScroll += 2; } } else if (_mouseClickType == Common::EVENT_RBUTTONUP) { _vm->removeMessage(); @@ -334,40 +360,40 @@ void GameManager::processInput(Common::EventType eventType, int x, int y) { int click = -1; /* command row? */ - if ((y >= _guiCommandButton[0].top) && (y <= _guiCommandButton[0].bottom)) { + if ((_mouseY >= _guiCommandButton[0].top) && (_mouseY <= _guiCommandButton[0].bottom)) { field = 9; - while (x < _guiCommandButton[field].left - 1) + while (_mouseX < _guiCommandButton[field].left - 1) field--; field += 256; } /* exit box? */ - else if ((x >= 283) && (x <= 317) && (y >= 163) && (y <= 197)) { - field = _exitList[(x - 283) / 7 + 5 * ((y - 163) / 7)]; + else if ((_mouseX >= 283) && (_mouseX <= 317) && (_mouseY >= 163) && (_mouseY <= 197)) { + field = _exitList[(_mouseX - 283) / 7 + 5 * ((_mouseY - 163) / 7)]; } /* inventory box */ - else if ((y >= 161) && (x <= 270)) { - field = (x + 1) / 136 + ((y - 161) / 10) * 2; + else if ((_mouseY >= 161) && (_mouseX <= 270)) { + field = (_mouseX + 1) / 136 + ((_mouseY - 161) / 10) * 2; if (field + _inventoryScroll < _inventory.getSize()) field += 512; else field = -1; } /* inventory arrows */ - else if ((y >= 161) && (x >= 271) && (x < 279)) { - if (y > 180) + else if ((_mouseY >= 161) && (_mouseX >= 271) && (_mouseX < 279)) { + if (_mouseY > 180) field = 769; else field = 768; } /* normal item */ else { - for (int i = 0; (_currentRoom->getObject(i)->_name[0] != '\0') && (field == -1); i++) { + for (int i = 0; (_currentRoom->getObject(i)->_name[0] != '\0') && (field == -1) && i < kMaxObject; i++) { click = _currentRoom->getObject(i)->_click; if (click != 255) { MSNImageDecoder::ClickField *clickField = _vm->_currentImage->_clickField; do { - if ((x >= clickField[click].x1) && (x <= clickField[click].x2) && - (y >= clickField[click].y1) && (y <= clickField[click].y2)) + if ((_mouseX >= clickField[click].x1) && (_mouseX <= clickField[click].x2) && + (_mouseY >= clickField[click].y1) && (_mouseY <= clickField[click].y2)) field = i; click = clickField[click].next; @@ -402,7 +428,7 @@ void GameManager::processInput(Common::EventType eventType, int x, int y) { } } - drawStatus(); +// drawStatus(); } } @@ -515,6 +541,7 @@ void GameManager::mouseInput() { void GameManager::mouseInput2() { // STUB + // If animation off and timer expired, skip room animation } void GameManager::mouseInput3() { @@ -564,6 +591,12 @@ void GameManager::setAnimationTimer(int ticks) { _animationTimer = g_system->getMillis() + (55 * ticks); } +void GameManager::handleTime() { + _state.time = g_system->getMillis(); + if (_animationTimer <= _state.time) + _animationTimer = 0; +} + void GameManager::screenShake() { // STUB } @@ -605,11 +638,11 @@ void GameManager::drawMapExits() { } void GameManager::animationOff() { - // STUB + _animationEnabled = false; } void GameManager::animationOn() { - // STUB + _animationEnabled = true; } void GameManager::edit(char *text, int x, int y, int length) { @@ -622,8 +655,8 @@ void GameManager::loadOverlayStart() { void GameManager::drawStatus() { int index = static_cast<int>(_inputVerb); - _vm->renderBox(0, 140, 320, 9, HGR_BEF_ANZ); - _vm->renderText(guiStatusCommand_DE[index], 1, 141, COL_BEF_ANZ); + _vm->renderBox(0, 140, 320, 9, kColorWhite25); + _vm->renderText(guiStatusCommand_DE[index], 1, 141, kColorDarkGreen); if (Object::isNullObject(_inputObject[0])) { _vm->renderText(_currentInputObject->_name); @@ -642,7 +675,7 @@ void GameManager::drawStatus() { } void GameManager::openLocker(const Room *room, Object *obj, Object *lock, int section) { - _vm->renderImage(room->getFileNumber(), section); + drawImage(section); obj->setProperty(OPENED); lock->_click = 255; int i = obj->_click; @@ -651,7 +684,16 @@ void GameManager::openLocker(const Room *room, Object *obj, Object *lock, int se } void GameManager::closeLocker(const Room *room, Object *obj, Object *lock, int section) { - // STUB + if (!obj->hasProperty(OPENED)) { + _vm->renderMessage("Das ist schon geschlossen."); + } else { + drawImage(invertSection(section)); + obj->disableProperty(OPENED); + lock->_click = lock->_click2; + int i = obj->_click; + obj->_click = obj->_click2; + obj->_click2 = i; + } } int GameManager::invertSection(int section) { @@ -741,8 +783,8 @@ bool GameManager::genericInteract(Action verb, Object &obj1, Object &obj2) { "Es ist eine Uhr mit extra|lautem Wecker. " "Sie hat einen|Knopf zum Verstellen der Alarmzeit.|" "Uhrzeit: %s Alarmzeit: %s", - timeToString(_vm->getDOSTicks() - _state.timeStarting), - timeToString(_state.timeAlarm)).c_str()); + timeToString(_state.time + _state.timeStarting).c_str(), + timeToString(_state.timeAlarm).c_str()).c_str()); } else if ((verb == ACTION_PRESS) && (obj1._id == WATCH)) { char *min; int hours, minutes; @@ -930,26 +972,7 @@ bool GameManager::genericInteract(Action verb, Object &obj1, Object &obj2) { return true; } -void GameManager::executeRoom() { - if (!_vm->_messageDisplayed) - _vm->renderRoom(*_currentRoom); - drawMapExits(); - drawInventory(); - drawStatus(); - drawCommandBox(); - - animationOn(); - roomBrightness(); - if (_vm->_brightness == 0) - _vm->paletteFadeIn(); - else - _vm->paletteBrightness(); - if (!_currentRoom->hasSeen()) - _currentRoom->onEntrance(); - - if (_vm->_messageDisplayed || !_processInput) - return; - +void GameManager::handleInput() { bool validCommand = genericInteract(_inputVerb, *_inputObject[0], *_inputObject[1]); if (!validCommand) validCommand = _currentRoom->interact(_inputVerb, *_inputObject[0], *_inputObject[1]); @@ -1039,17 +1062,35 @@ void GameManager::executeRoom() { // This is not possible. _vm->renderMessage("Das geht nicht."); } + } +} - if (_newOverlay) { - loadOverlayStart(); - _newOverlay = false; - } - if (_newRoom) { - _newRoom = false; +void GameManager::executeRoom() { + if (_guiEnabled) { + if (!_vm->_messageDisplayed) { + g_system->fillScreen(kColorBlack); + _vm->renderRoom(*_currentRoom); } + drawMapExits(); + drawInventory(); + drawStatus(); + drawCommandBox(); + } + roomBrightness(); + if (_vm->_brightness == 0) + _vm->paletteFadeIn(); + else + _vm->paletteBrightness(); + if (!_currentRoom->hasSeen()) + _currentRoom->onEntrance(); + + if (!_guiEnabled || !_processInput || _vm->_messageDisplayed) { + + } else { + handleInput(); + resetInputState(); } - resetInputState(); } } diff --git a/engines/supernova/state.h b/engines/supernova/state.h index 79b8a8e70d..ced1de6533 100644 --- a/engines/supernova/state.h +++ b/engines/supernova/state.h @@ -99,7 +99,7 @@ public: GameManager(SupernovaEngine *vm); void processInput(Common::KeyState &state); - void processInput(Common::EventType eventType, int x, int y); + void processInput(); void executeRoom(); SupernovaEngine *_vm; @@ -116,6 +116,7 @@ public: int _status; bool _processInput; bool _guiEnabled; + bool _animationEnabled; Action _inputVerb; Object *_currentInputObject; Object *_inputObject[2]; @@ -169,6 +170,8 @@ public: void drawImage(int section); void changeRoom(RoomID id); void resetInputState(); + void handleInput(); + void handleTime(); void setAnimationTimer(int ticks); }; diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index b5e674d46a..e1293c452d 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -167,6 +167,11 @@ int SupernovaEngine::getDOSTicks() { } void SupernovaEngine::updateEvents() { + _gm->handleTime(); + if (_gm->_animationEnabled && _gm->_animationTimer == 0) + _gm->_currentRoom->animation(); + + _gm->_mouseClicked = false; while (g_system->getEventManager()->pollEvent(_event)) { switch (_event.type) { case Common::EVENT_QUIT: @@ -193,8 +198,13 @@ void SupernovaEngine::updateEvents() { // fallthrough case Common::EVENT_RBUTTONUP: // fallthrough + _gm->_mouseClicked = true; case Common::EVENT_MOUSEMOVE: - _gm->processInput(_event.type, _event.mouse.x, _event.mouse.y); + _gm->_mouseClickType = _event.type; + _gm->_mouseX = _event.mouse.x; + _gm->_mouseY = _event.mouse.y; + if (_gm->_guiEnabled) + _gm->processInput(); break; default: |