From d52032c75c4c3964219874d68ec9a84dc8e6f3fa Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Mon, 18 Apr 2005 20:03:14 +0000 Subject: converse support improved (still has some bugs) fixed: now protagonist can't be target object fixed: statusbar color added: *mouseButtonPressed in SagaEngine svn-id: r17672 --- saga/actor.cpp | 11 +- saga/actor.h | 7 +- saga/events.cpp | 4 +- saga/game.cpp | 25 +++- saga/input.cpp | 26 ++-- saga/interface.cpp | 356 +++++++++++++++++++++++++++++++++-------------------- saga/interface.h | 31 +++-- saga/render.cpp | 2 +- saga/saga.cpp | 2 + saga/saga.h | 25 +++- saga/script.cpp | 20 ++- saga/script.h | 2 +- saga/sfuncs.cpp | 5 +- saga/sthread.cpp | 1 + 14 files changed, 327 insertions(+), 190 deletions(-) diff --git a/saga/actor.cpp b/saga/actor.cpp index fdd0649e5c..d2fc6352ed 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -260,8 +260,6 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) { obj->location.y = ITE_ObjectTable[i].y; obj->location.z = ITE_ObjectTable[i].z; obj->disabled = false; - - obj->spritelistRn = 0; } } else { @@ -857,8 +855,8 @@ void Actor::handleActions(int msec, bool setup) { while ((delta.u() == 0) && (delta.v() == 0)) { - if ((actor == _protagonist) && (_vm->_interface->_playfieldClicked)) { - _vm->_isoMap->screenPointToTileCoords(_vm->getMousePos(), pickLocation); + if ((actor == _protagonist) && (_vm->mouseButtonPressed())) { + _vm->_isoMap->screenPointToTileCoords(_vm->mousePos(), pickLocation); if (!actorWalkTo(_protagonist->id, pickLocation)) { break; @@ -1170,7 +1168,7 @@ void Actor::calcScreenPosition(CommonObjectData *commonObjectData) { } -uint16 Actor::hitTest(const Point &testPoint) { +uint16 Actor::hitTest(const Point &testPoint, bool skipProtagonist) { CommonObjectOrderList::iterator drawOrderIterator; CommonObjectDataPointer drawObject; int frameNumber; @@ -1178,6 +1176,9 @@ uint16 Actor::hitTest(const Point &testPoint) { createDrawOrderList(); for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) { drawObject = drawOrderIterator.operator*(); + if (skipProtagonist && (drawObject == _protagonist)) { + continue; + } if (!getSpriteParams(drawObject, frameNumber, spriteList)) { continue; } diff --git a/saga/actor.h b/saga/actor.h index f9051cfad8..d75f5a7271 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -194,6 +194,8 @@ public: int sceneNumber; // scene int scriptEntrypointNumber; // script entrypoint number + int32 spriteListResourceId; // sprite list resource id + Location location; // logical coordinates Point screenPosition; // screen coordinates int screenDepth; // @@ -205,6 +207,7 @@ public: screenDepth = screenScale = 0; flags = 0; frameNumber = 0; + spriteListResourceId = 0; } }; @@ -216,7 +219,6 @@ typedef SortedList CommonObjectOrderList; class ObjectData: public CommonObjectData { public: uint16 interactBits; - int32 spritelistRn; }; class ActorData: public CommonObjectData { @@ -238,7 +240,6 @@ public: uint8 cycleFlags; SpriteList spriteList; // sprite list data - int spriteListResourceId; // sprite list resource id ActorFrameSequence *frames; // Actor's frames int framesCount; // Actor's frames count @@ -354,7 +355,7 @@ public: void drawPathTest(); - uint16 hitTest(const Point &testPoint); + uint16 hitTest(const Point &testPoint, bool skipProtagonist); void takeExit(uint16 actorId, const HitZone *hitZone); bool actorEndWalk(uint16 actorId, bool recurse); bool actorWalkTo(uint16 actorId, const Location &toLocation); diff --git a/saga/events.cpp b/saga/events.cpp index 1483bbc3a1..bbf916443c 100644 --- a/saga/events.cpp +++ b/saga/events.cpp @@ -378,11 +378,11 @@ int Events::handleOneShot(EVENT *event) { break; case EVENT_SET_STATUS: _vm->_interface->setStatusText((const char*)event->data); - _vm->_interface->drawStatusBar(_vm->_gfx->getBackBuffer()); + _vm->_interface->drawStatusBar(); break; case EVENT_CLEAR_STATUS: _vm->_interface->setStatusText(""); - _vm->_interface->drawStatusBar(_vm->_gfx->getBackBuffer()); + _vm->_interface->drawStatusBar(); break; case EVENT_RESTORE_MODE: _vm->_interface->restoreMode(); diff --git a/saga/game.cpp b/saga/game.cpp index 9322d4000e..3e663bd22d 100644 --- a/saga/game.cpp +++ b/saga/game.cpp @@ -50,8 +50,17 @@ static PanelButton ITE_MainPanelButtons[] = { {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} + {kPanelButtonArrow, 306, 6, 8, 5, 0, 'u', 0, 0}, + {kPanelButtonArrow, 306, 41, 8, 5, 1, 'd', 0, 0} +}; + +static PanelButton ITE_ConversePanelButtons[] = { + {kPanelButtonConverseText, 52, 6 + CONVERSE_TEXT_HEIGHT * 0, CONVERSE_MAX_TEXT_WIDTH, CONVERSE_TEXT_HEIGHT, 0, '1', 0, 0}, + {kPanelButtonConverseText, 52, 6 + CONVERSE_TEXT_HEIGHT * 1, CONVERSE_MAX_TEXT_WIDTH, CONVERSE_TEXT_HEIGHT, 1, '2', 0, 0}, + {kPanelButtonConverseText, 52, 6 + CONVERSE_TEXT_HEIGHT * 2, CONVERSE_MAX_TEXT_WIDTH, CONVERSE_TEXT_HEIGHT, 2, '3', 0, 0}, + {kPanelButtonConverseText, 52, 6 + CONVERSE_TEXT_HEIGHT * 3, CONVERSE_MAX_TEXT_WIDTH, CONVERSE_TEXT_HEIGHT, 3, '4', 0, 0}, + {kPanelButtonArrow, 257, 6, 9, 6, 0, 'u', 0, 4, 2, 0}, + {kPanelButtonArrow, 257, 41, 9, 6, 1, 'd', 1, 5, 3, 0}, }; static GameDisplayInfo ITE_DisplayInfo = { @@ -80,7 +89,9 @@ static GameDisplayInfo ITE_DisplayInfo = { 1, 0, // inventory icon x, y offset 3, 1, // inventory x, y icon spacing ARRAYSIZE(ITE_MainPanelButtons), - ITE_MainPanelButtons + ITE_MainPanelButtons, + ARRAYSIZE(ITE_ConversePanelButtons), + ITE_ConversePanelButtons }; static GameResourceDescription ITE_Resources = { @@ -196,6 +207,10 @@ static PanelButton IHNM_MainPanelButtons[] = { {kPanelButtonVerb, 0, 0, 0, 0, kVerbWalkTo, ' ', 0, 0}, //TODO }; +static PanelButton IHNM_ConversePanelButtons[] = { + {kPanelButtonConverseText, 0, 0, 0, 0, 0, '1', 0, 0}, //TODO +}; + static GameDisplayInfo IHNM_DisplayInfo = { 640, 480, @@ -222,7 +237,9 @@ static GameDisplayInfo IHNM_DisplayInfo = { 0, 0, 0, 0, ARRAYSIZE(IHNM_MainPanelButtons), - IHNM_MainPanelButtons + IHNM_MainPanelButtons, + ARRAYSIZE(IHNM_ConversePanelButtons), + IHNM_ConversePanelButtons }; static GameResourceDescription IHNM_Resources = { diff --git a/saga/input.cpp b/saga/input.cpp index f49a6de953..56139ae932 100644 --- a/saga/input.cpp +++ b/saga/input.cpp @@ -38,7 +38,7 @@ namespace Saga { int SagaEngine::processInput() { OSystem::Event event; - Point imousePt; +// Point imousePt; while (g_system->pollEvent(event)) { switch (event.type) { @@ -101,17 +101,24 @@ int SagaEngine::processInput() { break; } break; + case OSystem::EVENT_LBUTTONUP: + _leftMouseButtonPressed = false; + break; + case OSystem::EVENT_RBUTTONUP: + _rightMouseButtonPressed = false; + break; case OSystem::EVENT_LBUTTONDOWN: + _leftMouseButtonPressed = true; + _mousePos = event.mouse; + _interface->update(_mousePos, UPDATE_LEFTBUTTONCLICK); + break; case OSystem::EVENT_RBUTTONDOWN: - _mousePos.x = event.mouse.x; - _mousePos.y = event.mouse.y; - imousePt = _mousePos; - _interface->update(imousePt, (event.type == OSystem::EVENT_LBUTTONDOWN) ? UPDATE_LEFTBUTTONCLICK : UPDATE_RIGHTBUTTONCLICK); + _rightMouseButtonPressed = true; + _mousePos = event.mouse; + _interface->update(_mousePos, UPDATE_RIGHTBUTTONCLICK); break; case OSystem::EVENT_MOUSEMOVE: - _mousePos.x = event.mouse.x; - _mousePos.y = event.mouse.y; - imousePt = _mousePos; + _mousePos = event.mouse; break; case OSystem::EVENT_QUIT: _system->quit(); @@ -124,9 +131,6 @@ int SagaEngine::processInput() { return SUCCESS; } -Point SagaEngine::getMousePos() { - return _mousePos; -} } // End of namespace Saga diff --git a/saga/interface.cpp b/saga/interface.cpp index 825fa98258..01661262fb 100644 --- a/saga/interface.cpp +++ b/saga/interface.cpp @@ -67,7 +67,6 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { return; } - _playfieldClicked = false; // Load interface module resource file context _interfaceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0); @@ -97,6 +96,9 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) { RSC_FreeResource(resource); + _conversePanel.buttons = _vm->getDisplayInfo().conversePanelButtons; + _conversePanel.buttonsCount = _vm->getDisplayInfo().conversePanelButtonsCount; + result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->conversePanelResourceId, &resource, &resourceLength); if ((result != SUCCESS) || (resourceLength == 0)) { error("Interface::Interface unable to load conversePanel resource"); @@ -219,6 +221,7 @@ int Interface::setMode(int mode, bool force) { } else { if (_panelMode == kPanelConverse) { _conversePanel.currentButton = NULL; + converseDisplayText(); } } @@ -277,13 +280,13 @@ bool Interface::processKeyCode(int keyCode) { return false; } -int Interface::setStatusText(const char *new_txt) { - assert(new_txt != NULL); - - strncpy(_statusText, new_txt, STATUS_TEXT_LEN); - _statusOnceColor = -1; +void Interface::setStatusText(const char *text, int statusColor) { + assert(text != NULL); + assert(strlen(text) < STATUS_TEXT_LEN); - return SUCCESS; + strncpy(_statusText, text, STATUS_TEXT_LEN); + _statusOnceColor = statusColor; + drawStatusBar(); } int Interface::loadScenePortraits(int resourceId) { @@ -310,7 +313,6 @@ int Interface::draw() { SURFACE *backBuffer; int i; - Point base; Point leftPortraitPoint; Point rightPortraitPoint; Point origin; @@ -321,11 +323,9 @@ int Interface::draw() { return SUCCESS; - drawStatusBar(backBuffer); + drawStatusBar(); if (_panelMode == kPanelMain) { - base.x = _mainPanel.x; - base.y = _mainPanel.y; origin.x = 0; origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight; @@ -338,28 +338,29 @@ int Interface::draw() { } } } else { - base.x = _conversePanel.x; - base.y = _conversePanel.y; + if (_panelMode == kPanelConverse) { - origin.x = 0; - origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight; + origin.x = 0; + origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight; - bufToSurface(backBuffer, _conversePanel.image, _conversePanel.imageWidth, - _conversePanel.imageHeight, NULL, &origin); - converseDisplayText(0); + bufToSurface(backBuffer, _conversePanel.image, _conversePanel.imageWidth, + _conversePanel.imageHeight, NULL, &origin); + + converseDisplayTextLines(backBuffer); + } } if (_panelMode == kPanelMain || _panelMode == kPanelConverse || _lockedMode == kPanelMain || _lockedMode == kPanelConverse) { - leftPortraitPoint.x = base.x + _vm->getDisplayInfo().leftPortraitXOffset; - leftPortraitPoint.y = base.y + _vm->getDisplayInfo().leftPortraitYOffset; + leftPortraitPoint.x = _mainPanel.x + _vm->getDisplayInfo().leftPortraitXOffset; + leftPortraitPoint.y = _mainPanel.y + _vm->getDisplayInfo().leftPortraitYOffset; _vm->_sprite->draw(backBuffer, _defPortraits, _leftPortrait, leftPortraitPoint, 256); } if (!_inMainMode && _vm->getDisplayInfo().rightPortraitXOffset >= 0) { - rightPortraitPoint.x = base.x + _vm->getDisplayInfo().rightPortraitXOffset; - rightPortraitPoint.y = base.y + _vm->getDisplayInfo().rightPortraitYOffset; + rightPortraitPoint.x = _mainPanel.x + _vm->getDisplayInfo().rightPortraitXOffset; + rightPortraitPoint.y = _mainPanel.y + _vm->getDisplayInfo().rightPortraitYOffset; _vm->_sprite->draw(backBuffer, _scenePortraits, _rightPortrait, rightPortraitPoint, 256); } @@ -371,15 +372,10 @@ int Interface::draw() { } int Interface::update(const Point& mousePoint, int updateFlag) { - SURFACE *backBuffer; if (_vm->_scene->isInDemo() || _panelMode == kPanelFade) return SUCCESS; - - backBuffer = _vm->_gfx->getBackBuffer(); - - if (_panelMode == kPanelMain) { if (updateFlag & UPDATE_MOUSEMOVE) { @@ -389,39 +385,51 @@ int Interface::update(const Point& mousePoint, int updateFlag) { if (_lastMousePoint.y < _vm->getSceneHeight()) { _vm->_script->setNonPlayfieldVerb(); } - handleCommandUpdate(backBuffer, mousePoint); + handleCommandUpdate(mousePoint); } } else { if (updateFlag & UPDATE_MOUSECLICK) { if (mousePoint.y < _vm->getSceneHeight()) { - _playfieldClicked = true; _vm->_script->playfieldClick(mousePoint, (updateFlag & UPDATE_LEFTBUTTONCLICK) != 0); - _playfieldClicked = false; } else { - handleCommandClick(backBuffer, mousePoint); + handleCommandClick(mousePoint); } } } } - drawStatusBar(backBuffer); + if (_panelMode == kPanelConverse) { + if (updateFlag & UPDATE_MOUSEMOVE) { + + handleConverseUpdate(mousePoint); + + } else { + if (updateFlag & UPDATE_MOUSECLICK) { + handleConverseClick(mousePoint); + } + } + } + _lastMousePoint = mousePoint; return SUCCESS; } -int Interface::drawStatusBar(SURFACE *ds) { +void Interface::drawStatusBar() { + SURFACE *backBuffer; Rect rect; int string_w; int color; + backBuffer = _vm->_gfx->getBackBuffer(); + // Disable this for IHNM for now, since that game uses the full screen // in some cases. if (_vm->getGameType() == GType_IHNM) { - return SUCCESS; + return; } @@ -431,7 +439,7 @@ int Interface::drawStatusBar(SURFACE *ds) { rect.right = _vm->getDisplayWidth(); rect.bottom = _vm->getDisplayInfo().statusY + _vm->getDisplayInfo().statusHeight; - drawRect(ds, &rect, _vm->getDisplayInfo().statusBGColor); + drawRect(backBuffer, &rect, _vm->getDisplayInfo().statusBGColor); string_w = _vm->_font->getStringWidth(SMALL_FONT_ID, _statusText, 0, 0); @@ -440,13 +448,12 @@ int Interface::drawStatusBar(SURFACE *ds) { else color = _statusOnceColor; - _vm->_font->draw(SMALL_FONT_ID, ds, _statusText, 0, (_vm->getDisplayInfo().statusWidth / 2) - (string_w / 2), + _vm->_font->draw(SMALL_FONT_ID, backBuffer, _statusText, 0, (_vm->getDisplayInfo().statusWidth / 2) - (string_w / 2), _vm->getDisplayInfo().statusY + _vm->getDisplayInfo().statusTextY, color, 0, 0); - return SUCCESS; } -void Interface::handleCommandClick(SURFACE *ds, const Point& mousePoint) { +void Interface::handleCommandClick(const Point& mousePoint) { PanelButton *panelButton; @@ -457,7 +464,7 @@ void Interface::handleCommandClick(SURFACE *ds, const Point& mousePoint) { } } -void Interface::handleCommandUpdate(SURFACE *ds, const Point& mousePoint) { +void Interface::handleCommandUpdate(const Point& mousePoint) { PanelButton *panelButton; panelButton = verbHitTest(mousePoint); @@ -489,10 +496,7 @@ PanelButton *Interface::verbHitTest(const Point& mousePoint) { 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; + _mainPanel.calcPanelButtonRect(panelButton, rect); if (rect.contains(mousePoint)) return panelButton; } @@ -554,7 +558,7 @@ void Interface::drawInventory() { drawPoint.y = y + row * height; _vm->_sprite->draw(back_buf, _vm->_sprite->_mainSprites, - _vm->_actor->getObj(_vm->_actor->objIndexToId(_inventory[i]))->spritelistRn, + _vm->_actor->getObj(_vm->_actor->objIndexToId(_inventory[i]))->spriteListResourceId, drawPoint, 256); if (++col >= _vm->getDisplayInfo().inventoryColumns) { @@ -642,6 +646,26 @@ void Interface::drawVerb(int verb, int state) { drawPanelButtonText(backBuffer, &_mainPanel, panelButton, textColor, _vm->getDisplayInfo().verbTextShadowColor); } +void Interface::drawPanelButtonArrow(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton) { + Point point; + int spriteNumber; + + if (panel->currentButton == panelButton) { + if (panelButton->flag != 0) { + spriteNumber = panelButton->downSpriteNumber; + } else { + spriteNumber = panelButton->overSpriteNumber; + } + } else { + spriteNumber = panelButton->upSpriteNumber; + } + + point.x = panel->x + panelButton->xOffset; + point.y = panel->y + panelButton->yOffset; + + _vm->_sprite->draw(ds, _vm->_sprite->_mainSprites, spriteNumber, point, 256); +} + void Interface::drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor) { const char *text; int textWidth; @@ -674,9 +698,10 @@ void Interface::converseInit(void) { void Interface::converseClear(void) { for (int i = 0; i < CONVERSE_MAX_TEXTS; i++) { - if (_converseText[i].text) + if (_converseText[i].text != NULL) { free(_converseText[i].text); - _converseText[i].text = NULL; + _converseText[i].text = NULL; + } _converseText[i].stringNum = -1; _converseText[i].replyId = 0; _converseText[i].replyFlags = 0; @@ -688,41 +713,39 @@ void Interface::converseClear(void) { _converseStartPos = 0; _converseEndPos = 0; _conversePos = -1; - - for (int i = 0; i < CONVERSE_TEXT_LINES; i++) { - _converseLastColors[0][i] = 0; - _converseLastColors[1][i] = 0; - } } bool Interface::converseAddText(const char *text, int replyId, byte replyFlags, int replyBit) { int count = 0; // count how many pieces of text per string - char temp[128]; + int i; + int len; + byte c; - assert(strlen(text) < 128); + assert(strlen(text) < CONVERSE_MAX_WORK_STRING); - strncpy(temp, text, 128); + strncpy(_converseWorkString, text, CONVERSE_MAX_WORK_STRING); while (1) { - int i; - int len = strlen(temp); + len = strlen(_converseWorkString); for (i = len; i >= 0; i--) { - byte c = temp[i]; + c = _converseWorkString[i]; if ((c == ' ' || c == '\0') - && _vm->_font->getStringWidth(SMALL_FONT_ID, temp, i, 0) + && _vm->_font->getStringWidth(SMALL_FONT_ID, _converseWorkString, i, 0) <= CONVERSE_MAX_TEXT_WIDTH) break; } - if (i < 0) + if (i < 0) { return true; + } - if (_converseTextCount == CONVERSE_MAX_TEXTS) + if (_converseTextCount == CONVERSE_MAX_TEXTS) { return true; + } _converseText[_converseTextCount].text = (char *)malloc(i + 1); - strncpy(_converseText[_converseTextCount].text, temp, i); + strncpy(_converseText[_converseTextCount].text, _converseWorkString, i); _converseText[_converseTextCount].text[i] = 0; _converseText[_converseTextCount].textNum = count; @@ -737,7 +760,7 @@ bool Interface::converseAddText(const char *text, int replyId, byte replyFlags, if (len == i) break; - strncpy(temp, &temp[i + 1], len - i); + strncpy(_converseWorkString, &_converseWorkString[i + 1], len - i); } _converseStrCount++; @@ -745,15 +768,10 @@ bool Interface::converseAddText(const char *text, int replyId, byte replyFlags, return false; } -void Interface::converseDisplayText(int pos) { - int end; +void Interface::converseDisplayText() { + int end; - if (pos >= _converseTextCount) - pos = _converseTextCount - 1; - if (pos < 0) - pos = 0; - - _converseStartPos = pos; + _converseStartPos = 0; end = _converseTextCount - CONVERSE_TEXT_LINES; @@ -761,93 +779,86 @@ void Interface::converseDisplayText(int pos) { end = 0; _converseEndPos = end; - - converseDisplayTextLine(kITEColorBrightWhite, false, true); + draw(); } -void Interface::converseSetTextLines(int row, int textcolor, bool btnDown) { - _conversePos = row + _converseStartPos; - if (_conversePos >= _converseTextCount) - _conversePos = -1; - - converseDisplayTextLine(textcolor, btnDown, false); +void Interface::converseSetTextLines(int row) { + int pos = row + _converseStartPos; + if (pos >= _converseTextCount) + pos = -1; + if (pos != _conversePos) { + _conversePos = pos; + draw(); + } } -void Interface::converseDisplayTextLine(int textcolor, bool btnDown, bool rebuild) { - int x = 52; // FIXME: remove hardcoded value - int y = 6; // FIXME: remove hardcoded value - int pos = _converseStartPos; - byte textcolors[2][CONVERSE_TEXT_LINES]; - SURFACE *ds; +void Interface::converseDisplayTextLines(SURFACE *ds) { + int relPos; + byte foregnd; + byte backgnd; + byte bulletForegnd; + byte bulletBackgnd; + const char *str; + char bullet[2] = { + (char)0xb7, 0 + }; + Point point; + Rect rect(8, CONVERSE_TEXT_LINES * CONVERSE_TEXT_HEIGHT); + + assert(_conversePanel.buttonsCount >= 6); - ds = _vm->_gfx->getBackBuffer(); // FIXME: probably best to move this out + bulletForegnd = kITEColorGreen; + bulletBackgnd = kITEColorBlack; + + rect.moveTo(_conversePanel.x + _conversePanel.buttons[0].xOffset, + _conversePanel.y + _conversePanel.buttons[0].yOffset); + drawRect(ds, &rect, kITEColorDarkGrey); //fill bullet place + for (int i = 0; i < CONVERSE_TEXT_LINES; i++) { - int relpos = pos + i; + relPos = _converseStartPos + i; - if (_conversePos >= 0 - && _converseText[_conversePos].stringNum - == _converseText[relpos].stringNum) { - textcolors[0][i] = textcolor; - textcolors[1][i] = (!btnDown) ? kITEColorDarkGrey : kITEColorGrey; - } else { - textcolors[0][i] = kITEColorBlue; - textcolors[1][i] = kITEColorDarkGrey; + if (_converseTextCount <= relPos) { + break; } - } - // if no colors have changed, exit - if (!rebuild && memcmp(textcolors, _converseLastColors, sizeof(textcolors)) == 0) - return; - - memcpy(_converseLastColors, textcolors, sizeof(textcolors)); - - Rect rect(8, CONVERSE_TEXT_LINES * CONVERSE_TEXT_HEIGHT); - int scrx = _conversePanel.x + x; - - rect.moveTo(_conversePanel.x + x, _conversePanel.y + y); - drawRect(ds, &rect, kITEColorDarkGrey); - - rect.top = rect.left = 0; - rect.right = CONVERSE_MAX_TEXT_WIDTH; - rect.bottom = CONVERSE_TEXT_HEIGHT; - - for (int i = 0; i < CONVERSE_TEXT_LINES; i++) { - byte foregnd = textcolors[0][i]; - byte backgnd = textcolors[1][i]; - int relpos = pos + i; - - rect.moveTo(_conversePanel.x + x + 7 + 1, - _conversePanel.y + y + i * CONVERSE_TEXT_HEIGHT); + if (_conversePos >= 0 && _converseText[_conversePos].stringNum == _converseText[relPos].stringNum) { + foregnd = kITEColorBrightWhite; + backgnd = (!_vm->leftMouseButtonPressed()) ? kITEColorDarkGrey : kITEColorGrey; + } else { + foregnd = kITEColorBlue; + backgnd = kITEColorDarkGrey; + } + _conversePanel.calcPanelButtonRect(&_conversePanel.buttons[i], rect); + rect.left += 8; drawRect(ds, &rect, backgnd); - if (_converseTextCount > i) { - const char *str = _converseText[relpos].text; - char bullet[] = { (char)0xb7, 0 }; - int scry = i * CONVERSE_TEXT_HEIGHT + _conversePanel.y + y; - byte tcolor, bcolor; - - if (_converseText[relpos].textNum == 0) { // first entry - tcolor = kITEColorGreen; - bcolor = kITEColorBlack; - _vm->_font->draw(SMALL_FONT_ID, ds, bullet, strlen(bullet), - scrx + 2, scry, tcolor, bcolor, FONT_SHADOW | FONT_DONTMAP); - } - _vm->_font->draw(SMALL_FONT_ID, ds, str, strlen(str), - scrx + 9, scry, foregnd, kITEColorBlack, FONT_SHADOW); + str = _converseText[relPos].text; + + if (_converseText[relPos].textNum == 0) { // first entry + _vm->_font->draw(SMALL_FONT_ID, ds, bullet, 1, + rect.left - 6, rect.top, bulletForegnd, bulletBackgnd, FONT_SHADOW | FONT_DONTMAP); } + _vm->_font->draw(SMALL_FONT_ID, ds, str, strlen(str), + rect.left + 1, rect.top, foregnd, kITEColorBlack, FONT_SHADOW); } - // FIXME: TODO: arrows + if (_converseStartPos != 0) { + drawPanelButtonArrow(ds, &_conversePanel, &_conversePanel.buttons[4]); + } + + if (_converseStartPos != _converseEndPos) { + drawPanelButtonArrow(ds, &_conversePanel, &_conversePanel.buttons[5]); + } } void Interface::converseChangePos(int chg) { if ((chg < 0 && _converseStartPos + chg >= 0) || (chg > 0 && _converseStartPos < _converseEndPos)) { _converseStartPos += chg; - converseDisplayTextLine(kITEColorBlue, false, true); + draw(); } } @@ -858,8 +869,7 @@ void Interface::converseSetPos(int key) { if (selection >= _converseTextCount) return; - // FIXME: wait until Andrew defines proper color - converseSetTextLines(selection, kITEColorBrightWhite, false); + converseSetTextLines(selection); ct = &_converseText[_conversePos]; @@ -870,5 +880,79 @@ void Interface::converseSetPos(int key) { _conversePos = -1; } +PanelButton *Interface::converseHitTest(const Point& mousePoint) { + PanelButton *panelButton; + Rect rect; + int i; + for (i = 0; i < _conversePanel.buttonsCount; i++) { + panelButton = &_conversePanel.buttons[i]; + if (panelButton != NULL) { + _conversePanel.calcPanelButtonRect(panelButton, rect); + if (rect.contains(mousePoint)) { + return panelButton; + } + } + } + + return NULL; +} + +void Interface::handleConverseUpdate(const Point& mousePoint) { + Rect rect; + bool changed; + + PanelButton *last = _conversePanel.currentButton; + + if (!_vm->mouseButtonPressed()) { // remove pressed flag + _conversePanel.buttons[4].flag = 0; + _conversePanel.buttons[5].flag = 0; + } + + _conversePanel.currentButton = converseHitTest(mousePoint); + changed = last != _conversePanel.currentButton; + + + if (_conversePanel.currentButton == NULL) { + _conversePos = -1; + if (changed) { + draw(); + } + return; + } + + if (_conversePanel.currentButton->type == kPanelButtonConverseText) { + converseSetTextLines(_conversePanel.currentButton->id); + } + + if (_conversePanel.currentButton->type == kPanelButtonArrow) { + if (_conversePanel.currentButton->flag == 1) { + //TODO: insert timeout catchup + converseChangePos((_conversePanel.currentButton->id == 0) ? -1 : 1); + } + draw(); + } +} + + +void Interface::handleConverseClick(const Point& mousePoint) { + Rect rect; + + _conversePanel.currentButton = converseHitTest(mousePoint); + + if (_conversePanel.currentButton == NULL) { + return; + } + + if (_conversePanel.currentButton->type == kPanelButtonConverseText) { + converseSetPos(_conversePanel.currentButton->keyChar); + } + + if (_conversePanel.currentButton->type == kPanelButtonArrow) { + _conversePanel.currentButton->flag = 1; + converseChangePos((_conversePanel.currentButton->id == 0) ? -1 : 1); + } + +} + } // End of namespace Saga diff --git a/saga/interface.h b/saga/interface.h index 4311c0f690..acc9c8bf98 100644 --- a/saga/interface.h +++ b/saga/interface.h @@ -49,6 +49,7 @@ enum InterfaceUpdateFlags { #define CONVERSE_MAX_TEXT_WIDTH (256 - 60) #define CONVERSE_TEXT_HEIGHT 10 #define CONVERSE_TEXT_LINES 4 +#define CONVERSE_MAX_WORK_STRING 128 enum PanelModes { kPanelNull, @@ -78,6 +79,13 @@ struct InterfacePanel { int buttonsCount; PanelButton *buttons; SpriteList sprites; + + void calcPanelButtonRect(const PanelButton* panelButton, Rect &rect) { + rect.left = x + panelButton->xOffset; + rect.right = rect.left + panelButton->width; + rect.top = y + panelButton->yOffset; + rect.bottom = rect.top + panelButton->height; + } }; @@ -106,7 +114,6 @@ enum ITEColors { class Interface { public: - bool _playfieldClicked; Interface(SagaEngine *vm); ~Interface(void); @@ -119,14 +126,13 @@ public: void rememberMode(); void restoreMode(); bool isInMainMode() { return _inMainMode; } - int setStatusText(const char *new_txt); - void setStatusOnceColor(int color) { _statusOnceColor = color; } + void setStatusText(const char *text, int statusColor = -1); int loadScenePortraits(int resourceId); int setLeftPortrait(int portrait); int setRightPortrait(int portrait); int draw(); int update(const Point& mousePoint, int updateFlag); - int drawStatusBar(SURFACE *ds); + void drawStatusBar(); void drawVerb(int verb, int state); bool processKeyCode(int keyCode); @@ -138,25 +144,29 @@ public: private: int inventoryTest(const Point& imousePt, int *ibutton); PanelButton *verbHitTest(const Point& mousePoint); - void handleCommandUpdate(SURFACE *ds, const Point& mousePoint); - void handleCommandClick(SURFACE *ds, const Point& mousePoint); + void handleCommandUpdate(const Point& mousePoint); + void handleCommandClick(const Point& mousePoint); + PanelButton *converseHitTest(const Point& mousePoint); + void handleConverseUpdate(const Point& mousePoint); + void handleConverseClick(const Point& mousePoint); void lockMode() { _lockedMode = _panelMode; } void unlockMode() { _panelMode = _lockedMode; } void drawPanelButtonText(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton, int textColor, int textShadowColor); + void drawPanelButtonArrow(SURFACE *ds, InterfacePanel *panel, PanelButton *panelButton); public: void converseInit(void); void converseClear(void); bool converseAddText(const char *text, int replyId, byte replyFlags, int replyBit); - void converseDisplayText(int pos); - void converseSetTextLines(int row, int textcolor, bool btnDown); + void converseDisplayText(); + void converseSetTextLines(int row); void converseChangePos(int chg); void converseSetPos(int key); private: - void converseDisplayTextLine(int textcolor, bool btnUp, bool rebuild); + void converseDisplayTextLines(SURFACE *ds); PanelButton *getPanelButtonByVerbType(int verb) { if ((verb < 0) || (verb >= kVerbTypesMax)) { error("Interface::getPanelButtonByVerbType wrong verb"); @@ -190,14 +200,13 @@ private: int _inventorySize; byte _inventoryCount; + char _converseWorkString[CONVERSE_MAX_WORK_STRING]; Converse _converseText[CONVERSE_MAX_TEXTS]; int _converseTextCount; int _converseStrCount; int _converseStartPos; int _converseEndPos; int _conversePos; - - byte _converseLastColors[2][CONVERSE_TEXT_LINES]; }; } // End of namespace Saga diff --git a/saga/render.cpp b/saga/render.cpp index d10c9e8671..93b4068eed 100644 --- a/saga/render.cpp +++ b/saga/render.cpp @@ -112,7 +112,7 @@ int Render::drawScene() { backbuf_surface = _backbuf_surface; // Get mouse coordinates - mouse_pt = _vm->getMousePos(); + mouse_pt = _vm->mousePos(); _vm->_scene->getBGInfo(&bg_info); bg_pt.x = 0; diff --git a/saga/saga.cpp b/saga/saga.cpp index 9aeba8cd8a..711542418f 100644 --- a/saga/saga.cpp +++ b/saga/saga.cpp @@ -116,6 +116,8 @@ SagaEngine *_vm = NULL; SagaEngine::SagaEngine(GameDetector *detector, OSystem *syst) : Engine(syst) { + _leftMouseButtonPressed = _rightMouseButtonPressed = false; + _console = NULL; _gameFileContexts = NULL; _quit = false; diff --git a/saga/saga.h b/saga/saga.h index 37ea016619..a789bc9cc7 100644 --- a/saga/saga.h +++ b/saga/saga.h @@ -139,7 +139,8 @@ enum HitZoneFlags { enum PanelButtonType { kPanelButtonVerb = 0, - kPanelButtonArrow = 1 + kPanelButtonArrow = 1, + kPanelButtonConverseText = 2 }; enum TextStringIds { @@ -311,6 +312,8 @@ struct PanelButton { int keyChar; int upSpriteNumber; int downSpriteNumber; + int overSpriteNumber; + int flag; }; struct GameDisplayInfo { @@ -348,6 +351,8 @@ struct GameDisplayInfo { int inventoryYSpacing; int mainPanelButtonsCount; PanelButton *mainPanelButtons; + int conversePanelButtonsCount; + PanelButton *conversePanelButtons; }; @@ -475,10 +480,26 @@ public: double percent); int processInput(void); - Point getMousePos(); + const Point &mousePos() const { + return _mousePos; + } + + const bool leftMouseButtonPressed() const { + return _leftMouseButtonPressed; + } + + const bool rightMouseButtonPressed() const { + return _rightMouseButtonPressed; + } + + const bool mouseButtonPressed() const { + return _leftMouseButtonPressed || _rightMouseButtonPressed; + } private: Point _mousePos; + bool _leftMouseButtonPressed; + bool _rightMouseButtonPressed; bool _quit; RSCFILE_CONTEXT **_gameFileContexts; diff --git a/saga/script.cpp b/saga/script.cpp index f1f6e13734..33390c6e1e 100644 --- a/saga/script.cpp +++ b/saga/script.cpp @@ -350,7 +350,7 @@ void Script::scriptExec(int argc, const char **argv) { } // verb -void Script::showVerb(int statuscolor) { +void Script::showVerb(int statusColor) { const char *verbName; const char *object1Name; const char *object2Name; @@ -365,7 +365,7 @@ void Script::showVerb(int statuscolor) { verbName = _mainStrings.getString(_leftButtonVerb - 1); if (objectTypeId(_currentObject[0]) == kGameObjectNone) { - _vm->_interface->setStatusText(verbName); + _vm->_interface->setStatusText(verbName, statusColor); return; } @@ -373,7 +373,7 @@ void Script::showVerb(int statuscolor) { if (!_secondObjectNeeded) { snprintf(statusString, STATUS_TEXT_LEN, "%s %s", verbName, object1Name); - _vm->_interface->setStatusText(statusString); + _vm->_interface->setStatusText(statusString, statusColor); return; } @@ -386,18 +386,16 @@ void Script::showVerb(int statuscolor) { if (_leftButtonVerb == kVerbGive) { snprintf(statusString, STATUS_TEXT_LEN, "Give %s to %s", object1Name, object2Name); - _vm->_interface->setStatusText(statusString); + _vm->_interface->setStatusText(statusString, statusColor); } else { if (_leftButtonVerb == kVerbUse) { snprintf(statusString, STATUS_TEXT_LEN, "Use %s with %s", object1Name, object2Name); - _vm->_interface->setStatusText(statusString); + _vm->_interface->setStatusText(statusString, statusColor); } else { snprintf(statusString, STATUS_TEXT_LEN, "%s %s", verbName, object1Name); - _vm->_interface->setStatusText(statusString); + _vm->_interface->setStatusText(statusString, statusColor); } } - if (statuscolor != -1) - _vm->_interface->setStatusOnceColor(statuscolor); } void Script::setVerb(int verb) { @@ -518,11 +516,9 @@ void Script::doVerb() { } void Script::setPointerVerb() { - Point mousePoint; - mousePoint = _vm->getMousePos(); if (_vm->_interface->isActive()) { _pointerObject = ID_PROTAG; - whichObject(mousePoint); + whichObject(_vm->mousePos()); } } @@ -689,7 +685,7 @@ void Script::whichObject(const Point& mousePoint) { if (_vm->_actor->_protagonist->currentAction == kActionWalkDir) { } else { - newObjectId = _vm->_actor->hitTest(mousePoint); + newObjectId = _vm->_actor->hitTest(mousePoint, true); if (newObjectId != ID_NOTHING) { if (objectTypeId(newObjectId) == kGameObjectObject) { diff --git a/saga/script.h b/saga/script.h index 7dc144e594..4fa8feb3d1 100644 --- a/saga/script.h +++ b/saga/script.h @@ -354,7 +354,7 @@ public: bool isVoiceLUTPresent() const { return _voiceLUTPresent; } void doVerb(); - void showVerb(int statuscolor = -1); + void showVerb(int statusColor = -1); void setVerb(int verb); int getCurrentVerb() const { return _currentVerb; } void setPointerVerb(); diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index 32bd103318..4a2eaf81e8 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -374,7 +374,8 @@ void Script::sfPreDialog(SCRIPTFUNC_PARAMS) { if (_vm->_interface->isInMainMode()) _vm->_interface->setMode(kPanelConverse); else - _vm->_interface->converseDisplayText(0); + _vm->_interface->converseDisplayText(); + _vm->_interface->setMode(kPanelNull); } @@ -748,7 +749,7 @@ void Script::SF_dropObject(SCRIPTFUNC_PARAMS) { } obj->sceneNumber = _vm->_scene->currentSceneNumber(); - obj->spritelistRn = 9 + sprite_param; + obj->spriteListResourceId = 9 + sprite_param; obj->location.x = x_param; obj->location.y = y_param; } diff --git a/saga/sthread.cpp b/saga/sthread.cpp index 6a591aae4a..dea95a6a14 100644 --- a/saga/sthread.cpp +++ b/saga/sthread.cpp @@ -654,6 +654,7 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) { _vm->_interface->activate(); _vm->_interface->setMode(kPanelConverse); thread->wait(kWaitTypeDialogEnd); + return false; } break; CASEOP(opReply) { -- cgit v1.2.3