diff options
author | Jaromir Wysoglad | 2019-05-30 09:56:43 +0200 |
---|---|---|
committer | Thierry Crozat | 2019-07-28 15:09:14 +0100 |
commit | dd5f1778ff20d7624ed3490ceeea1c8aa9e9fde8 (patch) | |
tree | c619df1a6469dab4c977c3ddfbce0d2519a24720 | |
parent | f82e55a7f14ae25d24fb420eb0c189292ec8d1ea (diff) | |
download | scummvm-rg350-dd5f1778ff20d7624ed3490ceeea1c8aa9e9fde8.tar.gz scummvm-rg350-dd5f1778ff20d7624ed3490ceeea1c8aa9e9fde8.tar.bz2 scummvm-rg350-dd5f1778ff20d7624ed3490ceeea1c8aa9e9fde8.zip |
SUPERNOVA2: Render GUI
-rw-r--r-- | engines/supernova2/ms2_def.h | 2 | ||||
-rw-r--r-- | engines/supernova2/screen.cpp | 8 | ||||
-rw-r--r-- | engines/supernova2/screen.h | 6 | ||||
-rw-r--r-- | engines/supernova2/state.cpp | 334 | ||||
-rw-r--r-- | engines/supernova2/state.h | 14 | ||||
-rw-r--r-- | engines/supernova2/supernova2.cpp | 41 | ||||
-rw-r--r-- | engines/supernova2/supernova2.h | 2 |
7 files changed, 357 insertions, 50 deletions
diff --git a/engines/supernova2/ms2_def.h b/engines/supernova2/ms2_def.h index e686500e1e..987fc5f7c7 100644 --- a/engines/supernova2/ms2_def.h +++ b/engines/supernova2/ms2_def.h @@ -130,7 +130,7 @@ kStringCommandGo, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kS kStringCommandPress, kStringCommandPull, kStringCommandUse, kStringCommandTalk, kStringCommandGive, kString10, kStringStatusCommandGo, kStringStatusCommandLook, kStringStatusCommandTake, kStringStatusCommandOpen, kStringStatusCommandClose, kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, -kStringStatusCommandGive, kString21, kString22, kString23, kString24, +kStringStatusCommandGive, kPhrasalVerbParticleGiveTo, kPhrasalVerbParticleUseWith, kString23, kString24, kString25, kString26, kString27, kStringTextSpeed, kString29, kString30, kString31, kString32, kString33, kString34, kString35, kString36, kString37, kString38, kString39, diff --git a/engines/supernova2/screen.cpp b/engines/supernova2/screen.cpp index af9b2b94f9..6237a6ec4c 100644 --- a/engines/supernova2/screen.cpp +++ b/engines/supernova2/screen.cpp @@ -271,10 +271,10 @@ void Screen::renderText(const Common::String &text) { renderText(text.c_str()); } -/*void Screen::renderText(const GuiElement &guiElement) { +void Screen::renderText(const GuiElement &guiElement) { renderText(guiElement.getText(), guiElement.getTextPos().x, guiElement.getTextPos().y, guiElement.getTextColor()); -}*/ +} void Screen::renderText(const uint16 character, int x, int y, byte color) { char text[2]; @@ -545,10 +545,10 @@ void Screen::renderBox(int x, int y, int width, int height, byte color) { _vm->_system->unlockScreen(); } -/*void Screen::renderBox(const GuiElement &guiElement) { +void Screen::renderBox(const GuiElement &guiElement) { renderBox(guiElement.left, guiElement.top, guiElement.width(), guiElement.height(), guiElement.getBackgroundColor()); -}*/ +} void Screen::initPalette() { g_system->getPaletteManager()->setPalette(initVGAPalette, 0, 256); diff --git a/engines/supernova2/screen.h b/engines/supernova2/screen.h index dbfeb42634..252e4df9bd 100644 --- a/engines/supernova2/screen.h +++ b/engines/supernova2/screen.h @@ -35,7 +35,7 @@ namespace Supernova2 { class Supernova2Engine; class GameManager; class ResourceManager; -//class GuiElement; +class GuiElement; class Room; class MS2Image; class Screen; @@ -165,9 +165,9 @@ public: void renderText(const char *text, int x, int y, byte color); void renderText(const Common::String &text, int x, int y, byte color); void renderText(StringId stringId, int x, int y, byte color); - //void renderText(const GuiElement &guiElement); + void renderText(const GuiElement &guiElement); void renderBox(int x, int y, int width, int height, byte color); - //void renderBox(const GuiElement &guiElement); + void renderBox(const GuiElement &guiElement); void setColor63(byte value); Common::Point getTextCursorPos(); void setTextCursorPos(int x, int y); diff --git a/engines/supernova2/state.cpp b/engines/supernova2/state.cpp index 33a3d95351..49fba402a6 100644 --- a/engines/supernova2/state.cpp +++ b/engines/supernova2/state.cpp @@ -164,6 +164,7 @@ void GameManager::initState() { _currentInputObject = &_nullObject; _inputObject[0] = &_nullObject; _inputObject[1] = &_nullObject; + _inputVerb = ACTION_WALK; _processInput = false; _guiEnabled = true; _animationEnabled = true; @@ -171,6 +172,7 @@ void GameManager::initState() { _keyPressed = false; _mouseX = -1; _mouseY = -1; + _mouseField = -1; _inventoryScroll = 0; _timerPaused = 0; _timePaused = false; @@ -251,8 +253,6 @@ void GameManager::updateEvents() { case Common::EVENT_LBUTTONUP: // fallthrough case Common::EVENT_RBUTTONUP: - if (_currentRoom->getId() != INTRO) - return; _mouseClicked = true; // fallthrough case Common::EVENT_MOUSEMOVE: @@ -260,7 +260,7 @@ void GameManager::updateEvents() { _mouseX = event.mouse.x; _mouseY = event.mouse.y; if (_guiEnabled) - //processInput(); + processInput(); break; default: break; @@ -301,6 +301,305 @@ void GameManager::processInput(Common::KeyState &state) { } } +void GameManager::resetInputState() { + setObjectNull(_inputObject[0]); + setObjectNull(_inputObject[1]); + _inputVerb = ACTION_WALK; + _processInput = false; + _mouseClicked = false; + _keyPressed = false; + _key.reset(); + _mouseClickType = Common::EVENT_MOUSEMOVE; + + processInput(); +} + + +void GameManager::processInput() { + enum { + onNone, + onObject, + onCmdButton, + onInventory, + onInventoryArrowUp, + onInventoryArrowDown + } mouseLocation; + + if (_mouseField >= 0 && _mouseField < 256) + mouseLocation = onObject; + else if (_mouseField >= 256 && _mouseField < 512) + mouseLocation = onCmdButton; + else if (_mouseField >= 512 && _mouseField < 768) + mouseLocation = onInventory; + else if (_mouseField == 768) + mouseLocation = onInventoryArrowUp; + else if (_mouseField == 769) + mouseLocation = onInventoryArrowDown; + else + mouseLocation = onNone; + + if (_mouseClickType == Common::EVENT_LBUTTONUP) { + if (_vm->_screen->isMessageShown()) { + // Hide the message and consume the event + _vm->removeMessage(); + if (mouseLocation != onCmdButton) + return; + } + + switch(mouseLocation) { + case onObject: + case onInventory: + // Fallthrough + if (_inputVerb == ACTION_GIVE || _inputVerb == ACTION_USE) { + if (isNullObject(_inputObject[0])) { + _inputObject[0] = _currentInputObject; + if (!_inputObject[0]->hasProperty(COMBINABLE)) + _processInput = true; + } else { + _inputObject[1] = _currentInputObject; + _processInput = true; + } + } else { + _inputObject[0] = _currentInputObject; + if (!isNullObject(_currentInputObject)) + _processInput = true; + } + break; + case onCmdButton: + resetInputState(); + _inputVerb = static_cast<Action>(_mouseField - 256); + break; + case onInventoryArrowUp: + if (_inventoryScroll >= 2) + _inventoryScroll -= 2; + break; + case onInventoryArrowDown: + if (_inventoryScroll < _inventory.getSize() - ARRAYSIZE(_guiInventory)) + _inventoryScroll += 2; + break; + case onNone: + break; + } + + } else if (_mouseClickType == Common::EVENT_RBUTTONUP) { + if (_vm->_screen->isMessageShown()) { + // Hide the message and consume the event + _vm->removeMessage(); + return; + } + + if (isNullObject(_currentInputObject)) + return; + + if (mouseLocation == onObject || mouseLocation == onInventory) { + _inputObject[0] = _currentInputObject; + ObjectTypes type = _inputObject[0]->_type; + if (type & OPENABLE) + _inputVerb = (type & OPENED) ? ACTION_CLOSE : ACTION_OPEN; + else if (type & PRESS) + _inputVerb = ACTION_PRESS; + else if (type & TALK) + _inputVerb = ACTION_TALK; + else + _inputVerb = ACTION_LOOK; + + _processInput = true; + } + + } else if (_mouseClickType == Common::EVENT_MOUSEMOVE) { + int field = -1; + int click = -1; + + if ((_mouseY >= _guiCommandButton[0].top) && (_mouseY <= _guiCommandButton[0].bottom)) { + /* command row */ + field = 9; + while (_mouseX < _guiCommandButton[field].left - 1) + field--; + field += 256; + } else if ((_mouseX >= 283) && (_mouseX <= 317) && (_mouseY >= 163) && (_mouseY <= 197)) { + /* exit box */ + field = _exitList[(_mouseX - 283) / 7 + 5 * ((_mouseY - 163) / 7)]; + } else if ((_mouseY >= 161) && (_mouseX <= 270)) { + /* inventory box */ + field = (_mouseX + 1) / 136 + ((_mouseY - 161) / 10) * 2; + if (field + _inventoryScroll < _inventory.getSize()) + field += 512; + else + field = -1; + } else if ((_mouseY >= 161) && (_mouseX >= 271) && (_mouseX < 279)) { + /* inventory arrows */ + field = (_mouseY > 180) ? 769 : 768; + } else { + /* normal item */ + for (int i = 0; (_currentRoom->getObject(i)->_id != INVALIDOBJECT) && + (field == -1) && i < kMaxObject; i++) { + click = _currentRoom->getObject(i)->_click; + const MS2Image *image = _vm->_screen->getCurrentImage(); + if (click != 255 && image) { + const MS2Image::ClickField *clickField = image->_clickField; + do { + if ((_mouseX >= clickField[click].x1) && (_mouseX <= clickField[click].x2) && + (_mouseY >= clickField[click].y1) && (_mouseY <= clickField[click].y2)) + field = i; + + click = clickField[click].next; + } while ((click != 0) && (field == -1)); + } + } + } + + if (_mouseField != field) { + switch (mouseLocation) { + case onInventoryArrowUp: + case onInventoryArrowDown: + // Fallthrough + _guiInventoryArrow[_mouseField - 768].setHighlight(false); + break; + case onInventory: + _guiInventory[_mouseField - 512].setHighlight(false); + break; + case onCmdButton: + _guiCommandButton[_mouseField - 256].setHighlight(false); + break; + case onObject: + case onNone: + // Fallthrough + break; + } + + setObjectNull(_currentInputObject); + + _mouseField = field; + if (_mouseField >= 0 && _mouseField < 256) + mouseLocation = onObject; + else if (_mouseField >= 256 && _mouseField < 512) + mouseLocation = onCmdButton; + else if (_mouseField >= 512 && _mouseField < 768) + mouseLocation = onInventory; + else if (_mouseField == 768) + mouseLocation = onInventoryArrowUp; + else if (_mouseField == 769) + mouseLocation = onInventoryArrowDown; + else + mouseLocation = onNone; + + switch (mouseLocation) { + case onInventoryArrowUp: + case onInventoryArrowDown: + // Fallthrough + _guiInventoryArrow[_mouseField - 768].setHighlight(true); + break; + case onInventory: + _guiInventory[_mouseField - 512].setHighlight(true); + _currentInputObject = _inventory.get(_mouseField - 512 + _inventoryScroll); + break; + case onCmdButton: + _guiCommandButton[_mouseField - 256].setHighlight(true); + break; + case onObject: + _currentInputObject = _currentRoom->getObject(_mouseField); + break; + case onNone: + break; + } + } + } +} + +void GameManager::setObjectNull(Object *&obj) { + obj = &_nullObject; +} + +bool GameManager::isNullObject(Object *obj) { + return obj == &_nullObject; +} + +void GameManager::showMenu() { + _vm->renderBox(0, 138, 320, 62, 0); + _vm->renderBox(0, 140, 320, 9, kColorWhite25); + drawCommandBox(); + _vm->renderBox(281, 161, 39, 39, kColorWhite25); + drawInventory(); +} + +void GameManager::drawStatus() { + int index = static_cast<int>(_inputVerb); + _vm->renderBox(0, 140, 320, 9, kColorWhite25); + _vm->renderText(_vm->getGameString(guiStatusCommands[index]), 1, 141, kColorDarkGreen); + + if (isNullObject(_inputObject[0])) + _vm->renderText(_currentInputObject->_name); + else { + _vm->renderText(_inputObject[0]->_name); + if (_inputVerb == ACTION_GIVE) + _vm->renderText(kPhrasalVerbParticleGiveTo); + else if (_inputVerb == ACTION_USE) + _vm->renderText(kPhrasalVerbParticleUseWith); + + _vm->renderText(_currentInputObject->_name); + } +} + +void GameManager::drawCommandBox() { + for (int i = 0; i < ARRAYSIZE(_guiCommandButton); ++i) { + _vm->renderBox(_guiCommandButton[i]); + int space = (_guiCommandButton[i].width() - Screen::textWidth(_guiCommandButton[i].getText())) / 2; + _vm->renderText(_guiCommandButton[i].getText(), + _guiCommandButton[i].getTextPos().x + space, + _guiCommandButton[i].getTextPos().y, + _guiCommandButton[i].getTextColor()); + } +} + +void GameManager::drawInventory() { + for (int i = 0; i < ARRAYSIZE(_guiInventory); ++i) { + _vm->renderBox(_guiInventory[i]); + _vm->renderText(_inventory.get(i + _inventoryScroll)->_name, + _guiInventory[i].getTextPos().x, + _guiInventory[i].getTextPos().y, + _guiInventory[i].getTextColor()); + } + + _vm->renderBox(_guiInventoryArrow[0]); + _vm->renderBox(_guiInventoryArrow[1]); + if (_inventory.getSize() > ARRAYSIZE(_guiInventory)) { + if (_inventoryScroll != 0) + _vm->renderText(_guiInventoryArrow[0]); + if (_inventoryScroll + ARRAYSIZE(_guiInventory) < _inventory.getSize()) + _vm->renderText(_guiInventoryArrow[1]); + } +} + +uint16 GameManager::getKeyInput(bool blockForPrintChar) { + while (!_vm->shouldQuit()) { + updateEvents(); + if (_keyPressed) { + if (blockForPrintChar) { + if (Common::isPrint(_key.keycode) || + _key.keycode == Common::KEYCODE_BACKSPACE || + _key.keycode == Common::KEYCODE_DELETE || + _key.keycode == Common::KEYCODE_RETURN || + _key.keycode == Common::KEYCODE_SPACE || + _key.keycode == Common::KEYCODE_ESCAPE || + _key.keycode == Common::KEYCODE_UP || + _key.keycode == Common::KEYCODE_DOWN || + _key.keycode == Common::KEYCODE_LEFT || + _key.keycode == Common::KEYCODE_RIGHT) { + if (_key.flags & Common::KBD_SHIFT) + return toupper(_key.ascii); + else + return tolower(_key.ascii); + } + } else { + return _key.ascii; + } + } + g_system->updateScreen(); + g_system->delayMillis(_vm->_delay); + } + return 0; +} + void GameManager::getInput() { while (!_vm->shouldQuit()) { updateEvents(); @@ -311,6 +610,11 @@ void GameManager::getInput() { } } +void GameManager::changeRoom(RoomId id) { + _currentRoom = _rooms[id]; + _newRoom = true; +} + void GameManager::wait(int ticks) { uint32 end = g_system->getMillis() + ticksToMsec(ticks); do { @@ -346,24 +650,6 @@ bool GameManager::waitOnInput(int ticks, Common::KeyCode &keycode) { return false; } -void GameManager::changeRoom(RoomId id) { - _currentRoom = _rooms[id]; - _newRoom = true; -} - -void GameManager::resetInputState() { -// setObjectNull(_inputObject[0]); -// setObjectNull(_inputObject[1]); -// _inputVerb = ACTION_WALK; - _processInput = false; - _mouseClicked = false; - _keyPressed = false; - _key.reset(); - _mouseClickType = Common::EVENT_MOUSEMOVE; - - //processInput(); -} - void GameManager::executeRoom() { if (_processInput && !_vm->_screen->isMessageShown() && _guiEnabled) { // handleInput(); @@ -386,9 +672,9 @@ void GameManager::executeRoom() { _vm->renderRoom(*_currentRoom); } // drawMapExits(); -// drawInventory(); -// drawStatus(); -// drawCommandBox(); + drawInventory(); + drawStatus(); + drawCommandBox(); } //if (_vm->_screen->getViewportBrightness() == 0) diff --git a/engines/supernova2/state.h b/engines/supernova2/state.h index 7ed65cc3a3..b32d2d24c0 100644 --- a/engines/supernova2/state.h +++ b/engines/supernova2/state.h @@ -105,7 +105,7 @@ public: void updateEvents(); void processInput(Common::KeyState &state); - //void processInput(); + void processInput(); void executeRoom(); static StringId guiCommands[]; @@ -117,6 +117,7 @@ public: bool _keyPressed; int _mouseX; int _mouseY; + int _mouseField; Room *_currentRoom; bool _newRoom; Room *_rooms[NUMROOMS]; @@ -125,6 +126,7 @@ public: bool _processInput; bool _guiEnabled; bool _animationEnabled; + Action _inputVerb; Object _nullObject; Object *_currentInputObject; Object *_inputObject[2]; @@ -143,15 +145,23 @@ public: byte _rows[6]; byte _rowsStart[6]; + void setObjectNull(Object *&obj); + bool isNullObject(Object *obj); + void initState(); void initRooms(); void destroyRooms(); void initGui(); + uint16 getKeyInput(bool blockForPrintChar = false); void getInput(); - void changeRoom(RoomId id); void wait(int ticks); void waitOnInput(int ticks); bool waitOnInput(int ticks, Common::KeyCode &keycode); + void showMenu(); + void drawStatus(); + void drawCommandBox(); + void drawInventory(); + void changeRoom(RoomId id); void resetInputState(); private: diff --git a/engines/supernova2/supernova2.cpp b/engines/supernova2/supernova2.cpp index f2a21a6d90..d617ced94e 100644 --- a/engines/supernova2/supernova2.cpp +++ b/engines/supernova2/supernova2.cpp @@ -255,6 +255,27 @@ void Supernova2Engine::renderText(StringId stringId) { _screen->renderText(stringId); } +void Supernova2Engine::renderText(const GuiElement &guiElement) { + _screen->renderText(guiElement); +} + +void Supernova2Engine::renderText(const uint16 character, int x, int y, byte color) { + _screen->renderText(character, x, y, color); +} + +void Supernova2Engine::renderText(const char *text, int x, int y, byte color) { + _screen->renderText(text, x, y, color); +} + +void Supernova2Engine::renderText(const Common::String &text, int x, int y, byte color) { + _screen->renderText(text, x, y, color); +} + +void Supernova2Engine::renderText(StringId stringId, int x, int y, byte color) { + _screen->renderText(stringId, x, y, color); +} + + void Supernova2Engine::paletteBrightness() { _screen->paletteBrightness(); } @@ -385,24 +406,12 @@ void Supernova2Engine::setColor63(byte value) { return quit; }*/ -void Supernova2Engine::renderText(const uint16 character, int x, int y, byte color) { - _screen->renderText(character, x, y, color); -} - -void Supernova2Engine::renderText(const char *text, int x, int y, byte color) { - _screen->renderText(text, x, y, color); -} - -void Supernova2Engine::renderText(const Common::String &text, int x, int y, byte color) { - _screen->renderText(text, x, y, color); -} - -void Supernova2Engine::renderText(StringId stringId, int x, int y, byte color) { - _screen->renderText(stringId, x, y, color); -} - void Supernova2Engine::renderBox(int x, int y, int width, int height, byte color) { _screen->renderBox(x, y, width, height, color); } +void Supernova2Engine::renderBox(const GuiElement &guiElement) { + _screen->renderBox(guiElement); +} + } diff --git a/engines/supernova2/supernova2.h b/engines/supernova2/supernova2.h index e5798d921f..26673920fd 100644 --- a/engines/supernova2/supernova2.h +++ b/engines/supernova2/supernova2.h @@ -110,7 +110,9 @@ public: void renderText(const char *text, int x, int y, byte color); void renderText(const Common::String &text, int x, int y, byte color); void renderText(StringId stringId, int x, int y, byte color); + void renderText(const GuiElement &guiElement); void renderBox(int x, int y, int width, int height, byte color); + void renderBox(const GuiElement &guiElement); void setColor63(byte value); }; |