aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorbjörn Andersson2005-04-24 12:13:03 +0000
committerTorbjörn Andersson2005-04-24 12:13:03 +0000
commit5553ef53f191ae190fcd6c35c430e61d665bae44 (patch)
tree70b96175820eaad9060429330f29187d82201c66
parent6f29b92a5fa765ae3adb270035aeb104c2a9765d (diff)
downloadscummvm-rg350-5553ef53f191ae190fcd6c35c430e61d665bae44.tar.gz
scummvm-rg350-5553ef53f191ae190fcd6c35c430e61d665bae44.tar.bz2
scummvm-rg350-5553ef53f191ae190fcd6c35c430e61d665bae44.zip
Moved conversation stuff from Logic to Mouse.
svn-id: r17787
-rw-r--r--sword2/function.cpp126
-rw-r--r--sword2/icons.cpp21
-rw-r--r--sword2/logic.cpp4
-rw-r--r--sword2/logic.h20
-rw-r--r--sword2/mouse.cpp121
-rw-r--r--sword2/mouse.h25
-rw-r--r--sword2/speech.h29
-rw-r--r--sword2/sword2.cpp4
8 files changed, 172 insertions, 178 deletions
diff --git a/sword2/function.cpp b/sword2/function.cpp
index a80ffa7f0b..37affd9923 100644
--- a/sword2/function.cpp
+++ b/sword2/function.cpp
@@ -146,26 +146,7 @@ int32 Logic::fnPreLoad(int32 *params) {
int32 Logic::fnAddSubject(int32 *params) {
// params: 0 id
// 1 daves reference number
-
- if (_scriptVars[IN_SUBJECT] == 0) {
- // This is the start of the new subject list. Set the default
- // repsonse id to zero in case we're never passed one.
- _defaultResponseId = 0;
- }
-
- if (params[0] == -1) {
- // Id -1 is used for setting the default response, i.e. the
- // response when someone uses an object on a person and he
- // doesn't know anything about it. See fnChoose() below.
-
- _defaultResponseId = params[1];
- } else {
- debug(5, "fnAddSubject res %d, uid %d", params[0], params[1]);
- _subjectList[_scriptVars[IN_SUBJECT]].res = params[0];
- _subjectList[_scriptVars[IN_SUBJECT]].ref = params[1];
- _scriptVars[IN_SUBJECT]++;
- }
-
+ _vm->_mouse->addSubject(params[0], params[1]);
return IR_CONT;
}
@@ -194,109 +175,12 @@ int32 Logic::fnChoose(int32 *params) {
// values, to be used with the CP_JUMP_ON_RETURNED opcode. As far as I
// can tell, this is the only function that uses that feature.
- uint i;
-
- _scriptVars[AUTO_SELECTED] = 0;
-
- if (_scriptVars[OBJECT_HELD]) {
- // The player used an object on a person. In this case it
- // triggered a conversation menu. Act as if the user tried to
- // talk to the person about that object. If the person doesn't
- // know anything about it, use the default response.
-
- uint32 response = _defaultResponseId;
-
- for (i = 0; i < _scriptVars[IN_SUBJECT]; i++) {
- if (_subjectList[i].res == _scriptVars[OBJECT_HELD]) {
- response = _subjectList[i].ref;
- break;
- }
- }
-
- // The user won't be holding the object any more, and the
- // conversation menu will be closed.
-
- _scriptVars[OBJECT_HELD] = 0;
- _scriptVars[IN_SUBJECT] = 0;
- return IR_CONT | (response << 3);
- }
-
- if (_scriptVars[CHOOSER_COUNT_FLAG] == 0 && _scriptVars[IN_SUBJECT] == 1 && _subjectList[0].res == EXIT_ICON) {
- // This is the first time the chooser is coming up in this
- // conversation, there is only one subject and that's the
- // EXIT icon.
- //
- // In other words, the player doesn't have anything to talk
- // about. Skip it.
-
- // The conversation menu will be closed. We set AUTO_SELECTED
- // because the speech script depends on it.
-
- _scriptVars[AUTO_SELECTED] = 1;
- _scriptVars[IN_SUBJECT] = 0;
- return IR_CONT | (_subjectList[0].ref << 3);
- }
-
- byte *icon;
-
- if (!_choosing) {
- // This is a new conversation menu.
+ uint32 response = _vm->_mouse->chooseMouse();
- if (!_scriptVars[IN_SUBJECT])
- error("fnChoose with no subjects");
-
- for (i = 0; i < _scriptVars[IN_SUBJECT]; i++) {
- icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(StandardHeader) + RDMENU_ICONWIDE * RDMENU_ICONDEEP;
- _vm->_mouse->setMenuIcon(RDMENU_BOTTOM, i, icon);
- _vm->_resman->closeResource(_subjectList[i].res);
- }
-
- for (; i < 15; i++)
- _vm->_mouse->setMenuIcon(RDMENU_BOTTOM, (uint8) i, NULL);
-
- _vm->_mouse->showMenu(RDMENU_BOTTOM);
- _vm->_mouse->setMouse(NORMAL_MOUSE_ID);
- _choosing = true;
- return IR_REPEAT;
- }
-
- // The menu is there - we're just waiting for a click. We only care
- // about left clicks.
-
- MouseEvent *me = _vm->mouseEvent();
- int mouseX, mouseY;
-
- _vm->_mouse->getPos(mouseX, mouseY);
-
- if (!me || !(me->buttons & RD_LEFTBUTTONDOWN) || mouseY < 400)
- return IR_REPEAT;
-
- // Check for click on a menu.
-
- int hit = _vm->_mouse->menuClick(_scriptVars[IN_SUBJECT]);
- if (hit < 0)
+ if (response == (uint32) -1)
return IR_REPEAT;
- // Hilight the clicked icon by greying the others.
-
- for (i = 0; i < _scriptVars[IN_SUBJECT]; i++) {
- if ((int) i != hit) {
- icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(StandardHeader);
- _vm->_mouse->setMenuIcon(RDMENU_BOTTOM, i, icon);
- _vm->_resman->closeResource(_subjectList[i].res);
- }
- }
-
- // For non-speech scripts that manually call the chooser
- _scriptVars[RESULT] = _subjectList[hit].res;
-
- // The conversation menu will be closed
-
- _choosing = false;
- _scriptVars[IN_SUBJECT] = 0;
- _vm->_mouse->setMouse(0);
-
- return IR_CONT | (_subjectList[hit].ref << 3);
+ return IR_CONT | (response << 3);
}
/**
@@ -3255,7 +3139,7 @@ int32 Logic::fnPlayCredits(int32 *params) {
screenInfo->new_palette = 99;
- if (!_vm->_mouse->getMouseStatus() || _choosing)
+ if (!_vm->_mouse->getMouseStatus() || _vm->_mouse->isChoosing())
_vm->_mouse->setMouse(NORMAL_MOUSE_ID);
if (_scriptVars[DEAD])
diff --git a/sword2/icons.cpp b/sword2/icons.cpp
index ab28e94efd..399d40c903 100644
--- a/sword2/icons.cpp
+++ b/sword2/icons.cpp
@@ -33,6 +33,27 @@ void Mouse::addMenuObject(MenuObject *obj) {
_totalTemp++;
}
+void Mouse::addSubject(int32 id, int32 ref) {
+ if (Logic::_scriptVars[IN_SUBJECT] == 0) {
+ // This is the start of the new subject list. Set the default
+ // repsonse id to zero in case we're never passed one.
+ _defaultResponseId = 0;
+ }
+
+ if (id == -1) {
+ // Id -1 is used for setting the default response, i.e. the
+ // response when someone uses an object on a person and he
+ // doesn't know anything about it. See fnChoose().
+
+ _defaultResponseId = ref;
+ } else {
+ debug(5, "fnAddSubject res %d, uid %d", id, ref);
+ _subjectList[Logic::_scriptVars[IN_SUBJECT]].res = id;
+ _subjectList[Logic::_scriptVars[IN_SUBJECT]].ref = ref;
+ Logic::_scriptVars[IN_SUBJECT]++;
+ }
+}
+
/**
* Create and start the inventory (bottom) menu
*/
diff --git a/sword2/logic.cpp b/sword2/logic.cpp
index 5922d92830..c286b2f9b7 100644
--- a/sword2/logic.cpp
+++ b/sword2/logic.cpp
@@ -34,11 +34,9 @@ Logic::Logic(Sword2Engine *vm) :
_vm(vm), _kills(0), _currentRunList(0), _smackerLeadIn(0),
_smackerLeadOut(0), _sequenceTextLines(0), _speechTime(0), _animId(0),
_speechAnimType(0), _leftClickDelay(0), _rightClickDelay(0),
- _defaultResponseId(0), _officialTextNumber(0), _speechTextBlocNo(0),
- _choosing(false) {
+ _officialTextNumber(0), _speechTextBlocNo(0) {
_scriptVars = NULL;
- memset(_subjectList, 0, sizeof(_subjectList));
memset(_eventList, 0, sizeof(_eventList));
memset(_syncList, 0, sizeof(_syncList));
_router = new Router(_vm);
diff --git a/sword2/logic.h b/sword2/logic.h
index a23aa10a9e..426c2a2745 100644
--- a/sword2/logic.h
+++ b/sword2/logic.h
@@ -23,8 +23,6 @@
#ifndef _LOGIC
#define _LOGIC
-#include "sword2/speech.h"
-
namespace Sword2 {
struct MovieTextObject;
@@ -98,15 +96,6 @@ private:
void createSequenceSpeech(MovieTextObject *sequenceText[]);
void clearSequenceSpeech(MovieTextObject *sequenceText[]);
- // array of these for subject menu build up
-
- struct SubjectUnit {
- uint32 res;
- uint32 ref;
- };
-
- SubjectUnit _subjectList[MAX_SUBJECT_LIST];
-
// when not playing a wav we calculate the speech time based upon
// length of ascii
@@ -120,12 +109,6 @@ private:
uint32 _leftClickDelay; // click-delay for LEFT mouse button
uint32 _rightClickDelay; // click-delay for RIGHT mouse button
- // ref number for default response when luggage icon is used on a
- // person & it doesn't match any of the icons which would have been in
- // the chooser
-
- uint32 _defaultResponseId;
-
// calculated by locateTalker() for use in speech-panning & text-sprite
// positioning
@@ -161,9 +144,6 @@ public:
// so speech text cleared when running a new start-script
uint32 _speechTextBlocNo;
- // could alternately use logic->looping of course
- bool _choosing;
-
int runScript(char *scriptData, char *objectData, uint32 *offset);
void sendEvent(uint32 id, uint32 interact_id);
diff --git a/sword2/mouse.cpp b/sword2/mouse.cpp
index 98d09635cb..176ae7579a 100644
--- a/sword2/mouse.cpp
+++ b/sword2/mouse.cpp
@@ -85,6 +85,10 @@ Mouse::Mouse(Sword2Engine *vm) {
_totalMasters = 0;
memset(_masterMenuList, 0, sizeof(_masterMenuList));
memset(_mouseList, 0, sizeof(_mouseList));
+ memset(_subjectList, 0, sizeof(_subjectList));
+
+ _defaultResponseId = 0;
+ _choosing = false;
_iconCount = 0;
@@ -253,7 +257,7 @@ int Mouse::menuClick(int menu_items) {
return (_pos.x - RDMENU_ICONSTART) / (RDMENU_ICONWIDE + RDMENU_ICONSPACING);
}
-void Mouse::systemMenuMouse(void) {
+void Mouse::systemMenuMouse() {
uint32 safe_looping_music_id;
MouseEvent *me;
int hit;
@@ -400,7 +404,7 @@ void Mouse::systemMenuMouse(void) {
_vm->_logic->fnStopMusic(NULL);
}
-void Mouse::dragMouse(void) {
+void Mouse::dragMouse() {
byte buf1[NAME_LEN], buf2[NAME_LEN];
MouseEvent *me;
int hit;
@@ -602,7 +606,7 @@ void Mouse::menuMouse() {
}
}
-void Mouse::normalMouse(void) {
+void Mouse::normalMouse() {
// The gane is playing and none of the menus are activated - but, we
// need to check if a menu is to start. Note, won't have luggage
@@ -821,6 +825,117 @@ void Mouse::normalMouse(void) {
}
}
+uint32 Mouse::chooseMouse() {
+ // Unlike the other mouse "engines", this one is called directly by the
+ // fnChoose() opcode.
+
+ uint i;
+
+ Logic::_scriptVars[AUTO_SELECTED] = 0;
+
+ if (Logic::_scriptVars[OBJECT_HELD]) {
+ // The player used an object on a person. In this case it
+ // triggered a conversation menu. Act as if the user tried to
+ // talk to the person about that object. If the person doesn't
+ // know anything about it, use the default response.
+
+ uint32 response = _defaultResponseId;
+
+ for (i = 0; i < Logic::_scriptVars[IN_SUBJECT]; i++) {
+ if (_subjectList[i].res == Logic::_scriptVars[OBJECT_HELD]) {
+ response = _subjectList[i].ref;
+ break;
+ }
+ }
+
+ // The user won't be holding the object any more, and the
+ // conversation menu will be closed.
+
+ Logic::_scriptVars[OBJECT_HELD] = 0;
+ Logic::_scriptVars[IN_SUBJECT] = 0;
+ return response;
+ }
+
+ if (Logic::_scriptVars[CHOOSER_COUNT_FLAG] == 0 && Logic::_scriptVars[IN_SUBJECT] == 1 && _subjectList[0].res == EXIT_ICON) {
+ // This is the first time the chooser is coming up in this
+ // conversation, there is only one subject and that's the
+ // EXIT icon.
+ //
+ // In other words, the player doesn't have anything to talk
+ // about. Skip it.
+
+ // The conversation menu will be closed. We set AUTO_SELECTED
+ // because the speech script depends on it.
+
+ Logic::_scriptVars[AUTO_SELECTED] = 1;
+ Logic::_scriptVars[IN_SUBJECT] = 0;
+ return _subjectList[0].ref;
+ }
+
+ byte *icon;
+
+ if (!_choosing) {
+ // This is a new conversation menu.
+
+ if (!Logic::_scriptVars[IN_SUBJECT])
+ error("fnChoose with no subjects");
+
+ for (i = 0; i < Logic::_scriptVars[IN_SUBJECT]; i++) {
+ icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(StandardHeader) + RDMENU_ICONWIDE * RDMENU_ICONDEEP;
+ setMenuIcon(RDMENU_BOTTOM, i, icon);
+ _vm->_resman->closeResource(_subjectList[i].res);
+ }
+
+ for (; i < 15; i++)
+ setMenuIcon(RDMENU_BOTTOM, (uint8) i, NULL);
+
+ showMenu(RDMENU_BOTTOM);
+ setMouse(NORMAL_MOUSE_ID);
+ _choosing = true;
+ return (uint32) -1;
+ }
+
+ // The menu is there - we're just waiting for a click. We only care
+ // about left clicks.
+
+ MouseEvent *me = _vm->mouseEvent();
+ int mouseX, mouseY;
+
+ getPos(mouseX, mouseY);
+
+ if (!me || !(me->buttons & RD_LEFTBUTTONDOWN) || mouseY < 400)
+ return (uint32) -1;
+
+ // Check for click on a menu.
+
+ int hit = _vm->_mouse->menuClick(Logic::_scriptVars[IN_SUBJECT]);
+ if (hit < 0)
+ return (uint32) -1;
+
+ // Hilight the clicked icon by greying the others. This can look a bit
+ // odd when you click on the exit icon, but there are also cases when
+ // it looks strange if you don't do it.
+
+ for (i = 0; i < Logic::_scriptVars[IN_SUBJECT]; i++) {
+ if ((int) i != hit) {
+ icon = _vm->_resman->openResource(_subjectList[i].res) + sizeof(StandardHeader);
+ _vm->_mouse->setMenuIcon(RDMENU_BOTTOM, i, icon);
+ _vm->_resman->closeResource(_subjectList[i].res);
+ }
+ }
+
+ // For non-speech scripts that manually call the chooser
+ Logic::_scriptVars[RESULT] = _subjectList[hit].res;
+
+ // The conversation menu will be closed
+
+ _choosing = false;
+ Logic::_scriptVars[IN_SUBJECT] = 0;
+ setMouse(0);
+
+ return _subjectList[hit].ref;
+}
+
void Mouse::mouseOnOff() {
// this handles the cursor graphic when moving on and off mouse areas
// it also handles the luggage thingy
diff --git a/sword2/mouse.h b/sword2/mouse.h
index 54ead36198..d2fc2bdb03 100644
--- a/sword2/mouse.h
+++ b/sword2/mouse.h
@@ -21,6 +21,8 @@
#ifndef MOUSE_H
#define MOUSE_H
+#define MAX_SUBJECT_LIST 30 // is that enough?
+
#define TOTAL_mouse_list 50
namespace Sword2 {
@@ -99,6 +101,13 @@ struct MouseUnit {
int32 pointer_text;
};
+// Array of these for subject menu build up
+
+ struct SubjectUnit {
+ uint32 res;
+ uint32 ref;
+};
+
class Mouse {
private:
Sword2Engine *_vm;
@@ -114,6 +123,17 @@ private:
MenuObject _masterMenuList[TOTAL_engine_pockets];
uint32 _totalMasters;
+ SubjectUnit _subjectList[MAX_SUBJECT_LIST];
+
+ // ref number for default response when luggage icon is used on a
+ // person & it doesn't match any of the icons which would have been in
+ // the chooser
+
+ uint32 _defaultResponseId;
+
+ // could alternately use logic->looping of course
+ bool _choosing;
+
uint8 _menuStatus[2];
byte *_icons[2][RDMENU_MAXPOCKETS];
uint8 _pocketStatus[2][RDMENU_MAXPOCKETS];
@@ -200,6 +220,8 @@ public:
void processMenu();
void addMenuObject(MenuObject *obj);
+ void addSubject(int32 id, int32 ref);
+
void buildMenu();
void buildSystemMenu();
@@ -231,6 +253,9 @@ public:
void dragMouse();
void systemMenuMouse();
+ bool isChoosing() { return _choosing; }
+ uint32 chooseMouse();
+
int menuClick(int menu_items);
};
diff --git a/sword2/speech.h b/sword2/speech.h
deleted file mode 100644
index 49ae49f3f9..0000000000
--- a/sword2/speech.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (C) 1994-1998 Revolution Software Ltd.
- * Copyright (C) 2003-2005 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- */
-
-#ifndef _SPEECH
-#define _SPEECH
-
-#define MAX_SUBJECT_LIST 30 // is that enough?
-
-namespace Sword2 {
-} // End of namespace Sword2
-
-#endif
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 2603f09bfb..20b75998a8 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -331,7 +331,7 @@ int Sword2Engine::go() {
pauseGame();
break;
case 'c':
- if (!Logic::_scriptVars[DEMO] && !_logic->_choosing)
+ if (!Logic::_scriptVars[DEMO] && !_mouse->isChoosing())
_logic->fnPlayCredits(NULL);
break;
#ifdef SWORD2_DEBUG
@@ -658,7 +658,7 @@ void Sword2Engine::unpauseGame() {
_gamePaused = false;
// If mouse is about or we're in a chooser menu
- if (!_mouse->getMouseStatus() || _logic->_choosing)
+ if (!_mouse->getMouseStatus() || _mouse->isChoosing())
_mouse->setMouse(NORMAL_MOUSE_ID);
}