diff options
author | Andrew Kurushin | 2005-01-13 22:42:49 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-01-13 22:42:49 +0000 |
commit | 326dd0c2553db220283cda1403c77bc0870f7451 (patch) | |
tree | ed32eec8ad09f04ae4b820e1692b53a58983f1b4 /saga | |
parent | e97c689f8bcbc925c02196b0596e9749a2533e88 (diff) | |
download | scummvm-rg350-326dd0c2553db220283cda1403c77bc0870f7451.tar.gz scummvm-rg350-326dd0c2553db220283cda1403c77bc0870f7451.tar.bz2 scummvm-rg350-326dd0c2553db220283cda1403c77bc0870f7451.zip |
- introduced SagaEngine::getTextString (for i18n it should route to corresponding string array)
- first step in verb implementation: proper button draw, keyboard respond 'w','l' &etc
- added comments and some fields to GameDisplayInfo
svn-id: r16554
Diffstat (limited to 'saga')
-rw-r--r-- | saga/game.cpp | 72 | ||||
-rw-r--r-- | saga/input.cpp | 14 | ||||
-rw-r--r-- | saga/interface.cpp | 481 | ||||
-rw-r--r-- | saga/interface.h | 102 | ||||
-rw-r--r-- | saga/saga.cpp | 47 | ||||
-rw-r--r-- | saga/saga.h | 81 | ||||
-rw-r--r-- | saga/script.cpp | 25 | ||||
-rw-r--r-- | saga/script.h | 12 |
8 files changed, 466 insertions, 368 deletions
diff --git a/saga/game.cpp b/saga/game.cpp index c85b1f8f01..5eb2cc5a0f 100644 --- a/saga/game.cpp +++ b/saga/game.cpp @@ -41,31 +41,46 @@ namespace Saga { static int detectGame(const FSList &fslist, bool mode = false); // ITE section +static PanelButton ITE_MainPanelButtons[] = { + {kPanelButtonVerb, 52, 4, 57, 10, kVerbWalkTo, 'w', 0, 1}, + {kPanelButtonVerb, 52, 15, 57, 10, kVerbLookAt, 'l', 2, 3}, + {kPanelButtonVerb, 52, 26, 57, 10, kVerbPickUp, 'p', 4, 5}, + {kPanelButtonVerb, 52, 37, 57, 10, kVerbTalkTo, 't', 0, 1}, + {kPanelButtonVerb, 110, 4, 56, 10, kVerbOpen, 'o', 6, 7}, + {kPanelButtonVerb, 110, 15, 56, 10, kVerbClose, 'c', 8, 9}, + {kPanelButtonVerb, 110, 26, 56, 10, kVerbUse, 'u', 10, 11}, + {kPanelButtonVerb, 110, 37, 56, 10, kVerbGive, 'g', 12, 13}, + {kPanelButtonArrow, 306, 6, 8, 5, 0, 'U', 0, 0}, + {kPanelButtonArrow, 306, 41, 8, 5, 1, 'D', 0, 0} +}; + static GameDisplayInfo ITE_DisplayInfo = { - 320, 200, + 320, 200, // logical width&height - 35, - 137, - - 137, - 320, - 12, - 2, - 186, - 15, - - 147, - 15, - 96, + 35, // scene path y offset + 137, // scene height + + 137, // status y + 320, // status width + 12, // status height + 2, // status text y offset + 186, // status text color + 15, // status BG color + + 147, // verb text color + 15, // verb text shadow color + 96, // verb text active color - 5, 4, - 274, 4, - - 181, 155, - 2, 4, - 29, 20, - 1, 0, - 3, 1 + 5, 4, // left portrait x, y offset + 274, 4, // right portrait x, y offset + + 181, 155, // inventory x, y + 2, 4, // inventory rows, columns + 29, 20, // inventory icon width, height + 1, 0, // inventory icon x, y offset + 3, 1, // inventory x, y icon spacing + ARRAYSIZE(ITE_MainPanelButtons), + ITE_MainPanelButtons }; static GameResourceDescription ITE_Resources = { @@ -177,6 +192,10 @@ static GameSoundInfo ITECD_GameSound = { // IHNM section +static PanelButton IHNM_MainPanelButtons[] = { + {kPanelButtonVerb, 0, 0, 0, 0, kVerbWalkTo, ' ', 0, 0}, //TODO +}; + static GameDisplayInfo IHNM_DisplayInfo = { 640, 480, @@ -201,7 +220,9 @@ static GameDisplayInfo IHNM_DisplayInfo = { 0, 0, 0, 0, 0, 0, - 0, 0 + 0, 0, + ARRAYSIZE(IHNM_MainPanelButtons), + IHNM_MainPanelButtons }; static GameResourceDescription IHNM_Resources = { @@ -688,11 +709,6 @@ int SagaEngine::loadLanguage(void) { test_file.close(); - if (_vm->_interface->registerLang() != SUCCESS) { - warning("Error registering interface language cvars"); - return FAILURE; - } - if (_vm->_scene->ITEIntroRegisterLang() != SUCCESS) { warning("Error registering intro sequence language cvars"); return FAILURE; diff --git a/saga/input.cpp b/saga/input.cpp index 5c032da81a..cfc3d48363 100644 --- a/saga/input.cpp +++ b/saga/input.cpp @@ -82,20 +82,8 @@ int SagaEngine::processInput() { case 'p': _render->toggleFlag(RF_RENDERPAUSE); break; - case 27: // Esc - // Skip to next scene skip target - switch (_interface->getMode()) { - case kPanelNull: - if (_scene->isInDemo()) - _scene->skipScene(); - else - _actor->abortAllSpeeches(); - break; - default: - break; - } - break; default: + _interface->processKeyCode(event.kbd.keycode); break; } break; diff --git a/saga/interface.cpp b/saga/interface.cpp index d24dad7744..d1ba561f40 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -39,67 +39,29 @@ namespace Saga { -static VERB_DATA I_VerbData[] = { - {I_VERB_WALKTO, "verb_walkto", "Walk to", kVerbWalkTo}, - {I_VERB_LOOKAT, "verb_lookat", "Look at", kVerbLookAt}, - {I_VERB_PICKUP, "verb_pickup", "Pick up", kVerbPickup}, - {I_VERB_TALKTO, "verb_talkto", "Talk to", kVerbSpeakTo}, - {I_VERB_OPEN, "verb_open", "Open", kVerbOpen}, - {I_VERB_CLOSE, "verb_close", "Close", kVerbClose}, - {I_VERB_USE, "verb_use", "Use", kVerbUse}, - {I_VERB_GIVE, "verb_give", "Give", kVerbGive} +static int verbTypeToTextStringsIdLUT[kVerbTypesMax] = { + -1, + kTextPickUp, + kTextLookAt, + kTextWalkTo, + kTextTalkTo, + kTextOpen, + kTextClose, + kTextGive, + kTextUse, + -1, + -1, + -1, + -1, + -1, + -1 }; -static InterfaceButton ITEMainPanel[] = { - {5, 4, 46, 47, "Portrait", 0, 0, BUTTON_NONE, 0}, //TODO: remove? - // "Walk To" and "Talk To" share button sprites - {52, 4, 109, 14, "Walk To", 1, 2, BUTTON_VERB, I_VERB_WALKTO}, - {52, 15, 109, 25, "Look At", 3, 4, BUTTON_VERB, I_VERB_LOOKAT}, - {52, 26, 109, 36, "Pick Up", 5, 6, BUTTON_VERB, I_VERB_PICKUP}, - {52, 37, 109, 47, "Talk To", 1, 2, BUTTON_VERB, I_VERB_TALKTO}, - {110, 4, 166, 14, "Open", 7, 8, BUTTON_VERB, I_VERB_OPEN}, - {110, 15, 166, 25, "Close", 9, 10, BUTTON_VERB, I_VERB_CLOSE}, - {110, 26, 166, 36, "Use", 11, 12, BUTTON_VERB, I_VERB_USE}, - {110, 37, 166, 47, "Give", 13, 14, BUTTON_VERB, I_VERB_GIVE}, - - {181, 6, 206, 24, "Inv1", 0, 0, BUTTON_NONE, 0}, - {213, 6, 240, 24, "Inv2", 0, 0, BUTTON_NONE, 0}, - {245, 6, 272, 24, "Inv3", 0, 0, BUTTON_NONE, 0}, - {277, 6, 304, 24, "Inv4", 0, 0, BUTTON_NONE, 0}, - {181, 27, 208, 45, "Inv5", 0, 0, BUTTON_NONE, 0}, - {213, 27, 240, 45, "Inv6", 0, 0, BUTTON_NONE, 0}, - {245, 27, 272, 45, "Inv7", 0, 0, BUTTON_NONE, 0}, - {277, 27, 304, 45, "Inv8", 0, 0, BUTTON_NONE, 0}, - {306, 6, 314, 11, "InvUp", 0, 0, BUTTON_NONE, 0}, - {306, 41, 314, 45, "InvDown", 0, 0, BUTTON_NONE, 0} -}; - - -static InterfaceButton IHNMMainPanel[] = { - {5, 4, 46, 47, "Portrait", 0, 0, 0, 0} -}; - -int Interface::registerLang(void) { -#if 0 - size_t i; - - for (i = 0; i < ARRAYSIZE(I_VerbData); i++) { - if (CVAR_Register_S(I_VerbData[i].verb_str, - I_VerbData[i].verb_cvar, - NULL, CVAR_CFG, VERB_STRLIMIT) != SUCCESS) { - - return FAILURE; - } - - assert(CVAR_Find(I_VerbData[i].verb_cvar) != NULL); - } -#endif - - return SUCCESS; -} - Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { + byte *resource; + size_t resourceLength; int result; + int i; if (_initialized) { return; @@ -107,71 +69,65 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { _iThread = _vm->_script->SThreadCreate(); if (_iThread == NULL) { - warning("Interface::Interface(): Error creating script thread for game interface module"); - return; + error("Interface::Interface(): Error creating script thread for game interface module"); } // Load interface module resource file context _interfaceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0); if (_interfaceContext == NULL) { - return; + error("Interface::Interface(): unable to load resource"); } + + _mainPanel.buttons = _vm->getDisplayInfo().mainPanelButtons; + _mainPanel.buttonsCount = _vm->getDisplayInfo().mainPanelButtonsCount; - // Initialize interface data by game type - if (_vm->getGameType() == GType_ITE) { - // Load Inherit the Earth interface desc - _mainPanel.buttons = ITEMainPanel; - _mainPanel.nbuttons = ARRAYSIZE(ITEMainPanel); - - } else if (_vm->getGameType() == GType_IHNM) { - // Load I Have No Mouth interface desc - _mainPanel.buttons = IHNMMainPanel; - _mainPanel.nbuttons = ARRAYSIZE(IHNMMainPanel); - } else { - return; + for (i = 0; i < kVerbTypesMax; i++) { + _verbTypeToPanelButton[i] = NULL; + } + + for (i = 0; i < _mainPanel.buttonsCount; i++) { + if (_mainPanel.buttons[i].type == kPanelButtonVerb) { + _verbTypeToPanelButton[_mainPanel.buttons[i].id] = &_mainPanel.buttons[i]; + } } - // Load command panel resource - result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->command_panel_rn, &_mainPanel.res, &_mainPanel.res_len); - if (result != SUCCESS) { - return; + result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->mainPanelResourceId, &resource, &resourceLength); + if ((result != SUCCESS) || (resourceLength == 0)) { + error("Interface::Interface(): unable to load mainPanel resource"); } + _vm->decodeBGImage(resource, resourceLength, &_mainPanel.image, + &_mainPanel.imageLength, &_mainPanel.imageWidth, &_mainPanel.imageHeight); + + RSC_FreeResource(resource); - // Load dialogue panel resource - result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->dialogue_panel_rn, &_conversePanel.res, &_conversePanel.res_len); - if (result != SUCCESS) { - return; + result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->conversePanelResourceId, &resource, &resourceLength); + if ((result != SUCCESS) || (resourceLength == 0)) { + error("Interface::Interface unable to load conversePanel resource"); } + _vm->decodeBGImage(resource, resourceLength, &_conversePanel.image, + &_conversePanel.imageLength, &_conversePanel.imageWidth, &_conversePanel.imageHeight); + RSC_FreeResource(resource); - if (_vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, _mainPanel.sprites) != SUCCESS) { - error("Unable to load sprite list"); + if (_vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, _mainPanel.sprites) != SUCCESS) { //TODO: move constant to ResourceDescription + error("Interface::Interface(): Unable to load sprite list"); } - - - if (_vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, _defPortraits) != SUCCESS) { - error("Unable to load sprite list"); + + if (_vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, _defPortraits) != SUCCESS) { //TODO: move constant to ResourceDescription + error("Interface::Interface(): Unable to load sprite list"); } - _vm->decodeBGImage(_mainPanel.res, _mainPanel.res_len, &_mainPanel.img, - &_mainPanel.img_len, &_mainPanel.img_w, &_mainPanel.img_h); - - _vm->decodeBGImage(_conversePanel.res, _conversePanel.res_len, - &_conversePanel.img, &_conversePanel.img_len, - &_conversePanel.img_w, &_conversePanel.img_h); - - _mainPanel.x = 0; + _mainPanel.x = 0; //TODO: move constant to DisplayInfo _mainPanel.y = 149; + _mainPanel.currentButton = NULL; - _conversePanel.x = 0; + _conversePanel.x = 0; //TODO: move constant to DisplayInfo _conversePanel.y = 149; + _conversePanel.currentButton = NULL; - _mainPanel.set_button = 1; _leftPortrait = 0; _rightPortrait = 0; - _activeVerb = I_VERB_WALKTO; - _active = false; _panelMode = _lockedMode = kPanelNull; _savedMode = -1; @@ -183,7 +139,7 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { _inventory = (uint16 *)calloc(_inventorySize, sizeof(uint16)); if (_inventory == NULL) { - return; + error("Interface::Interface(): not enough memory"); } _initialized = true; @@ -259,12 +215,47 @@ int Interface::setMode(int mode, bool force) { } else _panelMode = newMode; + + if (_panelMode == kPanelMain) { + _mainPanel.currentButton = NULL; + } else { + if (_panelMode == kPanelConverse) { + _conversePanel.currentButton = NULL; + } + } draw(); return SUCCESS; } +bool Interface::processKeyCode(int keyCode) { + int i; + switch (_panelMode) { + case kPanelNull: + if (keyCode == 27) {// Esc + if (_vm->_scene->isInDemo()) { + _vm->_scene->skipScene(); + } else { + _vm->_actor->abortAllSpeeches(); + } + return true; + } + break; + case kPanelMain: + for (i = 0; i < kVerbTypesMax; i++) { + if (_verbTypeToPanelButton[i] != NULL) { + if (_verbTypeToPanelButton[i]->keyChar == keyCode) { + _vm->_script->setVerb(_verbTypeToPanelButton[i]->id); + return true; + } + } + } + break; + } + return false; +} + int Interface::setStatusText(const char *new_txt) { assert(new_txt != NULL); @@ -295,6 +286,7 @@ int Interface::setRightPortrait(int portrait) { int Interface::draw() { SURFACE *backBuffer; + int i; Point base; Point leftPortraitPoint; @@ -314,32 +306,37 @@ int Interface::draw() { base.y = _mainPanel.y; origin.x = 0; - origin.y = _vm->getDisplayHeight() - _mainPanel.img_h; + origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight; - bufToSurface(backBuffer, _mainPanel.img, _mainPanel.img_w, _mainPanel.img_h, NULL, &origin); - + bufToSurface(backBuffer, _mainPanel.image, _mainPanel.imageWidth, _mainPanel.imageHeight, NULL, &origin); + //here we will draw verbs + for (i = 0; i < kVerbTypesMax; i++) { + if (_verbTypeToPanelButton[i] != NULL) { + drawPanelButtonText(backBuffer, &_mainPanel, _verbTypeToPanelButton[i], _vm->getDisplayInfo().verbTextColor, _vm->getDisplayInfo().verbTextShadowColor); + } + } } else { base.x = _conversePanel.x; base.y = _conversePanel.y; origin.x = 0; - origin.y = _vm->getDisplayHeight() - _mainPanel.img_h; + origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight; - bufToSurface(backBuffer, _conversePanel.img, _conversePanel.img_w, - _conversePanel.img_h, NULL, &origin); + bufToSurface(backBuffer, _conversePanel.image, _conversePanel.imageWidth, + _conversePanel.imageHeight, NULL, &origin); } if (_panelMode == kPanelMain || _panelMode == kPanelConverse || _lockedMode == kPanelMain || _lockedMode == kPanelConverse) { - leftPortraitPoint.x = base.x + _vm->getDisplayInfo().leftPortraitX; - leftPortraitPoint.y = base.y + _vm->getDisplayInfo().leftPortraitY; + leftPortraitPoint.x = base.x + _vm->getDisplayInfo().leftPortraitXOffset; + leftPortraitPoint.y = base.y + _vm->getDisplayInfo().leftPortraitYOffset; _vm->_sprite->draw(backBuffer, _defPortraits, _leftPortrait, leftPortraitPoint, 256); } - if (!_inMainMode && _vm->getDisplayInfo().rightPortraitX >= 0) { - rightPortraitPoint.x = base.x + _vm->getDisplayInfo().rightPortraitX; - rightPortraitPoint.y = base.y + _vm->getDisplayInfo().rightPortraitY; + if (!_inMainMode && _vm->getDisplayInfo().rightPortraitXOffset >= 0) { + rightPortraitPoint.x = base.x + _vm->getDisplayInfo().rightPortraitXOffset; + rightPortraitPoint.y = base.y + _vm->getDisplayInfo().rightPortraitYOffset; _vm->_sprite->draw(backBuffer, _scenePortraits, _rightPortrait, rightPortraitPoint, 256); } @@ -350,40 +347,41 @@ int Interface::draw() { return SUCCESS; } -int Interface::update(const Point& imousePt, int update_flag) { - SURFACE *back_buf; +int Interface::update(const Point& imousePointer, int updateFlag) { + SURFACE *backBuffer; - int imouse_x, imouse_y; if (_vm->_scene->isInDemo() || _panelMode == kPanelFade) return SUCCESS; - imouse_x = imousePt.x; - imouse_y = imousePt.y; - - back_buf = _vm->_gfx->getBackBuffer(); + + backBuffer = _vm->_gfx->getBackBuffer(); if (_panelMode == kPanelMain) { // FIXME: HACK // Update playfield space ( only if cursor is inside ) - if (imouse_y < _vm->getSceneHeight()) { + if (imousePointer.y < _vm->getSceneHeight()) { // Mouse is in playfield space - if (update_flag == UPDATE_MOUSEMOVE) { - handlePlayfieldUpdate(back_buf, imousePt); - } else if (update_flag == UPDATE_MOUSECLICK) { - handlePlayfieldClick(back_buf, imousePt); + if (updateFlag == UPDATE_MOUSEMOVE) { + handlePlayfieldUpdate(backBuffer, imousePointer); + } else { + if (updateFlag == UPDATE_MOUSECLICK) { + handlePlayfieldClick(backBuffer, imousePointer); + } + } + } else { + // Update command space + if (updateFlag == UPDATE_MOUSEMOVE) { + handleCommandUpdate(backBuffer, imousePointer); + } else { + if (updateFlag == UPDATE_MOUSECLICK) { + handleCommandClick(backBuffer, imousePointer); + } } - } - - // Update command space - if (update_flag == UPDATE_MOUSEMOVE) { - handleCommandUpdate(back_buf, imousePt); - } else if (update_flag == UPDATE_MOUSECLICK) { - handleCommandClick(back_buf, imousePt); } } - drawStatusBar(back_buf); + drawStatusBar(backBuffer); return SUCCESS; } @@ -417,112 +415,40 @@ int Interface::drawStatusBar(SURFACE *ds) { return SUCCESS; } -int Interface::handleCommandClick(SURFACE *ds, const Point& imousePt) { - int hit_button; - int ibutton_num; +void Interface::handleCommandClick(SURFACE *ds, const Point& imousePointer) { - int x_base; - int y_base; + PanelButton *panelButton; - Point button; - - int old_set_button; - int set_button; - - hit_button = hitTest(imousePt, &ibutton_num); - if (hit_button != SUCCESS) { - // Clicking somewhere other than a button doesn't do anything - return SUCCESS; + panelButton = verbHitTest(imousePointer); + if (panelButton) { + _vm->_script->setVerb(panelButton->id); + return; } +} - x_base = _mainPanel.x; - y_base = _mainPanel.y; - - if (_mainPanel.buttons[ibutton_num].flags & BUTTON_SET) { - old_set_button = _mainPanel.set_button; - set_button = ibutton_num; - _mainPanel.set_button = set_button; - - if (_mainPanel.buttons[set_button].flags & BUTTON_VERB) { - _activeVerb = _mainPanel.buttons[ibutton_num].data; - } - - if (_mainPanel.buttons[set_button].flags & BUTTON_BITMAP) { - button.x = x_base + _mainPanel.buttons[set_button].x1; - button.y = y_base + _mainPanel.buttons[set_button].y1; +void Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePointer) { + PanelButton *panelButton; - _vm->_sprite->draw(ds, _mainPanel.sprites, _mainPanel.buttons[set_button]. - active_sprite - 1, button, 256); + panelButton = verbHitTest(imousePointer); + if (_mainPanel.currentButton != panelButton) { + if (_mainPanel.currentButton) { + drawVerb(_mainPanel.currentButton->id, 0); } - - if (_mainPanel.buttons[old_set_button].flags & BUTTON_BITMAP) { - button.x = x_base + _mainPanel.buttons[old_set_button].x1; - button.y = y_base + _mainPanel.buttons[old_set_button].y1; - - _vm->_sprite->draw(ds, _mainPanel.sprites, _mainPanel.buttons[old_set_button]. - inactive_sprite - 1, button, 256); + if (panelButton) { + drawVerb(panelButton->id, 1); } } - - return SUCCESS; -} - -int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) { - int hit_button; - int ibutton_num; - -// int button_w = 0; - -/* int verb_idx = 0; - int string_w = 0; - int color; - int i;*/ - - hit_button = inventoryTest(imousePt, &ibutton_num); + _mainPanel.currentButton = panelButton; + if (panelButton) { + return; + } +/* hit_button = inventoryTest(imousePointer, &ibutton_num); if (hit_button == SUCCESS) { // Hovering over an inventory object return SUCCESS; - } - -/* hit_button = hitTest(imousePt, &ibutton_num); - - if (hit_button == SUCCESS) { - // Hovering over a command panel button - setStatusText(I_VerbData[_activeVerb].verb_str); - } + }*/ - for (i = 0; i < _mainPanel.nbuttons; i++) { - if (!(_mainPanel.buttons[i].flags & BUTTON_LABEL)) { - continue; - } - - button_w = _mainPanel.buttons[i].x2 - _mainPanel.buttons[i].x1; - - verb_idx = _mainPanel.buttons[i].data; - - string_w = _vm->_font->getStringWidth(SMALL_FONT_ID, I_VerbData[verb_idx].verb_str, 0, 0); - - if (i == hit_button) { - color = _iDesc.cmd_txt_hilitecol; - } else { - color = _iDesc.cmd_txt_col; - } - - button.x = _mainPanel.x + _mainPanel.buttons[i].x1; - button.y = _mainPanel.y + _mainPanel.buttons[i].y1; - - _vm->_font->draw(SMALL_FONT_ID, ds, I_VerbData[verb_idx].verb_str, 0, - button.x + ((button_w / 2) - (string_w / 2)), button.y + 1, - color, _iDesc.cmd_txt_shadowcol, FONT_SHADOW); - - if ((i == _mainPanel.set_button) && (_mainPanel.buttons[i].flags & BUTTON_BITMAP)) { - _vm->_sprite->draw(ds, _mainPanel.sprites, _mainPanel.buttons[i].active_sprite - 1, - button, 256); - } - } -*/ - return SUCCESS; } int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { @@ -531,7 +457,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { int objectNum; uint16 object_flags = 0; - int script_num; +// int script_num; ActorLocation location; objectNum = _vm->_scene->_objectMap->hitTest(imousePt); @@ -547,7 +473,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { object_flags = _vm->_scene->_objectMap->getFlags(objectNum); if (object_flags & kHitZoneExit) { // FIXME. This is wrong - if ((script_num = _vm->_scene->_objectMap->getEPNum(objectNum)) != -1) { +/* if ((script_num = _vm->_scene->_objectMap->getEPNum(objectNum)) != -1) { // Set active verb in script module _vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb); @@ -555,7 +481,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) { if (script_num != 0) { _vm->_script->SThreadExecute(_iThread, script_num); } - } + }*/ } else { // Not a normal scene object - walk to it as if it weren't there location.fromScreenPoint(imousePt); @@ -603,31 +529,23 @@ int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) { */ } -int Interface::hitTest(const Point& imousePt, int *ibutton) { - InterfaceButton *buttons; - - int nbuttons; - int xbase; - int ybase; - +PanelButton *Interface::verbHitTest(const Point& imousePointer) { + PanelButton *panelButton; + Rect rect; int i; - - buttons = _mainPanel.buttons; - nbuttons = _mainPanel.nbuttons; - - xbase = _mainPanel.x; - ybase = _mainPanel.y; - - for (i = 0; i < nbuttons; i++) { - if ((imousePt.x >= (xbase + buttons[i].x1)) && (imousePt.x < (xbase + buttons[i].x2)) && - (imousePt.y >= (ybase + buttons[i].y1)) && (imousePt.y < (ybase + buttons[i].y2))) { - *ibutton = i; - return SUCCESS; + for (i = 0; i < kVerbTypesMax; i++) { + panelButton = _verbTypeToPanelButton[i]; + if (panelButton != NULL) { + rect.left = _mainPanel.x + panelButton->xOffset; + rect.right = rect.left + panelButton->width; + rect.top = _mainPanel.y + panelButton->yOffset; + rect.bottom = rect.top + panelButton->height; + if (rect.contains(imousePointer)) + return panelButton; } } - *ibutton = -1; - return FAILURE; + return NULL; } void Interface::addToInventory(int sprite) { @@ -670,8 +588,8 @@ void Interface::drawInventory() { int row = 0; int col = 0; - int x = _vm->getDisplayInfo().inventoryX + _vm->getDisplayInfo().inventoryIconX; - int y = _vm->getDisplayInfo().inventoryY + _vm->getDisplayInfo().inventoryIconY; + int x = _vm->getDisplayInfo().inventoryX + _vm->getDisplayInfo().inventoryIconXOffset; + int y = _vm->getDisplayInfo().inventoryY + _vm->getDisplayInfo().inventoryIconYOffset; int width = _vm->getDisplayInfo().inventoryIconWidth + _vm->getDisplayInfo().inventoryXSpacing; int height = _vm->getDisplayInfo().inventoryIconHeight + _vm->getDisplayInfo().inventoryYSpacing; Point drawPoint; @@ -726,6 +644,71 @@ int Interface::inventoryTest(const Point& imousePt, int *ibutton) { } void Interface::drawVerb(int verb, int state) { + SURFACE *backBuffer; + PanelButton * panelButton; + PanelButton * rightButtonVerbPanelButton; + PanelButton * currentVerbPanelButton; + int textColor; + int spriteNumber; + Point point; + + backBuffer = _vm->_gfx->getBackBuffer(); + + panelButton = getPanelButtonByVerbType(verb); + rightButtonVerbPanelButton = getPanelButtonByVerbType(_vm->_script->getRightButtonVerb()); + currentVerbPanelButton = getPanelButtonByVerbType(_vm->_script->getCurrentVerb()); + + if (panelButton == NULL) { + warning("panelButton == NULL"); + return; + } + if (state == 2) { + state = (_mainPanel.currentButton == panelButton) ? 1 : 0; + } + + if (state) { + textColor = _vm->getDisplayInfo().verbTextActiveColor; + } else { + if (panelButton == rightButtonVerbPanelButton) { + textColor = _vm->getDisplayInfo().verbTextActiveColor; + } else { + textColor = _vm->getDisplayInfo().verbTextColor; + } + } + + if (panelButton == currentVerbPanelButton) { + spriteNumber = panelButton->downSpriteNumber; + } else { + spriteNumber = panelButton->upSpriteNumber; + } + point.x = _mainPanel.x + panelButton->xOffset; + point.y = _mainPanel.y + panelButton->yOffset; + + _vm->_sprite->draw(backBuffer, _mainPanel.sprites, spriteNumber, point, 256); + + drawPanelButtonText(backBuffer, &_mainPanel, panelButton, textColor, _vm->getDisplayInfo().verbTextShadowColor); +} + +void Interface::drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor) { + const char *text; + int textWidth; + Point point; + int textId; + + textId = verbTypeToTextStringsIdLUT[panelButton->id]; + + if (textId == -1) + error("textId == -1"); + + text = _vm->getTextString(textId); + + + textWidth = _vm->_font->getStringWidth(SMALL_FONT_ID, text, 0, 0); + + point.x = panel->x + panelButton->xOffset + (panelButton->width / 2) - (textWidth / 2); + point.y = panel->y + panelButton->yOffset + 1; + + _vm->_font->draw(SMALL_FONT_ID, ds, text, 0, point.x , point.y, textColor, textShadowColor, (textShadowColor != 0) ? FONT_SHADOW : 0); } // Converse stuff diff --git a/saga/interface.h b/saga/interface.h index f6d98ff2b2..e481998de9 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -48,7 +48,7 @@ enum INTERFACE_UPDATE_FLAGS { #define CONVERSE_TEXT_HEIGHT 10 #define CONVERSE_TEXT_LINES 4 -enum PANEL_MODES { +enum PanelModes { kPanelNull, kPanelMain, kPanelOption, @@ -64,58 +64,21 @@ enum PANEL_MODES { kPanelFade }; -enum BUTTON_FLAGS { - BUTTON_NONE = 0x0, - BUTTON_LABEL = 0x01, - BUTTON_BITMAP = 0x02, - BUTTON_SET = 0x04, - BUTTON_VERB = BUTTON_LABEL | BUTTON_BITMAP | BUTTON_SET -}; - -struct InterfaceButton { - int x1; - int y1; - int x2; - int y2; - const char *label; - int inactive_sprite; - int active_sprite; - int flags; - int data; -}; - struct InterfacePanel { - byte *res; - size_t res_len; int x; int y; - byte *img; - size_t img_len; - int img_w; - int img_h; - int set_button;//TODO: remove - int nbuttons; - InterfaceButton *buttons; + byte *image; + size_t imageLength; + int imageWidth; + int imageHeight; + + PanelButton *currentButton; + int buttonsCount; + PanelButton *buttons; SpriteList sprites; }; -enum INTERFACE_VERBS { - I_VERB_WALKTO, - I_VERB_LOOKAT, - I_VERB_PICKUP, - I_VERB_TALKTO, - I_VERB_OPEN, - I_VERB_CLOSE, - I_VERB_USE, - I_VERB_GIVE -}; -struct VERB_DATA { - int i_verb; - const char *verb_cvar; - char verb_str[VERB_STRLIMIT]; - int s_verb; -}; struct Converse { char *text; @@ -131,11 +94,10 @@ public: Interface(SagaEngine *vm); ~Interface(void); - int registerLang(); int activate(); int deactivate(); int setMode(int mode, bool force = false); - int getMode(void) { return _panelMode; } + int getMode(void) const { return _panelMode; } void rememberMode(); void restoreMode(); void lockMode() { _lockedMode = _panelMode; } @@ -146,22 +108,25 @@ public: int setLeftPortrait(int portrait); int setRightPortrait(int portrait); int draw(); + int update(const Point& imousePointer, int updateFlag); int drawStatusBar(SURFACE *ds); - int update(const Point& imousePt, int update_flag); + void drawVerb(int verb, int state); + bool processKeyCode(int keyCode); + void addToInventory(int sprite); void removeFromInventory(int sprite); void drawInventory(); - int inventoryTest(const Point& imousePt, int *ibutton); - + private: - int hitTest(const Point& imousePt, int *ibutton); - int handleCommandUpdate(SURFACE *ds, const Point& imousePt); - int handleCommandClick(SURFACE *ds, const Point& imousePt); + int inventoryTest(const Point& imousePt, int *ibutton); + PanelButton *verbHitTest(const Point& imousePointer); + void handleCommandUpdate(SURFACE *ds, const Point& imousePointer); + void handleCommandClick(SURFACE *ds, const Point& imousePointer); int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt); int handlePlayfieldClick(SURFACE *ds, const Point& imousePt); - void drawVerb(int verb, int state); - + + void drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor); public: void converseClear(void); bool converseAddText(const char *text, int replyId, byte replyFlags, int replyBit); @@ -172,28 +137,33 @@ public: private: void converseDisplayTextLine(int textcolor, bool btnUp, bool rebuild); - - + PanelButton *getPanelButtonByVerbType(int verb) { + if ((verb < 0) || (verb >= kVerbTypesMax)) { + error("Interface::getPanelButtonByVerbType wrong verb"); + } + return _verbTypeToPanelButton[verb]; + } private: SagaEngine *_vm; bool _initialized; - bool _active; RSCFILE_CONTEXT *_interfaceContext; + InterfacePanel _mainPanel; + InterfacePanel _conversePanel; + SpriteList _defPortraits; + SpriteList _scenePortraits; + SCRIPT_THREAD *_iThread; + PanelButton *_verbTypeToPanelButton[kVerbTypesMax]; + + bool _active; int _panelMode; int _savedMode; int _lockedMode; bool _inMainMode; - InterfacePanel _mainPanel; - InterfacePanel _conversePanel; char _statusText[STATUS_TEXT_LEN]; int _leftPortrait; int _rightPortrait; - SpriteList _defPortraits; - SpriteList _scenePortraits; - int _activeVerb; - SCRIPT_THREAD *_iThread; - + uint16 *_inventory; int _inventorySize; byte _inventoryCount; diff --git a/saga/saga.cpp b/saga/saga.cpp index 58ebbd7862..bd7a68db4b 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -60,6 +60,48 @@ static const GameSettings saga_games[] = { {0, 0, 0} }; +static const char *englishTextStrings[] = { + "Walk to", + "Look At", + "Pick Up", + "Talk to", + "Open", + "Close", + "Use", + "Give", + "Options", + "Test", + "Demo", + "Help", + "Quit Game", + "Fast", + "Slow", + "On", + "Off", + "Continue Playing", + "Load", + "Save", + "Game Options", + "Reading Speed", + "Music", + "Sound", + "Cancel", + "Quit", + "OK", + "Mid", + "Click", + "10%", + "20%", + "30%", + "40%", + "50%", + "60%", + "70%", + "80%", + "90%", + "Max" +}; + GameList Engine_SAGA_gameList() { GameList games; const GameSettings *g = saga_games; @@ -333,4 +375,9 @@ const char *SagaEngine::getObjectName(uint16 objectId) { return NULL; } +const char *SagaEngine::getTextString(int textStringId) { + + return englishTextStrings[textStringId]; //TODO: i18n +} + } // End of namespace Saga diff --git a/saga/saga.h b/saga/saga.h index d50a4b7de8..e1ac0a17cf 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -99,7 +99,7 @@ enum GameObjectTypes { kGameObjectStepZone = 4 }; -enum scriptTimings { +enum ScriptTimings { kScriptTimeTicksPerSecond = (728L/10L), kRepeatSpeed = 40, // 25 frames/sec kNormalFadeDuration = 320, // 64 steps, 5 msec each @@ -131,6 +131,52 @@ enum HitZoneFlags { kHitZoneTerminus = (1 << 3) }; +enum PanelButtonType { + kPanelButtonVerb = 0, + kPanelButtonArrow = 1 +}; + +enum TextStringIds { + kTextWalkTo, + kTextLookAt, + kTextPickUp, + kTextTalkTo, + kTextOpen, + kTextClose, + kTextUse, + kTextGive, + kTextOptions, + kTextTest, + kTextDemo, + kTextHelp, + kTextQuitGame, + kTextFast, + kTextSlow, + kTextOn, + kTextOff, + kTextContinuePlaying, + kTextLoad, + kTextSave, + kTextGameOptions, + kTextReadingSpeed, + kTextMusic, + kTextSound, + kTextCancel, + kTextQuit, + kTextOK, + kTextMid, + kTextClick, + kText10Percent, + kText20Percent, + kText30Percent, + kText40Percent, + kText50Percent, + kText60Percent, + kText70Percent, + kText80Percent, + kText90Percent, + kTextMax +}; struct IMAGE_HEADER { int width; @@ -236,8 +282,8 @@ struct GameFontDescription { struct GameResourceDescription { uint32 scene_lut_rn; uint32 script_lut_rn; - uint32 command_panel_rn; - uint32 dialogue_panel_rn; + uint32 mainPanelResourceId; + uint32 conversePanelResourceId; }; struct GameFileDescription { @@ -245,6 +291,18 @@ struct GameFileDescription { uint16 fileType; }; +struct PanelButton { + PanelButtonType type; + int xOffset; + int yOffset; + int width; + int height; + int id; + int keyChar; + int upSpriteNumber; + int downSpriteNumber; +}; + struct GameDisplayInfo { int logicalWidth; int logicalHeight; @@ -263,10 +321,10 @@ struct GameDisplayInfo { int verbTextShadowColor; int verbTextActiveColor; - int leftPortraitX; - int leftPortraitY; - int rightPortraitX; - int rightPortraitY; + int leftPortraitXOffset; + int leftPortraitYOffset; + int rightPortraitXOffset; + int rightPortraitYOffset; int inventoryX; int inventoryY; @@ -274,12 +332,15 @@ struct GameDisplayInfo { int inventoryColumns; int inventoryIconWidth; int inventoryIconHeight; - int inventoryIconX; - int inventoryIconY; + int inventoryIconXOffset; + int inventoryIconYOffset; int inventoryXSpacing; int inventoryYSpacing; + int mainPanelButtonsCount; + PanelButton *mainPanelButtons; }; + struct GameDescription { const char *name; SAGAGameType gameType; @@ -433,6 +494,8 @@ public: int getDisplayHeight() const { return _gameDisplayInfo.logicalHeight;} int getSceneHeight() const { return _gameDisplayInfo.sceneHeight; } const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; } + + const char *getTextString(int textStringId); private: int loadLanguage(void); int loadGame(int gameNumber); diff --git a/saga/script.cpp b/saga/script.cpp index 06b889ec37..f880dd2fd4 100644 --- a/saga/script.cpp +++ b/saga/script.cpp @@ -613,6 +613,31 @@ void Script::setVerb(int verb) { } void Script::setLeftButtonVerb(int verb) { + int oldVerb = _currentVerb; + + _currentVerb = _leftButtonVerb = verb; + + if ((_currentVerb != oldVerb) && (_vm->_interface->getMode() == kPanelMain)){ + if (oldVerb > kVerbNone) + _vm->_interface->drawVerb(oldVerb, 2); + + if (_currentVerb > kVerbNone) + _vm->_interface->drawVerb(_currentVerb, 2); + } +} + +void Script::setRightButtonVerb(int verb) { + int oldVerb = _currentVerb; + + _rightButtonVerb = verb; + + if ((_rightButtonVerb != oldVerb) && (_vm->_interface->getMode() == kPanelMain)){ + if (oldVerb > kVerbNone) + _vm->_interface->drawVerb(oldVerb, 2); + + if (_rightButtonVerb > kVerbNone) + _vm->_interface->drawVerb(_rightButtonVerb, 2); + } } void Script::doVerb() { diff --git a/saga/script.h b/saga/script.h index 30a58028ae..94f49c33bd 100644 --- a/saga/script.h +++ b/saga/script.h @@ -54,10 +54,10 @@ typedef unsigned int ScriptDataWord; enum VerbTypes { //todo: LUT for drawing kVerbNone = 0, - kVerbPickup = 1, + kVerbPickUp = 1, kVerbLookAt = 2, kVerbWalkTo = 3, - kVerbSpeakTo = 4, + kVerbTalkTo = 4, kVerbOpen = 5, kVerbClose = 6, kVerbGive = 7, @@ -67,7 +67,9 @@ enum VerbTypes { kVerbLeave = 11, kVerbBegin = 12, kVerbWalkOnly = 13, - kVerbLookOnly = 14 + kVerbLookOnly = 14, + + kVerbTypesMax = kVerbLookOnly + 1 }; #define STHREAD_TIMESLICE 8 @@ -250,6 +252,10 @@ public: void showVerb(); void setVerb(int verb); void setLeftButtonVerb(int verb); + void setRightButtonVerb(int verb); + int getCurrentVerb() const { return _currentVerb; } + int getLeftButtonVerb() const { return _leftButtonVerb; } + int getRightButtonVerb() const { return _rightButtonVerb; } void scriptInfo(); void scriptExec(int argc, const char **argv); |