aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2005-04-18 20:03:14 +0000
committerAndrew Kurushin2005-04-18 20:03:14 +0000
commitd52032c75c4c3964219874d68ec9a84dc8e6f3fa (patch)
treec66544dde7b5bf7bbbaf991b369c048411a2492e
parent3ea96a13a053e803435e93b20cf07d01d0c3d821 (diff)
downloadscummvm-rg350-d52032c75c4c3964219874d68ec9a84dc8e6f3fa.tar.gz
scummvm-rg350-d52032c75c4c3964219874d68ec9a84dc8e6f3fa.tar.bz2
scummvm-rg350-d52032c75c4c3964219874d68ec9a84dc8e6f3fa.zip
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
-rw-r--r--saga/actor.cpp11
-rw-r--r--saga/actor.h7
-rw-r--r--saga/events.cpp4
-rw-r--r--saga/game.cpp25
-rw-r--r--saga/input.cpp26
-rw-r--r--saga/interface.cpp356
-rw-r--r--saga/interface.h31
-rw-r--r--saga/render.cpp2
-rw-r--r--saga/saga.cpp2
-rw-r--r--saga/saga.h25
-rw-r--r--saga/script.cpp20
-rw-r--r--saga/script.h2
-rw-r--r--saga/sfuncs.cpp5
-rw-r--r--saga/sthread.cpp1
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<CommonObjectDataPointer> 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) {