From 8eb6a4db8bb73df76c5cc1d90775d0925a5a6adb Mon Sep 17 00:00:00 2001 From: uruk Date: Sun, 1 Jun 2014 21:44:07 +0200 Subject: CGE2: Add display of mouse cursor. The actual click-handling is not working yet. --- engines/cge2/cge2.cpp | 3 + engines/cge2/cge2.h | 3 + engines/cge2/cge2_main.cpp | 27 +++++-- engines/cge2/events.cpp | 174 +++++++++++++++++++++++++++++++++++++++++++-- engines/cge2/events.h | 27 +++++++ engines/cge2/vga13h.cpp | 14 ++-- engines/cge2/vga13h.h | 2 +- 7 files changed, 233 insertions(+), 17 deletions(-) diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp index d0d5740e7a..c4ae02757a 100644 --- a/engines/cge2/cge2.cpp +++ b/engines/cge2/cge2.cpp @@ -68,6 +68,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription) _busyPtr = nullptr; for (int i = 0; i < 2; i++) _vol[i] = nullptr; + _eventManager = nullptr; _quitFlag = false; _bitmapPalette = nullptr; @@ -112,6 +113,7 @@ void CGE2Engine::init() { for (int i = 0; i < kMaxPoint; i++) _point[i] = new V3D(); _sys = new System(this); + _eventManager = new EventManager(this); } void CGE2Engine::deinit() { @@ -140,6 +142,7 @@ void CGE2Engine::deinit() { delete _point[i]; } delete _sys; + delete _eventManager; } bool CGE2Engine::hasFeature(EngineFeature f) const { diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h index c7c16d4224..925cb67f50 100644 --- a/engines/cge2/cge2.h +++ b/engines/cge2/cge2.h @@ -55,6 +55,7 @@ class Talk; class Hero; class Bitmap; class System; +class EventManager; #define kScrWidth 320 #define kScrHeight 240 @@ -131,6 +132,7 @@ public: void mainLoop(); void handleFrame(); Sprite *locate(int ref); + Sprite *spriteAt(int x, int y); bool isHero(Sprite *spr); void loadUser(); void checkSaySwitch(); @@ -234,6 +236,7 @@ public: System *_sys; Sprite *_busyPtr; Sprite *_vol[2]; + EventManager *_eventManager; private: void init(); void deinit(); diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp index f468d15d66..e9fc11bd86 100644 --- a/engines/cge2/cge2_main.cpp +++ b/engines/cge2/cge2_main.cpp @@ -385,6 +385,11 @@ void CGE2Engine::caveUp(int cav) { _sprite = _vga->_showQ->first(); _vga->sunrise(_vga->_sysPal); + _dark = false; + + if (!_startupMode) + _mouse->on(); + feedSnail(_vga->_showQ->locate(bakRef + 255), kNear, _heroTab[_sex]->_ptr); //setDrawColors(); - It's only for debugging purposes. Can be left out for now. } @@ -414,8 +419,7 @@ void CGE2Engine::mainLoop() { handleFrame(); // Handle any pending events - //_eventManager->poll(); - warning("STUB: CGE2Engine::mainLoop() - Event handling is missing!"); + _eventManager->poll(); // Check shouldQuit() _quitFlag = shouldQuit(); @@ -426,8 +430,7 @@ void CGE2Engine::handleFrame() { uint32 millis = g_system->getMillis(); while (!_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) { // Handle any pending events - //_eventManager->poll(); - warning("STUB: CGE2Engine::handleFrame() - Event handling is missing!"); + _eventManager->poll(); if (millis >= (_lastTick + kGameTickDelay)) { // Dispatch the tick to any active objects @@ -476,8 +479,7 @@ void CGE2Engine::tick() { } } - //Mouse->Tick(); - warning("STUB: CGE2Engine::tick() - Mouse"); + _mouse->tick(); } void CGE2Engine::loadMap(int cav) { @@ -756,4 +758,17 @@ void CGE2Engine::switchHero(bool sex) { warning("STUB: CGE2Engine::switchHero()"); } +Sprite *CGE2Engine::spriteAt(int x, int y) { + Sprite *spr = NULL, *tail = _vga->_showQ->last(); + if (tail) { + for (spr = tail->_prev; spr; spr = spr->_prev) { + if (!spr->_flags._hide && !spr->_flags._tran) { + if (spr->shp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y)) + break; + } + } + } + return spr; +} + } // End of namespace CGE2 diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp index 670ea61c93..5c0300f1e1 100644 --- a/engines/cge2/events.cpp +++ b/engines/cge2/events.cpp @@ -63,23 +63,187 @@ void Keyboard::newKeyboard(Common::Event &event) { /*----------------- MOUSE interface -----------------*/ Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) { - warning("STUB: Mouse::Mouse() - Recheck the whole implementation!!!"); + _hold = NULL; + _hx = 0; + _hy = 0; + _exist = true; + _buttons = 0; + _busy = NULL; + _active = false; + _flags._kill = false; + + setSeq(_stdSeq8); + + BitmapPtr *MC = new BitmapPtr[3]; + MC[0] = new Bitmap(_vm, "MOUSE"); + MC[1] = new Bitmap(_vm, "DUMMY"); + MC[2] = NULL; + setShapeList(MC, 2); + + step(1); + on(); + off(); } Mouse::~Mouse() { - warning("STUB: Mouse::~Mouse()"); + off(); } void Mouse::on() { - warning("STUB: Mouse::on()"); + if (_seqPtr && _exist) { + _active = true; + step(0); + if (_busy) + _busy->step(0); + } } void Mouse::off() { - warning("STUB: Mouse::off()"); + if (_seqPtr == 0) { + if (_exist) { + _active = false; + } + + step(1); + if (_busy) + _busy->step(1); + } } void Mouse::newMouse(Common::Event &event) { - warning("STUB: Mouse::newMouse()"); + if (!_active) + return; + + CGE2Event &evt = _vm->_eventManager->getNextEvent(); + evt._x = event.mouse.x; + evt._y = event.mouse.y; + evt._keyCode = Common::KEYCODE_INVALID; + evt._spritePtr = _vm->spriteAt(evt._x, evt._y); + + switch (event.type) { + case Common::EVENT_MOUSEMOVE: + evt._mask = kMouseRoll; + break; + case Common::EVENT_LBUTTONDOWN: + evt._mask = kMouseLeftDown; + _buttons |= 1; + break; + case Common::EVENT_LBUTTONUP: + evt._mask = kMouseLeftUp; + _buttons &= ~1; + break; + case Common::EVENT_RBUTTONDOWN: + evt._mask = kMouseRightDown; + _buttons |= 2; + break; + case Common::EVENT_RBUTTONUP: + evt._mask = kMouseRightUp; + _buttons &= ~2; + break; + default: + break; + } +} + +/*----------------- EventManager interface -----------------*/ + +EventManager::EventManager(CGE2Engine *vm) : _vm(vm){ + _eventQueueHead = 0; + _eventQueueTail = 0; + memset(&_eventQueue, 0, kEventMax * sizeof(CGE2Event)); + memset(&_event, 0, sizeof(Common::Event)); +} + +void EventManager::poll() { + while (g_system->getEventManager()->pollEvent(_event)) { + switch (_event.type) { + case Common::EVENT_KEYDOWN: + case Common::EVENT_KEYUP: + // Handle keyboard events + _vm->_keyboard->newKeyboard(_event); + handleEvents(); + break; + case Common::EVENT_MOUSEMOVE: + case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONDOWN: + case Common::EVENT_RBUTTONUP: + // Handle mouse events + _vm->_mouse->newMouse(_event); + handleEvents(); + break; + default: + break; + } + } +} + +void EventManager::handleEvents() { + while (_eventQueueTail != _eventQueueHead) { + CGE2Event e = _eventQueue[_eventQueueTail]; + if (e._mask) { + if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold) + _vm->_mouse->_hold->touch(e._mask | kEventAttn, e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y, e._keyCode); + + // update mouse cursor position + if (e._mask & kMouseRoll) + _vm->_mouse->gotoxyz(e._x, kWorldHeight - e._y); + + // activate current touched SPRITE + if (e._spritePtr) { + if (e._mask & kEventKeyb) + e._spritePtr->touch(e._mask, e._x, e._y, e._keyCode); + else + e._spritePtr->touch(e._mask, e._x - e._spritePtr->_pos2D.x, e._y - e._spritePtr->_pos2D.y, e._keyCode); + } else if (_vm->_sys) + _vm->_sys->touch(e._mask, e._x, e._y, e._keyCode); + + if (e._mask & kMouseLeftDown) { + _vm->_mouse->_hold = e._spritePtr; + if (_vm->_mouse->_hold) { + _vm->_mouse->_hold->_flags._hold = true; + + if (_vm->_mouse->_hold->_flags._drag) { + _vm->_mouse->_hx = e._x - _vm->_mouse->_hold->_pos2D.x; + _vm->_mouse->_hy = e._y - _vm->_mouse->_hold->_pos2D.y; + } + } + } + + if (e._mask & kMouseLeftUp) { + if (_vm->_mouse->_hold) { + _vm->_mouse->_hold->_flags._hold = false; + _vm->_mouse->_hold = NULL; + } + } + ///Touched = e.Ptr; + + // discard Text if button released + if (e._mask & (kMouseLeftUp | kMouseRightUp)) + _vm->killText(); + } + _eventQueueTail = (_eventQueueTail + 1) % kEventMax; + } + if (_vm->_mouse->_hold) { + if (_vm->_mouse->_hold->_flags._drag) + _vm->_mouse->_hold->gotoxyz(_vm->_mouse->_pos2D.x - _vm->_mouse->_hx, kWorldHeight - _vm->_mouse->_pos2D.y - _vm->_mouse->_hy); + } +} + +void EventManager::clearEvent(Sprite *spr) { + if (spr) { + for (uint16 e = _eventQueueTail; e != _eventQueueHead; e = (e + 1) % kEventMax) + if (_eventQueue[e]._spritePtr == spr) + _eventQueue[e]._mask = 0; + } else + _eventQueueTail = _eventQueueHead; +} + +CGE2Event &EventManager::getNextEvent() { + CGE2Event &evt = _eventQueue[_eventQueueHead]; + _eventQueueHead = (_eventQueueHead + 1) % kEventMax; + + return evt; } } // End of namespace CGE2 diff --git a/engines/cge2/events.h b/engines/cge2/events.h index 99f017bae3..39fbf536b9 100644 --- a/engines/cge2/events.h +++ b/engines/cge2/events.h @@ -65,6 +65,14 @@ public: /*----------------- MOUSE interface -----------------*/ +struct CGE2Event { + uint16 _mask; + uint16 _x; + uint16 _y; + Common::KeyCode _keyCode; + Sprite *_spritePtr; +}; + class Mouse : public Sprite { public: Sprite *_hold; @@ -83,6 +91,25 @@ private: CGE2Engine *_vm; }; +/*----------------- EventManager interface -----------------*/ + +class EventManager { +private: + CGE2Engine *_vm; + Common::Event _event; + CGE2Event _eventQueue[kEventMax]; + uint16 _eventQueueHead; + uint16 _eventQueueTail; + + void handleEvents(); +public: + EventManager(CGE2Engine *vm); + void poll(); + void clearEvent(Sprite *spr); + + CGE2Event &getNextEvent(); +}; + } // End of namespace CGE #endif // #define CGE2_EVENTS_H diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp index bc042a5e5b..8158d6da96 100644 --- a/engines/cge2/vga13h.cpp +++ b/engines/cge2/vga13h.cpp @@ -129,7 +129,7 @@ void Sprite::setShapeList(BitmapPtr *shp, int cnt) { if (shp) { for (int i = 0; i < cnt; i++) { - BitmapPtr p = *shp + i; + BitmapPtr p = *(shp + i); if (p->_w > _siz.x) _siz.x = p->_w; if (p->_h > _siz.y) @@ -472,6 +472,11 @@ void Sprite::step(int nr) { _vm->_waitRef = 0; } +#pragma argsused +void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) { + warning("STUB: Sprite::touch()"); +} + void Sprite::tick() { step(); } @@ -530,7 +535,7 @@ void Sprite::gotoxyz(V2D pos) { ++trim; } _pos2D.x = pos.x; - + if (pos.y < -kPanHeight) { pos.y = -kPanHeight; ++trim; @@ -963,7 +968,7 @@ void Vga::show() { spr->show(); } - //_vm->_mouse->show(); + _vm->_mouse->show(); update(); for (Sprite *spr = _showQ->first(); spr; spr = spr->_next) { @@ -990,8 +995,7 @@ void Vga::show() { spr->_flags._zmov = false; } } - //_vm->_mouse->hide(); - warning("STUB: Vga::show() - Mouse handling is missing!"); + _vm->_mouse->hide(); } void Vga::updateColors() { diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h index 20d97ee4eb..a4829b6947 100644 --- a/engines/cge2/vga13h.h +++ b/engines/cge2/vga13h.h @@ -198,7 +198,7 @@ public: void step(int nr = -1); Seq *setSeq(Seq *seq); CommandHandler::Command *snList(Action type); - //virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode); + virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode); virtual void tick(); void clrHide(void) { if (_ext) _ext->_b0 = NULL; } void sync(Common::Serializer &s); -- cgit v1.2.3