diff options
| author | Max Horn | 2002-09-22 04:03:45 +0000 | 
|---|---|---|
| committer | Max Horn | 2002-09-22 04:03:45 +0000 | 
| commit | 6bb2e335c79b253ca22f0d94a3267f9f4320d29b (patch) | |
| tree | 21ddf31487d4a75b8ab3217b702f6358dd4cf71b | |
| parent | c0855df3820662a91aab184ff15d50c371b4c208 (diff) | |
| download | scummvm-rg350-6bb2e335c79b253ca22f0d94a3267f9f4320d29b.tar.gz scummvm-rg350-6bb2e335c79b253ca22f0d94a3267f9f4320d29b.tar.bz2 scummvm-rg350-6bb2e335c79b253ca22f0d94a3267f9f4320d29b.zip | |
NewGUI now has its own event loop; this may cause some regression
svn-id: r5001
| -rw-r--r-- | gui/newgui.cpp | 145 | ||||
| -rw-r--r-- | gui/newgui.h | 32 | ||||
| -rw-r--r-- | scumm/scummvm.cpp | 19 | 
3 files changed, 93 insertions, 103 deletions
| diff --git a/gui/newgui.cpp b/gui/newgui.cpp index f8dff32c90..1867ddd6bd 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -26,14 +26,20 @@  #include "dialog.h"  #include "scumm/dialogs.h" +  #ifdef _MSC_VER +  #	pragma warning( disable : 4068 ) // unknown pragma +  #endif +  /*   * TODO list   * - get a nicer font which contains diacrits (ŠšŸ§Žˆ etc.) - * - add more widgets + * - add more widgets: edit field, popup, radio buttons, ... + * + * Other ideas:   * - allow multi line (l/c/r aligned) text via StaticTextWidget ?   * - add "close" widget to all dialogs (with a flag to turn it off) ?   * - make dialogs "moveable" ? @@ -73,8 +79,8 @@ static byte guifont[] = {  // Constructor  NewGui::NewGui(Scumm *s) : _s(s), _system(s->_system), _screen(0), -	_use_alpha_blending(true), _need_redraw(false), _prepare_for_gui(true), -	_currentKeyDown(0), _cursorAnimateCounter(0) +	_use_alpha_blending(true), _need_redraw(false), +	_currentKeyDown(0), _cursorAnimateCounter(0), _cursorAnimateTimer(0)  {  	// Setup some default GUI colors.  	// TODO - either use nicer values, or maybe make this configurable? @@ -88,106 +94,105 @@ NewGui::NewGui(Scumm *s) : _s(s), _system(s->_system), _screen(0),  	memset(_cursor, 0xFF, sizeof(_cursor));  } -void NewGui::loop() +void NewGui::runLoop()  { -	Dialog *activeDialog = _dialogStack.top(); -	int i; +	if (!isActive()) +		return; -	if (_prepare_for_gui) { -		saveState(); +	Dialog *activeDialog; +	int i; +	OSystem::Event event; -		_eventList.clear(); -		_currentKeyDown = 0; -		 -		_lastClick.x = _lastClick.y = 0; -		_lastClick.time = 0; -		_lastClick.count = 0; +	saveState(); -		_prepare_for_gui = false; -	} +	_currentKeyDown = 0; +	 +	_lastClick.x = _lastClick.y = 0; +	_lastClick.time = 0; +	_lastClick.count = 0; -	activeDialog->handleTickle(); +	while (isActive()) { +		activeDialog = _dialogStack.top(); -	if (_need_redraw) { -		// Restore the overlay to its initial state, then draw all dialogs. -		// This is necessary to get the blending right. -		_system->clear_overlay(); -		_system->grab_overlay(_screen, _screen_pitch); -		for (i = 0; i < _dialogStack.size(); i++) -			_dialogStack[i]->draw(); -		_need_redraw = false; -	} +		activeDialog->handleTickle(); -	animateCursor(); - -	if (_eventList.size() > 0) -	{ -		OSystem::Event t; -		 -		for (i = 0; i < _eventList.size(); i++) -		{ -			t = _eventList[i]; +		if (_need_redraw) { +			// Restore the overlay to its initial state, then draw all dialogs. +			// This is necessary to get the blending right. +			_system->clear_overlay(); +			_system->grab_overlay(_screen, _screen_pitch); +			for (i = 0; i < _dialogStack.size(); i++) +				_dialogStack[i]->draw(); +			_need_redraw = false; +		} -			switch(t.event_code) { +		animateCursor(); +	 +		_system->update_screen();		 + +		while (_system->poll_event(&event)) { +			switch(event.event_code) {  				case OSystem::EVENT_KEYDOWN: -					activeDialog->handleKeyDown((byte)t.kbd.ascii, t.kbd.flags); +					activeDialog->handleKeyDown((byte)event.kbd.ascii, event.kbd.flags);  					// init continuous event stream -					_currentKeyDown = t.kbd.ascii; -					_currentKeyDownFlags = t.kbd.flags; +					_currentKeyDown = event.kbd.ascii; +					_currentKeyDownFlags = event.kbd.flags;  					_keyRepeatEvenCount = 1;  					_keyRepeatLoopCount = 0;  					break;  				case OSystem::EVENT_KEYUP: -					activeDialog->handleKeyUp((byte)t.kbd.ascii, t.kbd.flags); -					if (t.kbd.ascii == _currentKeyDown) +					activeDialog->handleKeyUp((byte)event.kbd.ascii, event.kbd.flags); +					if (event.kbd.ascii == _currentKeyDown)  						// only stop firing events if it's the current key  						_currentKeyDown = 0;  					break;  				case OSystem::EVENT_MOUSEMOVE: -					activeDialog->handleMouseMoved(t.mouse.x - activeDialog->_x, t.mouse.y - activeDialog->_y, 0); +					_system->set_mouse_pos(event.mouse.x, event.mouse.y); +					activeDialog->handleMouseMoved(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 0);  					break; -				// We don't distinguish between mousebuttons (for now at least) +				// We don'event distinguish between mousebuttons (for now at least)  				case OSystem::EVENT_LBUTTONDOWN:  				case OSystem::EVENT_RBUTTONDOWN: {  					uint32 time = _system->get_msecs();  					if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) -					      && ABS(_lastClick.x - t.mouse.x) < 3 -					      && ABS(_lastClick.y - t.mouse.y) < 3) { +					      && ABS(_lastClick.x - event.mouse.x) < 3 +					      && ABS(_lastClick.y - event.mouse.y) < 3) {  						_lastClick.count++;  					} else { -						_lastClick.x = t.mouse.x; -						_lastClick.y = t.mouse.y; +						_lastClick.x = event.mouse.x; +						_lastClick.y = event.mouse.y;  						_lastClick.count = 1;  					}  					_lastClick.time = time;  					} -					activeDialog->handleMouseDown(t.mouse.x - activeDialog->_x, t.mouse.y - activeDialog->_y, 1, _lastClick.count); +					activeDialog->handleMouseDown(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count);  					break;  				case OSystem::EVENT_LBUTTONUP:  				case OSystem::EVENT_RBUTTONUP: -					activeDialog->handleMouseUp(t.mouse.x - activeDialog->_x, t.mouse.y - activeDialog->_y, 1, _lastClick.count); +					activeDialog->handleMouseUp(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y, 1, _lastClick.count);  					break;  			}  		} -		_eventList.clear(); -	} - -	// check if event should be sent again (keydown) -	if (_currentKeyDown != 0) -	{ -		// if only fired once, wait longer -		if ( _keyRepeatLoopCount >= ((_keyRepeatEvenCount > 1) ? 2 : 4) ) -		//                                                           ^  loops to wait first event -		//                                                       ^      loops to wait after first event +		// check if event should be sent again (keydown) +		if (_currentKeyDown != 0)  		{ -			// fire event -			activeDialog->handleKeyDown(_currentKeyDown, _currentKeyDownFlags); -			_keyRepeatEvenCount++; -			_keyRepeatLoopCount = 0; +			// if only fired once, wait longer +			if ( _keyRepeatLoopCount >= ((_keyRepeatEvenCount > 1) ? 2 : 4) ) +			//                                                           ^  loops to wait first event +			//                                                       ^      loops to wait after first event +			{ +				// fire event +				activeDialog->handleKeyDown(_currentKeyDown, _currentKeyDownFlags); +				_keyRepeatEvenCount++; +				_keyRepeatLoopCount = 0; +			} +			_keyRepeatLoopCount++;  		} -		_keyRepeatLoopCount++; + +		// Delay for a moment +		_system->delay_msecs(10);  	}  } @@ -227,9 +232,6 @@ void NewGui::restoreState()  void NewGui::openDialog(Dialog *dialog)  { -	if (_dialogStack.empty()) -		_prepare_for_gui = true; -  	_dialogStack.push(dialog);  	_need_redraw = true;  } @@ -458,9 +460,10 @@ void NewGui::drawBitmap(uint32 bitmap[8], int x, int y, int16 color)  //  void NewGui::animateCursor()  { -	if (0 == (_cursorAnimateCounter & 0x3)) { +	int time = _system->get_msecs();  +	if (time > _cursorAnimateTimer + kCursorAnimateDelay) {  		const byte colors[4] = { 15, 15, 7, 8 }; -		const byte color = colors[(_cursorAnimateCounter >> 2) & 3]; +		const byte color = colors[_cursorAnimateCounter];  		int i;  		for (i = 0; i < 16; i++) { @@ -471,6 +474,8 @@ void NewGui::animateCursor()  		}  		_system->set_mouse_cursor(_cursor, 16, 16, 8, 8); + +		_cursorAnimateTimer = time; +		_cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4;  	} -	_cursorAnimateCounter++;  } diff --git a/gui/newgui.h b/gui/newgui.h index 1f38558097..ba96a8590b 100644 --- a/gui/newgui.h +++ b/gui/newgui.h @@ -23,7 +23,6 @@  #include "scummsys.h"  #include "system.h"	// For events -#include "common/list.h"  class Dialog;  class Scumm; @@ -38,7 +37,8 @@ enum {  };  enum { -	kDoubleClickDelay = 500    // milliseconds +	kDoubleClickDelay = 500,    // milliseconds +	kCursorAnimateDelay = 500  };  // Extremly simple stack class, doesn't even do any error checking (for now) @@ -57,25 +57,19 @@ public:  	Dialog	*operator [](int i)	{ return _stack[i]; }  }; -typedef ScummVM::List<OSystem::Event> EventList; -  // This class hopefully will replace the old Gui class completly one day   class NewGui {  	friend class Dialog;  public: -	int16 _color, _shadowcolor; -	int16 _bgcolor; -	int16 _textcolor; -	int16 _textcolorhi; -	void loop(); +	// Main entry for the GUI: this will start an event loop that keeps running +	// until no dialogs are active anymore. +	void runLoop();  	bool isActive()	{ return ! _dialogStack.empty(); }  	NewGui(Scumm *s); -	void handleEvent(const OSystem::Event &event) { _eventList.push_back(event); } -  protected:  	Scumm		*_s;  	OSystem		*_system; @@ -84,7 +78,6 @@ protected:  	bool		_use_alpha_blending;  	bool		_need_redraw; -	bool		_prepare_for_gui;  	DialogStack	_dialogStack;  	// for continuous events (keyDown) @@ -102,13 +95,10 @@ protected:  		int count;	// How often was it already pressed?  	} _lastClick; -	// List of events to be handled -	EventList	_eventList; -	 -  	// mouse cursor state  	bool		_oldCursorMode;  	int			_cursorAnimateCounter; +	int			_cursorAnimateTimer;  	byte		_cursor[2048];  	void saveState(); @@ -117,10 +107,18 @@ protected:  	void openDialog(Dialog *dialog);  	void closeTopDialog(); +	void loop(); +  	void animateCursor();  public: -	// Drawing +	// Theme colors +	int16 _color, _shadowcolor; +	int16 _bgcolor; +	int16 _textcolor; +	int16 _textcolorhi; + +	// Drawing primitives  	int16 *getBasePtr(int x, int y);  	void box(int x, int y, int width, int height);  	void line(int x, int y, int x2, int y2, int16 color); diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 55516d47f6..156a37f52c 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -910,6 +910,7 @@ void Scumm::pauseDialog()  	if (!_pauseDialog)  		_pauseDialog = new PauseDialog(_newgui, this);  	_pauseDialog->open(); +	_newgui->runLoop();  }  void Scumm::saveloadDialog() @@ -917,6 +918,7 @@ void Scumm::saveloadDialog()  	if (!_saveLoadDialog)  		_saveLoadDialog = new SaveLoadDialog(_newgui, this);  	_saveLoadDialog->open(); +	_newgui->runLoop();  }  void Scumm::optionsDialog() @@ -924,6 +926,7 @@ void Scumm::optionsDialog()  	if (!_optionsDialog)  		_optionsDialog = new OptionsDialog(_newgui, this);  	_optionsDialog->open(); +	_newgui->runLoop();  }  void Scumm::shutDown(int i) @@ -1286,19 +1289,6 @@ void Scumm::waitForTimer(int msec_delay) {  	for(;;) {  		while (_system->poll_event(&event)) { -			// if newgui is running, copy event to EventList, and let the GUI handle it itself -			// we might consider this approach for ScummLoop as well, and clean up the current mess -			if (_newgui->isActive()) { -				if (event.event_code == OSystem::EVENT_MOUSEMOVE) { -					mouse.x = event.mouse.x; -					mouse.y = event.mouse.y; -					_system->set_mouse_pos(event.mouse.x, event.mouse.y); -					_system->update_screen(); -				} -				_newgui->handleEvent(event); -				continue; -			} -  			switch(event.event_code) {  			case OSystem::EVENT_KEYDOWN:  				if (event.kbd.keycode >= '0' && event.kbd.keycode<='9' @@ -1413,9 +1403,6 @@ void Scumm::mainRun()  		if (_gui->isActive()) {  			_gui->loop();  			delta = 5; -		} else if (_newgui->isActive()) { -			_newgui->loop(); -			delta = 5;  		} else {  			delta = scummLoop(delta);  			if (delta < 1)	// Ensure we don't get into a loop | 
