diff options
| author | Matthew Stewart | 2018-03-11 19:22:24 -0400 | 
|---|---|---|
| committer | Eugene Sandulenko | 2018-08-09 08:37:30 +0200 | 
| commit | fd26d0a790342b086fc9430d3cb9d4449104e6ce (patch) | |
| tree | 422c66a91b1bab3fa3d6e87f6b8aac58e834b609 | |
| parent | 295c55c510d8ebdbfb453ea769fff243bdfb4e0c (diff) | |
| download | scummvm-rg350-fd26d0a790342b086fc9430d3cb9d4449104e6ce.tar.gz scummvm-rg350-fd26d0a790342b086fc9430d3cb9d4449104e6ce.tar.bz2 scummvm-rg350-fd26d0a790342b086fc9430d3cb9d4449104e6ce.zip  | |
STARTREK: Begin implementing event system.
Textbox now responds to mouse input.
| -rw-r--r-- | engines/startrek/events.cpp | 94 | ||||
| -rwxr-xr-x | engines/startrek/graphics.h | 22 | ||||
| -rwxr-xr-x | engines/startrek/module.mk | 1 | ||||
| -rwxr-xr-x | engines/startrek/startrek.cpp | 36 | ||||
| -rwxr-xr-x | engines/startrek/startrek.h | 60 | ||||
| -rw-r--r-- | engines/startrek/text.cpp | 205 | 
6 files changed, 374 insertions, 44 deletions
diff --git a/engines/startrek/events.cpp b/engines/startrek/events.cpp new file mode 100644 index 0000000000..a37ae8c7a4 --- /dev/null +++ b/engines/startrek/events.cpp @@ -0,0 +1,94 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "startrek/startrek.h" + +namespace StarTrek { + +void StarTrekEngine::initializeEventsAndMouse() { +	_mouseMoveEventInQueue = false; +	_tickEventInQueue = false; + +	// TODO: mouse +} + +/** + * Returns false if there is no event waiting. + */ +bool StarTrekEngine::getNextEvent(TrekEvent *e) { +	pollSystemEvents(); // TODO: put this somewhere else? + +	if (_eventQueue.empty()) +		return false; +	*e = _eventQueue.front(); +	return true; +} + +void StarTrekEngine::removeNextEvent() { +	if (_eventQueue.empty()) +		return; + +	const TrekEvent &e = _eventQueue.front(); + +	if (e.type == TREKEVENT_MOUSEMOVE) +		_mouseMoveEventInQueue = false; +	if (e.type == TREKEVENT_TICK) +		_tickEventInQueue = false; + +	_eventQueue.pop_front(); +} + +bool StarTrekEngine::popNextEvent(TrekEvent *e) { +	if (!getNextEvent(e)) +		return false; + +	removeNextEvent(); +	return true; +} + +void StarTrekEngine::addEventToQueue(const TrekEvent &e) { +	if (e.type == TREKEVENT_MOUSEMOVE && _mouseMoveEventInQueue) { +		// Only allow one mouse move event at once +		for (Common::List<TrekEvent>::iterator i = _eventQueue.begin(); i!=_eventQueue.end(); i++) { +			if (i->type == TREKEVENT_MOUSEMOVE) { +				*i = e; +				return; +			} +		} + +		error("Couldn't find mouse move event in eventQueue"); +	} + +	if (e.type == TREKEVENT_TICK) { +		// Only allow one tick event at once +		if (_tickEventInQueue) +			return; +		_tickEventInQueue = true; +	} + +	if (e.type == TREKEVENT_MOUSEMOVE) +		_mouseMoveEventInQueue = true; + +	assert(_eventQueue.size() < 0x40); +	_eventQueue.push_back(e); +} + +} diff --git a/engines/startrek/graphics.h b/engines/startrek/graphics.h index 62c49f2d01..578abdf705 100755 --- a/engines/startrek/graphics.h +++ b/engines/startrek/graphics.h @@ -47,23 +47,24 @@ const int MAX_SPRITES = 32;  const int MAX_MENUBUTTONS = 16; // This is arbitrary, the original game has no such limit  const int TEXTBOX_WIDTH = 26; +const int MAX_TEXTBOX_LINES = 12;  // Keeps track of data for a list of buttons making up a menu  struct Menu {  	Sprite sprites[MAX_MENUBUTTONS];  	uint16 retvals[MAX_MENUBUTTONS]; -	uint16 buttonVar2; +	uint32 disabledButtons;  	SharedPtr<FileStream> menuFile;  	uint16 numButtons; -	uint16 buttonVar1; +	int16 selectedButton;  	SharedPtr<Menu> nextMenu;  	Menu() : nextMenu(SharedPtr<Menu>()) {}  };  class Graphics; -typedef String (Graphics::*TextGetterFunc)(int, int, String *); +typedef String (Graphics::*TextGetterFunc)(int, void *, String *);  class Graphics { @@ -115,11 +116,12 @@ private:  	// text.cpp (TODO: separate class)  public:  	int showText(TextGetterFunc textGetter, int var, int xoffset, int yoffset, int textColor, bool loopChoices, int maxTextLines, int arg10); -	String tmpFunction(int choiceIndex, int var, String *headerTextOutput); -	String readTextFromRdf(int choiceIndex, int rdfVar, String *headerTextOutput); + +	String readTextFromRdf(int choiceIndex, void *data, String *headerTextOutput); +	String readTextFromBuffer(int choiceIndex, void *data, String *headerTextOutput);  private: -	int handleTextboxEvents(uint32 arg0, bool arg4); +	int handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4);  	SharedPtr<TextBitmap> initTextSprite(int *xoffsetPtr, int *yoffsetPtr, byte textColor, int numTextLines, bool withHeader, Sprite *sprite);  	void drawMainText(SharedPtr<TextBitmap> bitmap, int numTextLines, int numTextboxLines, const String &text, bool withHeader); @@ -134,20 +136,24 @@ private:  	String skipTextAudioPrompt(const String &str);  	String playTextAudio(const String &str); +	int getMenuButtonAt(const Menu &menu, int x, int y); +	void drawMenuButtonOutline(SharedPtr<Bitmap> bitmap, byte color);  	void loadMenuButtons(String mnuFilename, int xpos, int ypos);  	void setMenuButtonVar2Bits(uint32 bits);  	void clearMenuButtonVar2Bits(uint32 bits); +  	uint16 _textboxVar1;  	uint32 _textboxVar2;  	uint32 _textboxVar3; -	uint16 _textboxVar4; -	uint16 _textboxVar5;  	uint16 _textboxVar6;  	uint16 _textboxVar7;  	bool _textboxHasMultipleChoices;  	SharedPtr<Menu> _activeMenu; + +	uint16 _textboxButtonVar4; +	uint16 _word_4B422;  };  } diff --git a/engines/startrek/module.mk b/engines/startrek/module.mk index ea8d4d385a..9114de4632 100755 --- a/engines/startrek/module.mk +++ b/engines/startrek/module.mk @@ -4,6 +4,7 @@ MODULE_OBJS = \  	bitmap.o \  	common.o \  	detection.o \ +	events.o \  	filestream.o \  	font.o \  	lzss.o \ diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index f83a18218b..1b333b925a 100755 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -55,6 +55,9 @@ StarTrekEngine::~StarTrekEngine() {  }  Common::Error StarTrekEngine::run() { +	_cdAudioEnabled = true; +	_midiAudioEnabled = true; +  	_gfx = new Graphics(this);  	_sound = new Sound(this); @@ -66,6 +69,8 @@ Common::Error StarTrekEngine::run() {  	}  	initGraphics(320, 200); + +	initializeEventsAndMouse();  // Hexdump data  #if 0 @@ -151,21 +156,38 @@ Common::Error StarTrekEngine::run() {  	_gfx->showText(&Graphics::readTextFromRdf, 0x2220, 150, 160, 0xb3, 0, 10, 0);  	while (!shouldQuit()) { -		pollEvents(); +		pollSystemEvents();  	}  #endif  	return Common::kNoError;  } -void StarTrekEngine::pollEvents() { +Room *StarTrekEngine::getRoom() { +	return _room; +} + +void StarTrekEngine::pollSystemEvents() {  	Common::Event event; +	TrekEvent trekEvent;  	while (_eventMan->pollEvent(event)) { +		trekEvent.mouse = event.mouse; +		trekEvent.kbd = event.kbd; +  		switch (event.type) {  		case Common::EVENT_QUIT:  			_system->quit();  			break; + +		case Common::EVENT_MOUSEMOVE: +			trekEvent.type = TREKEVENT_MOUSEMOVE; +			addEventToQueue(trekEvent); +			break; +		case Common::EVENT_LBUTTONDOWN: +			trekEvent.type = TREKEVENT_LBUTTONDOWN; +			addEventToQueue(trekEvent); +			break;  		default:  			break;  		} @@ -175,8 +197,14 @@ void StarTrekEngine::pollEvents() {  	_system->delayMillis(1000/60);  } -Room *StarTrekEngine::getRoom() { -	return _room; +void StarTrekEngine::playSound(int id) { +	// TODO +} + +void StarTrekEngine::updateClockTicks() { +	// TODO (based on DOS interrupt 1A, AH=0; read system clock counter) + +	_clockTicks = 0;  }  SharedPtr<FileStream> StarTrekEngine::openFile(Common::String filename, int fileIndex) { diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h index e19fd11436..a0b97b9760 100755 --- a/engines/startrek/startrek.h +++ b/engines/startrek/startrek.h @@ -17,15 +17,13 @@   * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL: https://scummvm-startrek.googlecode.com/svn/trunk/startrek.h $ - * $Id: startrek.h 14 2010-05-26 15:44:12Z clone2727 $ - *   */  #ifndef STARTREK_H  #define STARTREK_H +#include "common/events.h" +#include "common/list.h"  #include "common/ptr.h"  #include "common/rect.h"  #include "common/scummsys.h" @@ -59,6 +57,24 @@ enum StarTrekGameFeatures {  	GF_DEMO =    (1 << 0)  }; + +enum TrekEventType { +	TREKEVENT_TICK = 0, // DOS clock changes (see updateClockTicks) +	TREKEVENT_LBUTTONDOWN = 1, +	TREKEVENT_MOUSEMOVE = 2, +	TREKEVENT_LBUTTONUP = 3, +	TREKEVENT_RBUTTONDOWN = 4, +	TREKEVENT_RBUTTONUP = 5, +	TREKEVENT_KEYDOWN = 6 +}; + +struct TrekEvent { +	TrekEventType type; +	Common::KeyState kbd; +	Common::Point mouse; +	uint32 tick; +}; +  struct StarTrekGameDescription;  class Graphics;  class Sound; @@ -72,9 +88,35 @@ public:  	virtual ~StarTrekEngine();  	// Running the game -	void pollEvents();  	Room *getRoom(); +	void pollSystemEvents(); +	void playSound(int id); // TODO: rename, figure out what it is + +	// Events +public: +	void initializeEventsAndMouse(); +	bool getNextEvent(TrekEvent *e); +	void removeNextEvent(); +	bool popNextEvent(TrekEvent *e); +	void addEventToQueue(const TrekEvent &e); +	void clearEventBuffer(); +	uint32 getClockTicks(); +	void updateEvents(); +	void updateTimerEvent(); +	void updateMouseEvents(); +	void updateKeyboardEvents(); +	void updateClockTicks(); +	bool checkKeyPressed(); + +	Common::EventManager *getEventMan() { return _eventMan; } + +private: +	Common::List<TrekEvent> _eventQueue; +	bool _mouseMoveEventInQueue; +	bool _tickEventInQueue; + +public:  	// Detection related functions  	const StarTrekGameDescription *_gameDescription;  	uint32 getFeatures() const; @@ -89,6 +131,14 @@ public:  	// Movie related functions  	void playMovie(Common::String filename);  	void playMovieMac(Common::String filename); + + +	uint32 _clockTicks; + +	bool _midiAudioEnabled; +	bool _cdAudioEnabled; +	bool _textboxVar4; +  private:  	Graphics *_gfx; diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp index 9e54e8375c..6ac31b02a4 100644 --- a/engines/startrek/text.cpp +++ b/engines/startrek/text.cpp @@ -19,19 +19,20 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   */ +#include "common/events.h"  #include "common/stream.h"  #include "graphics/cursorman.h"  #include "startrek/graphics.h" -// List of events that can be returned by handleTextEvents. +// List of events that can be returned by handleTextboxEvents.  enum TextEvent { -	TEXTEVENT_RCLICK_OFFBUTTON = 0, +	TEXTEVENT_RCLICK_OFFBUTTON = -4,  	TEXTEVENT_ENABLEINPUT,          // Makes buttons selectable (occurs after a delay)  	TEXTEVENT_RCLICK_ONBUTTON,  	TEXTEVENT_LCLICK_OFFBUTTON, -	TEXTEVENT_CONFIRM, +	TEXTEVENT_CONFIRM = 0,  	TEXTEVENT_SCROLLUP,  	TEXTEVENT_SCROLLDOWN,  	TEXTEVENT_PREVCHOICE, @@ -59,7 +60,7 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff  	String speakerText;  	while(true) { -		String choiceText = (this->*textGetter)(numChoices, var, &speakerText); +		String choiceText = (this->*textGetter)(numChoices, &var, &speakerText);  		if (choiceText.empty())  			break; @@ -73,8 +74,8 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff  		numChoices++;  	} -	if (maxTextLines == 0 || maxTextLines > 12) -		maxTextLines = 12; +	if (maxTextLines == 0 || maxTextLines > MAX_TEXTBOX_LINES) +		maxTextLines = MAX_TEXTBOX_LINES;  	if (numTextboxLines > maxTextLines)  		numTextboxLines = maxTextLines; @@ -87,12 +88,12 @@ int Graphics::showText(TextGetterFunc textGetter, int var, int xoffset, int yoff  	int choiceIndex = 0;  	int scrollOffset = 0;  	if (tmpTextboxVar1 != 0 && tmpTextboxVar1 != 1 && numChoices == 1 -			&& _textboxVar5 != 0 && _textboxVar4 == 0) +			&& _vm->_cdAudioEnabled && !_vm->_textboxVar4)  		_textboxHasMultipleChoices = false;  	else  		_textboxHasMultipleChoices = true; -	if (tmpTextboxVar1 >= 0 && tmpTextboxVar1 <= 2 && _textboxVar5 == 1 && _textboxVar4 == 0) +	if (tmpTextboxVar1 >= 0 && tmpTextboxVar1 <= 2 && _vm->_cdAudioEnabled && !_vm->_textboxVar4)  		_textboxVar6 = true;  	else  		_textboxVar6 = false; @@ -196,7 +197,12 @@ readjustScrollDown:  readjustScroll:  				textboxSprite.bitmapChanged = true; -				// sub_225d3(textBitmap, numTextLines-scrollOffset, numTextboxLines, lineFormattedText+scrollOffset*0x18); +				drawMainText( +						textBitmap, +						numTextLines-scrollOffset, +						numTextboxLines, +						lineFormattedText.c_str() + scrollOffset*(TEXTBOX_WIDTH-2), +						numChoicesWithNames != 0);  				break;  			case TEXTEVENT_PREVCHOICE: @@ -266,27 +272,97 @@ reloadText:  	return choiceIndex;  } -int Graphics::handleTextboxEvents(uint32 arg0, bool arg4) { -	// TODO +int Graphics::handleTextboxEvents(uint32 ticksUntilClickingEnabled, bool arg4) { +	// TODO: finish + +	uint32 tickWhenClickingEnabled = _vm->_clockTicks + ticksUntilClickingEnabled; +  	while (true) { -		_vm->pollEvents(); -	} -} +		TrekEvent event; +		while (_vm->popNextEvent(&event)) { +			switch(event.type) { + +			case TREKEVENT_TICK: { +			case TREKEVENT_MOUSEMOVE: // FIXME: actual game only uses TICK event here +				Common::Point mousePos = getMousePos(); +				int buttonIndex = getMenuButtonAt(*_activeMenu, mousePos.x, mousePos.y); +				if (buttonIndex != -1) { +					if (_activeMenu->disabledButtons & (1<<buttonIndex)) +						buttonIndex = -1; +				} -String Graphics::tmpFunction(int choiceIndex, int var, String *headerTextOutput) { -	if (headerTextOutput != nullptr) -		*headerTextOutput = "Speaker                 "; +				if (buttonIndex != _activeMenu->selectedButton) { +					if (_activeMenu->selectedButton != -1) { +						Sprite &spr = _activeMenu->sprites[_activeMenu->selectedButton]; +						drawMenuButtonOutline(spr.bitmap, 0x00); +						spr.bitmapChanged = true; +					} +					if (buttonIndex != -1) { +						Sprite &spr = _activeMenu->sprites[buttonIndex]; +						drawMenuButtonOutline(spr.bitmap, 0xda); +						spr.bitmapChanged = true; +					} +					_activeMenu->selectedButton = buttonIndex; +				} +				// Not added: updating mouse position (scummvm handles that) + +				// sub_10492(); +				// sub_10A91(); +				drawAllSprites(); +				// sub_10BE7(); +				// sub_2A4B1(); + +				if (_word_4B422 != 0) { +					_word_4B422 = 0; +					if (_textboxVar1 != 0) { +						return TEXTEVENT_SPEECH_DONE; +					} +				} +				// sub_1E88C(); +				_textboxVar3++; -	if (choiceIndex >= 1) -		return NULL; -	return "Text test"; +				if (ticksUntilClickingEnabled != 0 && _vm->_clockTicks >= tickWhenClickingEnabled) +					return TEXTEVENT_ENABLEINPUT; +				break; +			} + +			case TREKEVENT_LBUTTONDOWN: +				if (_activeMenu->selectedButton != -1) { +					_vm->playSound(0x10); +					return _activeMenu->retvals[_activeMenu->selectedButton]; +				} +				else { +					Common::Point mouse = getMousePos(); +					if (getMenuButtonAt(*_activeMenu, mouse.x, mouse.y) == -1) { +						_vm->playSound(0x10); +						return TEXTEVENT_LCLICK_OFFBUTTON; +					} +				} +				break; + +			case TREKEVENT_RBUTTONDOWN: +				// TODO +				break; + +			case TREKEVENT_KEYDOWN: +				// TODO +				break; + +			default: +				break; +			} +		} +	}  } -String Graphics::readTextFromRdf(int choiceIndex, int rdfVar, String *headerTextOutput) { +/** + * Text getter for showText which reads from an rdf file. + */ +String Graphics::readTextFromRdf(int choiceIndex, void *data, String *headerTextOutput) {  	Room *room = _vm->getRoom(); -	// FIXME: in original game "rdfVar" is a pointer to the variable holding the offset. -	// Currently treating it as the offset itself. +	int rdfVar = *(int*)data; +  	uint16 textOffset = room->readRdfWord(rdfVar + (choiceIndex+1)*2);  	if (textOffset == 0) @@ -309,6 +385,20 @@ String Graphics::readTextFromRdf(int choiceIndex, int rdfVar, String *headerText  }  /** + * Text getter for showText which reads from a given buffer. + */ +String Graphics::readTextFromBuffer(int choiceIndex, void *data, String *headerTextOutput) { +	char buf[TEXTBOX_WIDTH]; +	memcpy(buf, data, TEXTBOX_WIDTH-2); +	buf[TEXTBOX_WIDTH-2] = '\0'; + +	*headerTextOutput = String(buf); + +	char *text = (char*)data+TEXTBOX_WIDTH-2; +	return String(text); +} + +/**   * Creates a blank textbox in a TextBitmap, and initializes a sprite to use it.   */  SharedPtr<TextBitmap> Graphics::initTextSprite(int *xoffsetPtr, int *yoffsetPtr, byte textColor, int numTextLines, bool withHeader, Sprite *sprite) { @@ -407,7 +497,6 @@ void Graphics::drawMainText(SharedPtr<TextBitmap> bitmap, int numTextLines, int  		lineIndex++;  	} -	debug("%d, %d\n", numTextLines, numTextboxLines);  	// Fill all remaining blank lines  	while (lineIndex != numTextboxLines) {  		memset(dest, ' ', TEXTBOX_WIDTH-2); @@ -448,15 +537,15 @@ void Graphics::getTextboxHeader(String *headerTextOutput, String speakerText, in  String Graphics::readLineFormattedText(TextGetterFunc textGetter, int var, int choiceIndex, SharedPtr<TextBitmap> textBitmap, int numTextboxLines, int *numTextLines) {  	String headerText; -	String text = (this->*textGetter)(choiceIndex, var, &headerText); +	String text = (this->*textGetter)(choiceIndex, &var, &headerText); -	if (_textboxVar1 == 2 && _textboxVar5 == 1 && _textboxVar4 == 1) { +	if (_textboxVar1 == 2 && _vm->_cdAudioEnabled && _vm->_textboxVar4) {  		uint32 oldSize = text.size();  		text = playTextAudio(text);  		if (oldSize != text.size())  			_textboxHasMultipleChoices = true;  	} -	else if ((_textboxVar1 == 0 || _textboxVar1 == 1) && _textboxVar5 == 1 && _textboxVar4 == 1) { +	else if ((_textboxVar1 == 0 || _textboxVar1 == 1) && _vm->_cdAudioEnabled && _vm->_textboxVar4) {  		text = playTextAudio(text);  	}  	else { @@ -598,6 +687,58 @@ String Graphics::playTextAudio(const String &str) {  	return skipTextAudioPrompt(str);  } +/** + * Returns the index of the button at the given position, or -1 if none. + */ +int Graphics::getMenuButtonAt(const Menu &menu, int x, int y) { +	for (int i=0; i<menu.numButtons; i++) { +		const Sprite &spr = menu.sprites[i]; + +		if (spr.drawMode != 2) +			continue; + +		int left = spr.pos.x - spr.bitmap->xoffset; +		int top = spr.pos.y - spr.bitmap->yoffset; + +		// Oddly, this doesn't account for x/yoffset... +		int right = spr.pos.x + spr.bitmap->width - 1; +		int bottom = spr.pos.y + spr.bitmap->height - 1; + +		if (x >= left && x <= right && y >= top && y <= bottom) +			return i; +	} + +	return -1; +} + +/** + * Draws or removes the outline on menu buttons when the cursor hovers on them, or leaves + * them. + */ +void Graphics::drawMenuButtonOutline(SharedPtr<Bitmap> bitmap, byte color) { +	int lineWidth = bitmap->width-2; +	int offsetToBottom = (bitmap->height-3)*bitmap->width; + +	byte *dest = bitmap->pixels + bitmap->width + 1; + +	while (lineWidth--) { +		*dest = color; +		*(dest+offsetToBottom) = color; +		dest++; +	} + +	int lineHeight = bitmap->height - 2; +	int offsetToRight = bitmap->width - 3; + +	dest = bitmap->pixels + bitmap->width + 1; + +	while (lineHeight--) { +		*dest = color; +		*(dest+offsetToRight) = color; +		dest += bitmap->width; +	} +} +  void Graphics::loadMenuButtons(String mnuFilename, int xpos, int ypos) {  	SharedPtr<Menu> oldMenu = _activeMenu;  	_activeMenu = SharedPtr<Menu>(new Menu()); @@ -629,6 +770,16 @@ void Graphics::loadMenuButtons(String mnuFilename, int xpos, int ypos) {  		_activeMenu->sprites[i].field6 = 8;  	} + +	if (_activeMenu->retvals[_activeMenu->numButtons-1] == 0) { +		// Set default retvals for buttons +		for (int i=0; i<_activeMenu->numButtons; i++) +			_activeMenu->retvals[i] = i; +	} + +	_activeMenu->selectedButton = -1; +	_activeMenu->disabledButtons = 0; +	_textboxButtonVar4 = 0;  }  // 0x0002: Disable scroll up  | 
