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 |