- 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
This commit is contained in:
Andrew Kurushin 2005-01-13 22:42:49 +00:00
parent e97c689f8b
commit 326dd0c255
8 changed files with 471 additions and 373 deletions

View File

@ -41,31 +41,46 @@ namespace Saga {
static int detectGame(const FSList &fslist, bool mode = false); static int detectGame(const FSList &fslist, bool mode = false);
// ITE section // 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 = { static GameDisplayInfo ITE_DisplayInfo = {
320, 200, 320, 200, // logical width&height
35, 35, // scene path y offset
137, 137, // scene height
137, 137, // status y
320, 320, // status width
12, 12, // status height
2, 2, // status text y offset
186, 186, // status text color
15, 15, // status BG color
147, 147, // verb text color
15, 15, // verb text shadow color
96, 96, // verb text active color
5, 4, 5, 4, // left portrait x, y offset
274, 4, 274, 4, // right portrait x, y offset
181, 155, 181, 155, // inventory x, y
2, 4, 2, 4, // inventory rows, columns
29, 20, 29, 20, // inventory icon width, height
1, 0, 1, 0, // inventory icon x, y offset
3, 1 3, 1, // inventory x, y icon spacing
ARRAYSIZE(ITE_MainPanelButtons),
ITE_MainPanelButtons
}; };
static GameResourceDescription ITE_Resources = { static GameResourceDescription ITE_Resources = {
@ -177,6 +192,10 @@ static GameSoundInfo ITECD_GameSound = {
// IHNM section // IHNM section
static PanelButton IHNM_MainPanelButtons[] = {
{kPanelButtonVerb, 0, 0, 0, 0, kVerbWalkTo, ' ', 0, 0}, //TODO
};
static GameDisplayInfo IHNM_DisplayInfo = { static GameDisplayInfo IHNM_DisplayInfo = {
640, 480, 640, 480,
@ -201,7 +220,9 @@ static GameDisplayInfo IHNM_DisplayInfo = {
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0 0, 0,
ARRAYSIZE(IHNM_MainPanelButtons),
IHNM_MainPanelButtons
}; };
static GameResourceDescription IHNM_Resources = { static GameResourceDescription IHNM_Resources = {
@ -688,11 +709,6 @@ int SagaEngine::loadLanguage(void) {
test_file.close(); test_file.close();
if (_vm->_interface->registerLang() != SUCCESS) {
warning("Error registering interface language cvars");
return FAILURE;
}
if (_vm->_scene->ITEIntroRegisterLang() != SUCCESS) { if (_vm->_scene->ITEIntroRegisterLang() != SUCCESS) {
warning("Error registering intro sequence language cvars"); warning("Error registering intro sequence language cvars");
return FAILURE; return FAILURE;

View File

@ -82,20 +82,8 @@ int SagaEngine::processInput() {
case 'p': case 'p':
_render->toggleFlag(RF_RENDERPAUSE); _render->toggleFlag(RF_RENDERPAUSE);
break; 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: default:
_interface->processKeyCode(event.kbd.keycode);
break; break;
} }
break; break;

View File

@ -39,67 +39,29 @@
namespace Saga { namespace Saga {
static VERB_DATA I_VerbData[] = { static int verbTypeToTextStringsIdLUT[kVerbTypesMax] = {
{I_VERB_WALKTO, "verb_walkto", "Walk to", kVerbWalkTo}, -1,
{I_VERB_LOOKAT, "verb_lookat", "Look at", kVerbLookAt}, kTextPickUp,
{I_VERB_PICKUP, "verb_pickup", "Pick up", kVerbPickup}, kTextLookAt,
{I_VERB_TALKTO, "verb_talkto", "Talk to", kVerbSpeakTo}, kTextWalkTo,
{I_VERB_OPEN, "verb_open", "Open", kVerbOpen}, kTextTalkTo,
{I_VERB_CLOSE, "verb_close", "Close", kVerbClose}, kTextOpen,
{I_VERB_USE, "verb_use", "Use", kVerbUse}, kTextClose,
{I_VERB_GIVE, "verb_give", "Give", kVerbGive} 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) { Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
byte *resource;
size_t resourceLength;
int result; int result;
int i;
if (_initialized) { if (_initialized) {
return; return;
@ -107,71 +69,65 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
_iThread = _vm->_script->SThreadCreate(); _iThread = _vm->_script->SThreadCreate();
if (_iThread == NULL) { if (_iThread == NULL) {
warning("Interface::Interface(): Error creating script thread for game interface module"); error("Interface::Interface(): Error creating script thread for game interface module");
return;
} }
// Load interface module resource file context // Load interface module resource file context
_interfaceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0); _interfaceContext = _vm->getFileContext(GAME_RESOURCEFILE, 0);
if (_interfaceContext == NULL) { if (_interfaceContext == NULL) {
return; error("Interface::Interface(): unable to load resource");
}
// 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;
}
// Load command panel resource
result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->command_panel_rn, &_mainPanel.res, &_mainPanel.res_len);
if (result != SUCCESS) {
return;
}
// Load dialogue panel resource
result = RSC_LoadResource(_interfaceContext, _vm->getResourceDescription()->dialogue_panel_rn, &_conversePanel.res, &_conversePanel.res_len);
if (result != SUCCESS) {
return;
}
if (_vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, _mainPanel.sprites) != SUCCESS) {
error("Unable to load sprite list");
} }
_mainPanel.buttons = _vm->getDisplayInfo().mainPanelButtons;
_mainPanel.buttonsCount = _vm->getDisplayInfo().mainPanelButtonsCount;
for (i = 0; i < kVerbTypesMax; i++) {
_verbTypeToPanelButton[i] = NULL;
}
if (_vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, _defPortraits) != SUCCESS) { for (i = 0; i < _mainPanel.buttonsCount; i++) {
error("Unable to load sprite list"); if (_mainPanel.buttons[i].type == kPanelButtonVerb) {
_verbTypeToPanelButton[_mainPanel.buttons[i].id] = &_mainPanel.buttons[i];
}
}
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);
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) { //TODO: move constant to ResourceDescription
error("Interface::Interface(): 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.x = 0; //TODO: move constant to DisplayInfo
&_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.y = 149; _mainPanel.y = 149;
_mainPanel.currentButton = NULL;
_conversePanel.x = 0; _conversePanel.x = 0; //TODO: move constant to DisplayInfo
_conversePanel.y = 149; _conversePanel.y = 149;
_conversePanel.currentButton = NULL;
_mainPanel.set_button = 1;
_leftPortrait = 0; _leftPortrait = 0;
_rightPortrait = 0; _rightPortrait = 0;
_activeVerb = I_VERB_WALKTO;
_active = false; _active = false;
_panelMode = _lockedMode = kPanelNull; _panelMode = _lockedMode = kPanelNull;
_savedMode = -1; _savedMode = -1;
@ -183,7 +139,7 @@ Interface::Interface(SagaEngine *vm) : _vm(vm), _initialized(false) {
_inventory = (uint16 *)calloc(_inventorySize, sizeof(uint16)); _inventory = (uint16 *)calloc(_inventorySize, sizeof(uint16));
if (_inventory == NULL) { if (_inventory == NULL) {
return; error("Interface::Interface(): not enough memory");
} }
_initialized = true; _initialized = true;
@ -259,12 +215,47 @@ int Interface::setMode(int mode, bool force) {
} }
else else
_panelMode = newMode; _panelMode = newMode;
if (_panelMode == kPanelMain) {
_mainPanel.currentButton = NULL;
} else {
if (_panelMode == kPanelConverse) {
_conversePanel.currentButton = NULL;
}
}
draw(); draw();
return SUCCESS; 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) { int Interface::setStatusText(const char *new_txt) {
assert(new_txt != NULL); assert(new_txt != NULL);
@ -295,6 +286,7 @@ int Interface::setRightPortrait(int portrait) {
int Interface::draw() { int Interface::draw() {
SURFACE *backBuffer; SURFACE *backBuffer;
int i;
Point base; Point base;
Point leftPortraitPoint; Point leftPortraitPoint;
@ -314,32 +306,37 @@ int Interface::draw() {
base.y = _mainPanel.y; base.y = _mainPanel.y;
origin.x = 0; 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 { } else {
base.x = _conversePanel.x; base.x = _conversePanel.x;
base.y = _conversePanel.y; base.y = _conversePanel.y;
origin.x = 0; origin.x = 0;
origin.y = _vm->getDisplayHeight() - _mainPanel.img_h; origin.y = _vm->getDisplayHeight() - _mainPanel.imageHeight;
bufToSurface(backBuffer, _conversePanel.img, _conversePanel.img_w, bufToSurface(backBuffer, _conversePanel.image, _conversePanel.imageWidth,
_conversePanel.img_h, NULL, &origin); _conversePanel.imageHeight, NULL, &origin);
} }
if (_panelMode == kPanelMain || _panelMode == kPanelConverse || if (_panelMode == kPanelMain || _panelMode == kPanelConverse ||
_lockedMode == kPanelMain || _lockedMode == kPanelConverse) { _lockedMode == kPanelMain || _lockedMode == kPanelConverse) {
leftPortraitPoint.x = base.x + _vm->getDisplayInfo().leftPortraitX; leftPortraitPoint.x = base.x + _vm->getDisplayInfo().leftPortraitXOffset;
leftPortraitPoint.y = base.y + _vm->getDisplayInfo().leftPortraitY; leftPortraitPoint.y = base.y + _vm->getDisplayInfo().leftPortraitYOffset;
_vm->_sprite->draw(backBuffer, _defPortraits, _leftPortrait, leftPortraitPoint, 256); _vm->_sprite->draw(backBuffer, _defPortraits, _leftPortrait, leftPortraitPoint, 256);
} }
if (!_inMainMode && _vm->getDisplayInfo().rightPortraitX >= 0) { if (!_inMainMode && _vm->getDisplayInfo().rightPortraitXOffset >= 0) {
rightPortraitPoint.x = base.x + _vm->getDisplayInfo().rightPortraitX; rightPortraitPoint.x = base.x + _vm->getDisplayInfo().rightPortraitXOffset;
rightPortraitPoint.y = base.y + _vm->getDisplayInfo().rightPortraitY; rightPortraitPoint.y = base.y + _vm->getDisplayInfo().rightPortraitYOffset;
_vm->_sprite->draw(backBuffer, _scenePortraits, _rightPortrait, rightPortraitPoint, 256); _vm->_sprite->draw(backBuffer, _scenePortraits, _rightPortrait, rightPortraitPoint, 256);
} }
@ -350,40 +347,41 @@ int Interface::draw() {
return SUCCESS; return SUCCESS;
} }
int Interface::update(const Point& imousePt, int update_flag) { int Interface::update(const Point& imousePointer, int updateFlag) {
SURFACE *back_buf; SURFACE *backBuffer;
int imouse_x, imouse_y;
if (_vm->_scene->isInDemo() || _panelMode == kPanelFade) if (_vm->_scene->isInDemo() || _panelMode == kPanelFade)
return SUCCESS; return SUCCESS;
imouse_x = imousePt.x;
imouse_y = imousePt.y; backBuffer = _vm->_gfx->getBackBuffer();
back_buf = _vm->_gfx->getBackBuffer();
if (_panelMode == kPanelMain) { // FIXME: HACK if (_panelMode == kPanelMain) { // FIXME: HACK
// Update playfield space ( only if cursor is inside ) // Update playfield space ( only if cursor is inside )
if (imouse_y < _vm->getSceneHeight()) { if (imousePointer.y < _vm->getSceneHeight()) {
// Mouse is in playfield space // Mouse is in playfield space
if (update_flag == UPDATE_MOUSEMOVE) { if (updateFlag == UPDATE_MOUSEMOVE) {
handlePlayfieldUpdate(back_buf, imousePt); handlePlayfieldUpdate(backBuffer, imousePointer);
} else if (update_flag == UPDATE_MOUSECLICK) { } else {
handlePlayfieldClick(back_buf, imousePt); 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; return SUCCESS;
} }
@ -417,112 +415,40 @@ int Interface::drawStatusBar(SURFACE *ds) {
return SUCCESS; return SUCCESS;
} }
int Interface::handleCommandClick(SURFACE *ds, const Point& imousePt) { void Interface::handleCommandClick(SURFACE *ds, const Point& imousePointer) {
int hit_button;
int ibutton_num;
int x_base; PanelButton *panelButton;
int y_base;
Point button; panelButton = verbHitTest(imousePointer);
if (panelButton) {
int old_set_button; _vm->_script->setVerb(panelButton->id);
int set_button; return;
hit_button = hitTest(imousePt, &ibutton_num);
if (hit_button != SUCCESS) {
// Clicking somewhere other than a button doesn't do anything
return SUCCESS;
} }
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;
_vm->_sprite->draw(ds, _mainPanel.sprites, _mainPanel.buttons[set_button].
active_sprite - 1, button, 256);
}
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);
}
}
return SUCCESS;
} }
int Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePt) { void Interface::handleCommandUpdate(SURFACE *ds, const Point& imousePointer) {
int hit_button; PanelButton *panelButton;
int ibutton_num;
// int button_w = 0; panelButton = verbHitTest(imousePointer);
if (_mainPanel.currentButton != panelButton) {
/* int verb_idx = 0; if (_mainPanel.currentButton) {
int string_w = 0; drawVerb(_mainPanel.currentButton->id, 0);
int color; }
int i;*/ if (panelButton) {
drawVerb(panelButton->id, 1);
hit_button = inventoryTest(imousePt, &ibutton_num); }
}
_mainPanel.currentButton = panelButton;
if (panelButton) {
return;
}
/* hit_button = inventoryTest(imousePointer, &ibutton_num);
if (hit_button == SUCCESS) { if (hit_button == SUCCESS) {
// Hovering over an inventory object // Hovering over an inventory object
return SUCCESS; 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) { int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
@ -531,7 +457,7 @@ int Interface::handlePlayfieldClick(SURFACE *ds, const Point& imousePt) {
int objectNum; int objectNum;
uint16 object_flags = 0; uint16 object_flags = 0;
int script_num; // int script_num;
ActorLocation location; ActorLocation location;
objectNum = _vm->_scene->_objectMap->hitTest(imousePt); 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); object_flags = _vm->_scene->_objectMap->getFlags(objectNum);
if (object_flags & kHitZoneExit) { // FIXME. This is wrong 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 // Set active verb in script module
_vm->_script->putWord(4, 4, I_VerbData[_activeVerb].s_verb); _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) { if (script_num != 0) {
_vm->_script->SThreadExecute(_iThread, script_num); _vm->_script->SThreadExecute(_iThread, script_num);
} }
} }*/
} else { } else {
// Not a normal scene object - walk to it as if it weren't there // Not a normal scene object - walk to it as if it weren't there
location.fromScreenPoint(imousePt); location.fromScreenPoint(imousePt);
@ -603,31 +529,23 @@ int Interface::handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt) {
*/ */
} }
int Interface::hitTest(const Point& imousePt, int *ibutton) { PanelButton *Interface::verbHitTest(const Point& imousePointer) {
InterfaceButton *buttons; PanelButton *panelButton;
Rect rect;
int nbuttons;
int xbase;
int ybase;
int i; int i;
for (i = 0; i < kVerbTypesMax; i++) {
buttons = _mainPanel.buttons; panelButton = _verbTypeToPanelButton[i];
nbuttons = _mainPanel.nbuttons; if (panelButton != NULL) {
rect.left = _mainPanel.x + panelButton->xOffset;
xbase = _mainPanel.x; rect.right = rect.left + panelButton->width;
ybase = _mainPanel.y; rect.top = _mainPanel.y + panelButton->yOffset;
rect.bottom = rect.top + panelButton->height;
for (i = 0; i < nbuttons; i++) { if (rect.contains(imousePointer))
if ((imousePt.x >= (xbase + buttons[i].x1)) && (imousePt.x < (xbase + buttons[i].x2)) && return panelButton;
(imousePt.y >= (ybase + buttons[i].y1)) && (imousePt.y < (ybase + buttons[i].y2))) {
*ibutton = i;
return SUCCESS;
} }
} }
*ibutton = -1; return NULL;
return FAILURE;
} }
void Interface::addToInventory(int sprite) { void Interface::addToInventory(int sprite) {
@ -670,8 +588,8 @@ void Interface::drawInventory() {
int row = 0; int row = 0;
int col = 0; int col = 0;
int x = _vm->getDisplayInfo().inventoryX + _vm->getDisplayInfo().inventoryIconX; int x = _vm->getDisplayInfo().inventoryX + _vm->getDisplayInfo().inventoryIconXOffset;
int y = _vm->getDisplayInfo().inventoryY + _vm->getDisplayInfo().inventoryIconY; int y = _vm->getDisplayInfo().inventoryY + _vm->getDisplayInfo().inventoryIconYOffset;
int width = _vm->getDisplayInfo().inventoryIconWidth + _vm->getDisplayInfo().inventoryXSpacing; int width = _vm->getDisplayInfo().inventoryIconWidth + _vm->getDisplayInfo().inventoryXSpacing;
int height = _vm->getDisplayInfo().inventoryIconHeight + _vm->getDisplayInfo().inventoryYSpacing; int height = _vm->getDisplayInfo().inventoryIconHeight + _vm->getDisplayInfo().inventoryYSpacing;
Point drawPoint; Point drawPoint;
@ -726,6 +644,71 @@ int Interface::inventoryTest(const Point& imousePt, int *ibutton) {
} }
void Interface::drawVerb(int verb, int state) { 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 // Converse stuff

View File

@ -48,7 +48,7 @@ enum INTERFACE_UPDATE_FLAGS {
#define CONVERSE_TEXT_HEIGHT 10 #define CONVERSE_TEXT_HEIGHT 10
#define CONVERSE_TEXT_LINES 4 #define CONVERSE_TEXT_LINES 4
enum PANEL_MODES { enum PanelModes {
kPanelNull, kPanelNull,
kPanelMain, kPanelMain,
kPanelOption, kPanelOption,
@ -64,58 +64,21 @@ enum PANEL_MODES {
kPanelFade 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 { struct InterfacePanel {
byte *res;
size_t res_len;
int x; int x;
int y; int y;
byte *img; byte *image;
size_t img_len; size_t imageLength;
int img_w; int imageWidth;
int img_h; int imageHeight;
int set_button;//TODO: remove
int nbuttons; PanelButton *currentButton;
InterfaceButton *buttons; int buttonsCount;
PanelButton *buttons;
SpriteList sprites; 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 { struct Converse {
char *text; char *text;
@ -131,11 +94,10 @@ public:
Interface(SagaEngine *vm); Interface(SagaEngine *vm);
~Interface(void); ~Interface(void);
int registerLang();
int activate(); int activate();
int deactivate(); int deactivate();
int setMode(int mode, bool force = false); int setMode(int mode, bool force = false);
int getMode(void) { return _panelMode; } int getMode(void) const { return _panelMode; }
void rememberMode(); void rememberMode();
void restoreMode(); void restoreMode();
void lockMode() { _lockedMode = _panelMode; } void lockMode() { _lockedMode = _panelMode; }
@ -146,22 +108,25 @@ public:
int setLeftPortrait(int portrait); int setLeftPortrait(int portrait);
int setRightPortrait(int portrait); int setRightPortrait(int portrait);
int draw(); int draw();
int update(const Point& imousePointer, int updateFlag);
int drawStatusBar(SURFACE *ds); 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 addToInventory(int sprite);
void removeFromInventory(int sprite); void removeFromInventory(int sprite);
void drawInventory(); void drawInventory();
int inventoryTest(const Point& imousePt, int *ibutton);
private: private:
int hitTest(const Point& imousePt, int *ibutton); int inventoryTest(const Point& imousePt, int *ibutton);
int handleCommandUpdate(SURFACE *ds, const Point& imousePt); PanelButton *verbHitTest(const Point& imousePointer);
int handleCommandClick(SURFACE *ds, const Point& imousePt); void handleCommandUpdate(SURFACE *ds, const Point& imousePointer);
void handleCommandClick(SURFACE *ds, const Point& imousePointer);
int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt); int handlePlayfieldUpdate(SURFACE *ds, const Point& imousePt);
int handlePlayfieldClick(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: public:
void converseClear(void); void converseClear(void);
bool converseAddText(const char *text, int replyId, byte replyFlags, int replyBit); bool converseAddText(const char *text, int replyId, byte replyFlags, int replyBit);
@ -172,28 +137,33 @@ public:
private: private:
void converseDisplayTextLine(int textcolor, bool btnUp, bool rebuild); 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: private:
SagaEngine *_vm; SagaEngine *_vm;
bool _initialized; bool _initialized;
bool _active;
RSCFILE_CONTEXT *_interfaceContext; RSCFILE_CONTEXT *_interfaceContext;
InterfacePanel _mainPanel;
InterfacePanel _conversePanel;
SpriteList _defPortraits;
SpriteList _scenePortraits;
SCRIPT_THREAD *_iThread;
PanelButton *_verbTypeToPanelButton[kVerbTypesMax];
bool _active;
int _panelMode; int _panelMode;
int _savedMode; int _savedMode;
int _lockedMode; int _lockedMode;
bool _inMainMode; bool _inMainMode;
InterfacePanel _mainPanel;
InterfacePanel _conversePanel;
char _statusText[STATUS_TEXT_LEN]; char _statusText[STATUS_TEXT_LEN];
int _leftPortrait; int _leftPortrait;
int _rightPortrait; int _rightPortrait;
SpriteList _defPortraits;
SpriteList _scenePortraits;
int _activeVerb;
SCRIPT_THREAD *_iThread;
uint16 *_inventory; uint16 *_inventory;
int _inventorySize; int _inventorySize;
byte _inventoryCount; byte _inventoryCount;

View File

@ -60,6 +60,48 @@ static const GameSettings saga_games[] = {
{0, 0, 0} {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 Engine_SAGA_gameList() {
GameList games; GameList games;
const GameSettings *g = saga_games; const GameSettings *g = saga_games;
@ -333,4 +375,9 @@ const char *SagaEngine::getObjectName(uint16 objectId) {
return NULL; return NULL;
} }
const char *SagaEngine::getTextString(int textStringId) {
return englishTextStrings[textStringId]; //TODO: i18n
}
} // End of namespace Saga } // End of namespace Saga

View File

@ -99,7 +99,7 @@ enum GameObjectTypes {
kGameObjectStepZone = 4 kGameObjectStepZone = 4
}; };
enum scriptTimings { enum ScriptTimings {
kScriptTimeTicksPerSecond = (728L/10L), kScriptTimeTicksPerSecond = (728L/10L),
kRepeatSpeed = 40, // 25 frames/sec kRepeatSpeed = 40, // 25 frames/sec
kNormalFadeDuration = 320, // 64 steps, 5 msec each kNormalFadeDuration = 320, // 64 steps, 5 msec each
@ -131,6 +131,52 @@ enum HitZoneFlags {
kHitZoneTerminus = (1 << 3) 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 { struct IMAGE_HEADER {
int width; int width;
@ -236,8 +282,8 @@ struct GameFontDescription {
struct GameResourceDescription { struct GameResourceDescription {
uint32 scene_lut_rn; uint32 scene_lut_rn;
uint32 script_lut_rn; uint32 script_lut_rn;
uint32 command_panel_rn; uint32 mainPanelResourceId;
uint32 dialogue_panel_rn; uint32 conversePanelResourceId;
}; };
struct GameFileDescription { struct GameFileDescription {
@ -245,6 +291,18 @@ struct GameFileDescription {
uint16 fileType; uint16 fileType;
}; };
struct PanelButton {
PanelButtonType type;
int xOffset;
int yOffset;
int width;
int height;
int id;
int keyChar;
int upSpriteNumber;
int downSpriteNumber;
};
struct GameDisplayInfo { struct GameDisplayInfo {
int logicalWidth; int logicalWidth;
int logicalHeight; int logicalHeight;
@ -263,10 +321,10 @@ struct GameDisplayInfo {
int verbTextShadowColor; int verbTextShadowColor;
int verbTextActiveColor; int verbTextActiveColor;
int leftPortraitX; int leftPortraitXOffset;
int leftPortraitY; int leftPortraitYOffset;
int rightPortraitX; int rightPortraitXOffset;
int rightPortraitY; int rightPortraitYOffset;
int inventoryX; int inventoryX;
int inventoryY; int inventoryY;
@ -274,12 +332,15 @@ struct GameDisplayInfo {
int inventoryColumns; int inventoryColumns;
int inventoryIconWidth; int inventoryIconWidth;
int inventoryIconHeight; int inventoryIconHeight;
int inventoryIconX; int inventoryIconXOffset;
int inventoryIconY; int inventoryIconYOffset;
int inventoryXSpacing; int inventoryXSpacing;
int inventoryYSpacing; int inventoryYSpacing;
int mainPanelButtonsCount;
PanelButton *mainPanelButtons;
}; };
struct GameDescription { struct GameDescription {
const char *name; const char *name;
SAGAGameType gameType; SAGAGameType gameType;
@ -433,6 +494,8 @@ public:
int getDisplayHeight() const { return _gameDisplayInfo.logicalHeight;} int getDisplayHeight() const { return _gameDisplayInfo.logicalHeight;}
int getSceneHeight() const { return _gameDisplayInfo.sceneHeight; } int getSceneHeight() const { return _gameDisplayInfo.sceneHeight; }
const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; } const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; }
const char *getTextString(int textStringId);
private: private:
int loadLanguage(void); int loadLanguage(void);
int loadGame(int gameNumber); int loadGame(int gameNumber);

View File

@ -613,6 +613,31 @@ void Script::setVerb(int verb) {
} }
void Script::setLeftButtonVerb(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() { void Script::doVerb() {

View File

@ -54,10 +54,10 @@ typedef unsigned int ScriptDataWord;
enum VerbTypes { enum VerbTypes {
//todo: LUT for drawing //todo: LUT for drawing
kVerbNone = 0, kVerbNone = 0,
kVerbPickup = 1, kVerbPickUp = 1,
kVerbLookAt = 2, kVerbLookAt = 2,
kVerbWalkTo = 3, kVerbWalkTo = 3,
kVerbSpeakTo = 4, kVerbTalkTo = 4,
kVerbOpen = 5, kVerbOpen = 5,
kVerbClose = 6, kVerbClose = 6,
kVerbGive = 7, kVerbGive = 7,
@ -67,7 +67,9 @@ enum VerbTypes {
kVerbLeave = 11, kVerbLeave = 11,
kVerbBegin = 12, kVerbBegin = 12,
kVerbWalkOnly = 13, kVerbWalkOnly = 13,
kVerbLookOnly = 14 kVerbLookOnly = 14,
kVerbTypesMax = kVerbLookOnly + 1
}; };
#define STHREAD_TIMESLICE 8 #define STHREAD_TIMESLICE 8
@ -250,6 +252,10 @@ public:
void showVerb(); void showVerb();
void setVerb(int verb); void setVerb(int verb);
void setLeftButtonVerb(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 scriptInfo();
void scriptExec(int argc, const char **argv); void scriptExec(int argc, const char **argv);