aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
authorAndrew Kurushin2005-01-13 22:42:49 +0000
committerAndrew Kurushin2005-01-13 22:42:49 +0000
commit326dd0c2553db220283cda1403c77bc0870f7451 (patch)
treeed32eec8ad09f04ae4b820e1692b53a58983f1b4 /saga
parente97c689f8bcbc925c02196b0596e9749a2533e88 (diff)
downloadscummvm-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.cpp72
-rw-r--r--saga/input.cpp14
-rw-r--r--saga/interface.cpp481
-rw-r--r--saga/interface.h102
-rw-r--r--saga/saga.cpp47
-rw-r--r--saga/saga.h81
-rw-r--r--saga/script.cpp25
-rw-r--r--saga/script.h12
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);