diff options
| -rw-r--r-- | engines/lure/debugger.cpp | 6 | ||||
| -rw-r--r-- | engines/lure/game.cpp | 41 | ||||
| -rw-r--r-- | engines/lure/luredefs.h | 6 | ||||
| -rw-r--r-- | engines/lure/menu.cpp | 54 | ||||
| -rw-r--r-- | engines/lure/menu.h | 11 | ||||
| -rw-r--r-- | engines/lure/res.cpp | 6 | ||||
| -rw-r--r-- | engines/lure/res.h | 4 | ||||
| -rw-r--r-- | engines/lure/res_struct.cpp | 30 | ||||
| -rw-r--r-- | engines/lure/res_struct.h | 26 | ||||
| -rw-r--r-- | engines/lure/surface.cpp | 26 | ||||
| -rw-r--r-- | engines/lure/surface.h | 7 | 
11 files changed, 150 insertions, 67 deletions
diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp index 63a9fab43c..3567c8cced 100644 --- a/engines/lure/debugger.cpp +++ b/engines/lure/debugger.cpp @@ -306,6 +306,7 @@ bool Debugger::cmd_hotspots(int argc, const char **argv) {  bool Debugger::cmd_hotspot(int argc, const char **argv) {  	Resources &res = Resources::getReference();  	StringData &strings = StringData::getReference(); +	StringList &stringList = res.stringList();  	char buffer[MAX_DESC_SIZE];  	HotspotData *hs;  	Hotspot *h; @@ -351,11 +352,12 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) {  			// List the action set for the character  			for (int action = GET; action <= EXAMINE; ++action) {  				uint16 offset = res.getHotspotAction(hs->actionsOffset, (Action) action); +				const char *actionStr = stringList.getString(action);  				if (offset >= 0x8000) { -					DebugPrintf("%s - Message %xh\n",  actionList[action], offset & 0x7ff); +					DebugPrintf("%s - Message %xh\n",  actionStr, offset & 0x7ff);  				} else if (offset != 0) { -					DebugPrintf("%s - Script %xh\n", actionList[action], offset); +					DebugPrintf("%s - Script %xh\n", actionStr, offset);  				}  			}  	} else { diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp index 56930f5e4c..1623973031 100644 --- a/engines/lure/game.cpp +++ b/engines/lure/game.cpp @@ -216,13 +216,22 @@ void Game::execute() {  }  void Game::handleMenuResponse(uint8 selection) { +	Common::String filename; +  	switch (selection) {  	case MENUITEM_CREDITS:  		doShowCredits();  		break;  	case MENUITEM_RESTART_GAME:  +		break; +  	case MENUITEM_SAVE_GAME: +		if (SaveRestoreDialog::show(true, filename)) { +			// Save the game here +		} +		break; +  	case MENUITEM_RESTORE_GAME:   		break; @@ -304,6 +313,7 @@ void Game::handleRightClickMenu() {  	Resources &res = Resources::getReference();  	Screen &screen = Screen::getReference();  	ValueTableData &fields = res.fieldList(); +	StringList &stringList = res.stringList();  	StringData &strings = StringData::getReference();  	Mouse &mouse = Mouse::getReference();  	char *statusLine = room.statusLine(); @@ -343,7 +353,7 @@ void Game::handleRightClickMenu() {  		action = PopupMenu::Show(actions);  		if (action != NONE) { -			sprintf(statusLine, "%s ", actionList[action]); +			sprintf(statusLine, "%s ", stringList.getString(action));  			statusLine += strlen(statusLine);  		} @@ -357,7 +367,7 @@ void Game::handleRightClickMenu() {  			hotspot = res.getHotspot(room.hotspotId());  			assert(hotspot);  			strings.getString(hotspot->nameId, statusLine); -			strcat(statusLine, " for "); +			strcat(statusLine, stringList.getString(S_FOR));  			statusLine += strlen(statusLine);  			itemId = PopupMenu::ShowItems(GET); @@ -368,7 +378,7 @@ void Game::handleRightClickMenu() {  			hotspot = res.getHotspot(room.hotspotId());  			assert(hotspot);  			strings.getString(hotspot->nameId, statusLine); -			strcat(statusLine, " to "); +			strcat(statusLine, stringList.getString(S_TO));  			breakFlag = GetTellActions();  			break; @@ -378,7 +388,7 @@ void Game::handleRightClickMenu() {  		case DRINK:  			hasItems = (res.numInventoryItems() != 0);  			if (!hasItems) -				strcat(statusLine, "(nothing)"); +				strcat(statusLine, stringList.getString(S_NOTHING));  			statusLine += strlen(statusLine);  			room.update(); @@ -398,9 +408,9 @@ void Game::handleRightClickMenu() {  						assert(useHotspot);  						strings.getString(useHotspot->nameId, statusLine);  						if (action == GIVE)  -							strcat(statusLine, " to "); +							strcat(statusLine, stringList.getString(S_TO));  						else  -							strcat(statusLine, " on "); +							strcat(statusLine, stringList.getString(S_ON));  						statusLine += strlen(statusLine);  					}  					else if ((action == DRINK) || (action == EXAMINE)) @@ -437,6 +447,7 @@ void Game::handleLeftClick() {  	Mouse &mouse = Mouse::getReference();  	Resources &res = Resources::getReference();  	StringData &strings = StringData::getReference(); +	StringList &stringList = res.stringList();  	Hotspot *player = res.getActiveHotspot(PLAYER_ID);  	room.setCursorState(CS_NONE); @@ -447,7 +458,7 @@ void Game::handleLeftClick() {  	if ((room.destRoomNumber() == 0) && (room.hotspotId() != 0)) {	  		// Handle look at hotspot -		sprintf(room.statusLine(), "%s ", actionList[LOOK_AT]); +		sprintf(room.statusLine(), "%s ", stringList.getString(LOOK_AT));  		HotspotData *hotspot = res.getHotspot(room.hotspotId());  		assert(hotspot);  		strings.getString(hotspot->nameId, room.statusLine() + strlen(room.statusLine())); @@ -466,13 +477,12 @@ void Game::handleLeftClick() {  	}  } -const char *continueStrsList[] = {"and then", "finish"}; -  bool Game::GetTellActions() {  	Resources &res = Resources::getReference();  	Screen &screen = Screen::getReference();  	Room &room = Room::getReference();  	StringData &strings = StringData::getReference(); +	StringList &stringList = res.stringList();  	char *statusLine = room.statusLine();  	uint16 fullCommands[MAX_TELL_COMMANDS * 3 + 1];  	uint16 *commands = &fullCommands[1]; @@ -483,6 +493,7 @@ bool Game::GetTellActions() {  	char selectionName[MAX_DESC_SIZE];  	HotspotData *hotspot;  	Action action; +	const char *continueStrsList[2] = {stringList.getString(S_AND_THEN), stringList.getString(S_FINISH)};  	// First word will be the destination character  	fullCommands[0] = room.hotspotId(); @@ -520,7 +531,7 @@ bool Game::GetTellActions() {  				}  				// Add the action to the status line -				sprintf(statusLine + strlen(statusLine), "%s ", actionList[action]); +				sprintf(statusLine + strlen(statusLine), "%s ", stringList.getString(action));  				// Handle any processing for the action  				commands[commandIndex * 3] = (uint16) action; @@ -722,20 +733,18 @@ void Game::doQuit() {  void Game::doTextSpeed() {  	Menu &menu = Menu::getReference(); +	StringList &sl = Resources::getReference().stringList();  	_slowSpeedFlag = !_slowSpeedFlag; -	const char *pSrc = _slowSpeedFlag ? "Slow" : "Fast"; -	char *pDest = menu.getMenu(2).getEntry(1); -	memcpy(pDest, pSrc, 4); +	menu.getMenu(2).entries()[1] = sl.getString(_slowSpeedFlag ? S_SLOW_TEXT : S_FAST_TEXT);  }  void Game::doSound() {  	Menu &menu = Menu::getReference(); +	StringList &sl = Resources::getReference().stringList();  	_soundFlag = !_soundFlag; -	const char *pSrc = _soundFlag ? "on " : "off"; -	char *pDest = menu.getMenu(2).getEntry(2) + 6; -	memcpy(pDest, pSrc, 3); +	menu.getMenu(2).entries()[2] = sl.getString(_soundFlag ? S_SOUND_ON : S_SOUND_OFF);  }  void Game::handleBootParam(int value) { diff --git a/engines/lure/luredefs.h b/engines/lure/luredefs.h index f1e4443ea5..358deaf03a 100644 --- a/engines/lure/luredefs.h +++ b/engines/lure/luredefs.h @@ -31,7 +31,7 @@ namespace Lure {  #define SUPPORT_FILENAME "lure.dat"  #define LURE_DAT_MAJOR 1 -#define LURE_DAT_MINOR 12 +#define LURE_DAT_MINOR 13  #define LURE_DEBUG 1 @@ -173,6 +173,8 @@ enum Action {  #define TALK_DIALOG_WIDTH 128  #define TALK_DIALOG_EDGE_SIZE 3  #define TALK_DIALOG_Y 33 +#define SAVE_DIALOG_X 69 +#define SAVE_DIALOG_Y 28  // Strings defines  #define STRINGS_RESOURCE_ID 0x10 @@ -204,6 +206,8 @@ enum Action {  #define EXIT_COORDINATES_RESOURCE_ID 0x3f14  #define EXIT_HOTSPOT_ID_LIST 0x3f15 +#define STRING_LIST_RESOURCE_ID 0x3f17 +  // Script constants  #define STARTUP_SCRIPT 0x23FC diff --git a/engines/lure/menu.cpp b/engines/lure/menu.cpp index cf694428b1..da53e898fd 100644 --- a/engines/lure/menu.cpp +++ b/engines/lure/menu.cpp @@ -34,37 +34,23 @@  namespace Lure {  MenuRecord::MenuRecord(uint16 hsxstartVal, uint16 hsxendVal, uint16 xstartVal,  -					   uint16 widthVal, const char *strings) { -	_xstart = xstartVal; _width = widthVal; -	_hsxstart = hsxstartVal; _hsxend = hsxendVal; +					   uint16 widthVal, int numParams, ...) { +	// Store list of pointers to strings +	va_list params; -	// Figure out the number of entries -	const char *sPtr = strings; -	_numEntries = 1; -	while ((sPtr = strchr(sPtr, ',')) != NULL) { -		++_numEntries; -		++sPtr; -	} +	_numEntries = numParams; +	_entries = (const char **) malloc(sizeof(const char *) * _numEntries);	 -	// Set up the list of entries -	char *sCopy = strdup(strings); -	char *s; -	_entries = (char **) malloc(sizeof(char *) * _numEntries); -	uint8 index = 0; -	s = sCopy; -	while (s != NULL) { -		_entries[index++] = s; -		s = strchr(s, ','); -		if (s != NULL) *s++ = '\0'; // replace comma with NULL -	} -} +	va_start(params, numParams); +	for (int index = 0; index < _numEntries; ++index) +		_entries[index] = va_arg(params, const char *); -MenuRecord::~MenuRecord() { -	free(_entries[0]);	// Delete string data for all the menu items -	free(_entries);		// Free the list +	// Store position data +	_xstart = xstartVal; _width = widthVal; +	_hsxstart = hsxstartVal; _hsxend = hsxendVal;  } -char *MenuRecord::getEntry(uint8 index) { +const char *MenuRecord::getEntry(uint8 index) {  	if (index >= _numEntries) error("Invalid menuitem index specified: %d", index);  	return _entries[index];  } @@ -75,15 +61,19 @@ static Menu *int_menu = NULL;  Menu::Menu() {  	int_menu = this; +	StringList &sl = Resources::getReference().stringList();  	MemoryBlock *data = Disk::getReference().getEntry(MENU_RESOURCE_ID);  	PictureDecoder decoder;  	_menu = decoder.decode(data, SCREEN_SIZE);  	delete data; -	_menus[0] = new MenuRecord(40, 87, 20, 80, "Credits"); -	_menus[1] = new MenuRecord(127, 179, 100, 120, "Restart game,Save game,Restore game"); -	_menus[2] = new MenuRecord(224, 281, 210, 105, "Quit,Slow Text\x8b,Sound on "); +	_menus[0] = new MenuRecord(40, 87, 20, 80, 1, sl.getString(S_CREDITS)); +	_menus[1] = new MenuRecord(127, 179, 100, 120, 3,  +		sl.getString(S_RESTART_GAME), sl.getString(S_SAVE_GAME), sl.getString(S_RESTORE_GAME)); +	_menus[2] = new MenuRecord(224, 281, 210, 105, 3, +		sl.getString(S_QUIT), sl.getString(S_SLOW_TEXT), sl.getString(S_SOUND_ON)); +  	_selectedMenu = NULL;  } @@ -372,6 +362,7 @@ uint16 PopupMenu::ShowItems(Action contextAction) {  }  Action PopupMenu::Show(uint32 actionMask) { +	StringList &stringList = Resources::getReference().stringList();  	int numEntries = 0;  	uint32 v = actionMask;  	int index; @@ -389,7 +380,7 @@ Action PopupMenu::Show(uint32 actionMask) {  	int strIndex = 0;  	for (currentAction = &sortedActions[0]; *currentAction != NONE; ++currentAction) {  		if ((actionMask & (1 << (*currentAction - 1))) != 0) { -			strList[strIndex] = actionList[*currentAction]; +			strList[strIndex] = stringList.getString(*currentAction);  			actionSet[strIndex] = *currentAction;  			++strIndex;  		} @@ -408,10 +399,11 @@ Action PopupMenu::Show(uint32 actionMask) {  }  Action PopupMenu::Show(int numEntries, Action *actions) { +	StringList &stringList = Resources::getReference().stringList();  	const char **strList = (const char **) Memory::alloc(sizeof(char *) * numEntries);  	Action *actionPtr = actions;  	for (int index = 0; index < numEntries; ++index) -		strList[index] = actionList[*actionPtr++]; +		strList[index] = stringList.getString(*actionPtr++);  	uint16 result = Show(numEntries, strList);  	delete strList; diff --git a/engines/lure/menu.h b/engines/lure/menu.h index 64dbbd88a5..ce87bc7227 100644 --- a/engines/lure/menu.h +++ b/engines/lure/menu.h @@ -39,20 +39,19 @@ class MenuRecord {  private:  	uint16 _xstart, _width;  	uint16 _hsxstart, _hsxend; -	char **_entries; +	const char **_entries;  	uint8 _numEntries;  public: -	MenuRecord(uint16 hsxstartVal, uint16 hsxendVal, uint16 xstartVal,  -		uint16 widthVal, const char *strings);  -	~MenuRecord(); +	MenuRecord(uint16 hsxstartVal, uint16 hsxendVal, uint16 xstartVal, uint16 widthVal,  +		int numParams, ...);   	uint16 xstart() { return _xstart; }  	uint16 width() { return _width; }  	uint16 hsxstart() { return _hsxstart; }  	uint16 hsxend() { return _hsxend; }  	uint8 numEntries() { return _numEntries; } -	char **entries() { return _entries; } -	char *getEntry(uint8 index); +	const char **entries() { return _entries; } +	const char *getEntry(uint8 index);  };  class Menu { diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp index cdd6a3586f..821c4103ac 100644 --- a/engines/lure/res.cpp +++ b/engines/lure/res.cpp @@ -55,6 +55,7 @@ void Resources::freeData() {  	_charSchedules.clear();  	_indexedRoomExitHospots.clear();  	_pausedList.clear(); +	_stringList.clear();  	delete _paletteSubset;  	delete _scriptData; @@ -298,6 +299,11 @@ void Resources::reloadData() {  		indexedRec++;  	} +	// Load the string list +	mb = d.getEntry(STRING_LIST_RESOURCE_ID); +	_stringList.load(mb); +	delete mb; +  	// Initialise delay list  	_delayList.clear(); diff --git a/engines/lure/res.h b/engines/lure/res.h index 3c27223b1d..c29fd80c30 100644 --- a/engines/lure/res.h +++ b/engines/lure/res.h @@ -69,6 +69,7 @@ private:  	CharacterScheduleList _charSchedules;  	RoomExitIndexedHotspotList _indexedRoomExitHospots;  	PausedCharacterList _pausedList; +	StringList _stringList;  	int numCharOffsets;  	uint16 *_charOffsets; @@ -123,6 +124,7 @@ public:  	CharacterScheduleList &charSchedules() { return _charSchedules; }  	RoomExitIndexedHotspotList &exitHotspots() { return _indexedRoomExitHospots; }  	PausedCharacterList &pausedList() { return _pausedList; } +	StringList &stringList() { return _stringList; }  	uint16 getCharOffset(int index) {   		if (index >= numCharOffsets)   			error("Invalid index %d passed to script engine support data offset list", index); @@ -152,7 +154,7 @@ public:  	const char *getCurrentActionStr() {   		if (_currentAction > EXAMINE)   			error("Invalid current action %d", _currentAction); -		return actionList[_currentAction];  +		return _stringList.getString(_currentAction);  	}  	Hotspot *activateHotspot(uint16 hotspotId);  	Hotspot *addHotspot(uint16 hotspotId); diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp index 01f29b14ce..e94b55b2e4 100644 --- a/engines/lure/res_struct.cpp +++ b/engines/lure/res_struct.cpp @@ -28,11 +28,6 @@  namespace Lure { -const char *actionList[] = {NULL, "Get", NULL, "Push", "Pull", "Operate", "Open", -	"Close", "Lock", "Unlock", "Use", "Give", "Talk to", "Tell", "Buy", -	"Look", "Look at", "Look through", "Ask", NULL, "Drink", "Status", -	"Go to", "Return", "Bribe", "Examine"}; -  const Action sortedActions[] = {ASK, BRIBE, BUY, CLOSE, DRINK, EXAMINE, GET, GIVE,   	GO_TO, LOCK, LOOK, LOOK_AT, LOOK_THROUGH, OPEN, OPERATE, PULL, PUSH, RETURN,   	STATUS, TALK_TO, TELL, UNLOCK, USE, NONE}; @@ -810,6 +805,31 @@ int PausedCharacterList::check(uint16 charId, int numImpinging, uint16 *impingin  	return result;  } +// String list resource class + +void StringList::load(MemoryBlock *data) { +	_data = Memory::allocate(data->size()); +	_data->copyFrom(data); + +	_numEntries = READ_LE_UINT16(_data->data()); +	char *p = (char *) _data->data() + sizeof(uint16); + +	_entries = (char **) Memory::alloc(_numEntries * sizeof(char *)); + +	for (int index = 0; index < _numEntries; ++index) { +		_entries[index] = p; +		p += strlen(p) + 1;	 +	} +} + +void StringList::clear() { +	if (_numEntries != 0) { +		Memory::dealloc(_entries); +		delete _data; +		_numEntries = 0; +	} +} +  // Field list and miscellaneous variables  ValueTableData::ValueTableData() { diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h index c9ae4e783d..b6e4f56502 100644 --- a/engines/lure/res_struct.h +++ b/engines/lure/res_struct.h @@ -30,7 +30,6 @@ namespace Lure {  using namespace Common; -extern const char *actionList[];  extern const Action sortedActions[];  /*-------------------------------------------------------------------------*/ @@ -644,6 +643,31 @@ public:  	int check(uint16 charId, int numImpinging, uint16 *impingingList);  }; +enum StringEnum {S_CREDITS = 25, S_RESTART_GAME = 26, S_SAVE_GAME = 27, S_RESTORE_GAME = 28,  +	S_QUIT = 29, S_FAST_TEXT = 30, S_SLOW_TEXT = 31, S_SOUND_ON = 32, S_SOUND_OFF = 33,  +	S_NOTHING = 34, S_FOR = 35, S_TO = 36, S_ON = 37, S_AND_THEN = 38, +	S_FINISH = 39}; + +class StringList { +private: +	MemoryBlock *_data; +	int _numEntries; +	char **_entries; +public: +	StringList() { _numEntries = 0; } +	~StringList() { clear(); } + +	void load(MemoryBlock *data); +	void clear(); +	int count() { return _numEntries; } +	const char *getString(int index) { +		if ((index < 0) || (index >= _numEntries)) error("Invalid index specified to String List"); +		return _entries[index]; +	} +	const char *getString(Action action) { return getString((int) action - 1); } +	const char *getString(StringEnum sEnum) { return getString((int) sEnum); } +}; +  // The following class holds the field list used by the script engine as   // well as miscellaneous fields used by the game.                           diff --git a/engines/lure/surface.cpp b/engines/lure/surface.cpp index 6e1890543e..af793ee561 100644 --- a/engines/lure/surface.cpp +++ b/engines/lure/surface.cpp @@ -352,7 +352,7 @@ void Surface::wordWrap(char *text, uint16 width, char **&lines, uint8 &numLines)  		lines[ctr] = strchr(lines[ctr-1], 0) + 1;  } -Surface *Surface::newDialog(uint16 width, uint8 numLines, char **lines, bool varLength, uint8 colour) { +Surface *Surface::newDialog(uint16 width, uint8 numLines, const char **lines, bool varLength, uint8 colour) {  	Surface *s = new Surface(width, (DIALOG_EDGE_SIZE + 3) * 2 +   		numLines * (FONT_HEIGHT - 1));  	s->createDialog(); @@ -369,9 +369,8 @@ Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {  	uint8 numLines;  	wordWrap(lineCopy, width - (DIALOG_EDGE_SIZE + 3) * 2, lines, numLines); -  	// Create the dialog  -	Surface *result = newDialog(width, numLines, lines, true, colour); +	Surface *result = newDialog(width, numLines, (const char **) lines, true, colour);  	// Deallocate used resources  	free(lines); @@ -519,4 +518,25 @@ TalkDialog::~TalkDialog() {  	delete _surface;  } +/*--------------------------------------------------------------------------*/ + +bool SaveRestoreDialog::show(bool save, Common::String &filename) { +	Screen &screen = Screen::getReference(); +	Mouse &mouse = Mouse::getReference(); +	Room &room = Room::getReference(); +	mouse.cursorOff(); + +	room.update(); +	Surface *s = new Surface(INFO_DIALOG_WIDTH, 100); +	s->createDialog(); +	s->copyToScreen(SAVE_DIALOG_X, SAVE_DIALOG_Y); + +	// Wait for a keypress or mouse button +	Events::getReference().waitForPress(); + +	screen.update(); +	mouse.cursorOn(); +	return false; +} +  } // end of namespace Lure diff --git a/engines/lure/surface.h b/engines/lure/surface.h index 9242bca03e..e2d6208471 100644 --- a/engines/lure/surface.h +++ b/engines/lure/surface.h @@ -67,7 +67,7 @@ public:  	static uint16 textWidth(const char *s, int numChars = 0);  	static void wordWrap(char *text, uint16 width, char **&lines, uint8 &numLines); -	static Surface *newDialog(uint16 width, uint8 numLines, char **lines, bool varLength = true, uint8 colour = DIALOG_TEXT_COLOUR); +	static Surface *newDialog(uint16 width, uint8 numLines, const char **lines, bool varLength = true, uint8 colour = DIALOG_TEXT_COLOUR);  	static Surface *newDialog(uint16 width, const char *lines, uint8 colour = DIALOG_TEXT_COLOUR);  	static Surface *getScreen(uint16 resourceId);  }; @@ -92,6 +92,11 @@ public:  	Surface &surface() { return *_surface; }  }; +class SaveRestoreDialog { +public: +	static bool show(bool save, Common::String &filename); +}; +  } // End of namespace Lure  #endif  | 
