/* 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. * */ #ifndef GLK_EVENTS_H #define GLK_EVENTS_H #include "common/events.h" #include "graphics/surface.h" #include "glk/utils.h" namespace Glk { #define GAME_FRAME_RATE 100 #define GAME_FRAME_TIME (1000 / GAME_FRAME_RATE) class Window; /** * Event types */ enum EvType { evtype_None = 0, evtype_Timer = 1, evtype_CharInput = 2, evtype_LineInput = 3, evtype_MouseInput = 4, evtype_Arrange = 5, evtype_Redraw = 6, evtype_SoundNotify = 7, evtype_Hyperlink = 8, evtype_VolumeNotify = 9, // ScummVM custom events evtype_Quit = 99 }; /** * Keycodes */ enum Keycode { keycode_Unknown = 0xffffffffU, keycode_Left = 0xfffffffeU, keycode_Right = 0xfffffffdU, keycode_Up = 0xfffffffcU, keycode_Down = 0xfffffffbU, keycode_Return = 0xfffffffaU, keycode_Delete = 0xfffffff9U, keycode_Escape = 0xfffffff8U, keycode_Tab = 0xfffffff7U, keycode_PageUp = 0xfffffff6U, keycode_PageDown = 0xfffffff5U, keycode_Home = 0xfffffff4U, keycode_End = 0xfffffff3U, keycode_Func1 = 0xffffffefU, keycode_Func2 = 0xffffffeeU, keycode_Func3 = 0xffffffedU, keycode_Func4 = 0xffffffecU, keycode_Func5 = 0xffffffebU, keycode_Func6 = 0xffffffeaU, keycode_Func7 = 0xffffffe9U, keycode_Func8 = 0xffffffe8U, keycode_Func9 = 0xffffffe7U, keycode_Func10 = 0xffffffe6U, keycode_Func11 = 0xffffffe5U, keycode_Func12 = 0xffffffe4U, // non standard keycodes keycode_Erase = 0xffffef7fU, keycode_MouseWheelUp = 0xffffeffeU, keycode_MouseWheelDown = 0xffffefffU, keycode_SkipWordLeft = 0xfffff000U, keycode_SkipWordRight = 0xfffff001U, // The last keycode is always = 0x100000000 - keycode_MAXVAL) keycode_MAXVAL = 28U }; /** * List of cursors */ enum CursorId { CURSOR_NONE = 0, CURSOR_ARROW = 1, CURSOR_IBEAM = 2, CURSOR_HAND = 3 }; /** * Event structure */ struct Event { EvType type; Window *window; uint val1, val2; /** * Constructor */ Event() { clear(); } /** * Constructor */ Event(EvType evType, Window *evWindow, uint evVal1, uint evVal2) { type = evType; window = evWindow; val1 = evVal1; val2 = evVal2; } /** * Clear */ void clear() { type = evtype_None; window = nullptr; val1 = val2 = 0; } /** * Boolean cast to allow checking whether event is filled out */ operator bool() const { return type != evtype_None; } }; typedef Event event_t; class EventQueue : public Common::Queue { public: /** * Retrieve a pending event, if any */ Event retrieve() { return empty() ? Event() : pop(); } }; /** * Events manager */ class Events { struct Surface : public Graphics::Surface { Common::Point _hotspot; }; private: EventQueue _eventsPolled; ///< User generated events EventQueue _eventsLogged; ///< Custom events generated by game code Event *_currentEvent; ///< Event pointer passed during event retrieval uint32 _priorFrameTime; ///< Time of prior game frame uint32 _frameCounter; ///< Frame counter bool _redraw; ///< Screen needed redrawing CursorId _cursorId; ///< Current cursor Id Surface _cursors[4]; ///< Cursor pixel data uint _timerMilli; ///< Time in milliseconds between timer events uint _timerTimeExpiry; ///< When to trigger next timer event private: /** * Initialize the cursor graphics */ void initializeCursors(); /** * Checks for whether it's time for the next game frame */ void checkForNextFrameCounter(); /** * Dispatches an event */ void dispatchEvent(Event &ev, bool polled); /** * Poll for user events */ void pollEvents(); /** * Handle a key down event */ void handleKeyDown(const Common::KeyState &ks); /** * Handle scroll events */ void handleScroll(bool wheelUp); /** * Handle mouse move events */ void handleMouseMove(const Point &pos); /** * Handle mouse down events */ void handleButtonDown(bool isLeft, const Point &pos); /** * Handle mouse up events */ void handleButtonUp(bool isLeft, const Point &pos); /** * Returns true if the passed keycode is for the Ctrl or Alt keys */ bool isModifierKey(const Common::KeyCode &keycode) const; public: bool _forceClick; public: /** * Constructor */ Events(); /** * Destructor */ ~Events(); /** * Get any pending event */ void getEvent(event_t *event, bool polled); /** * Store an event for retrieval */ void store(EvType type, Window *win, uint val1 = 0, uint val2 = 0); /** * Wait for a keypress */ uint getKeypress(); /** * Wait for a keyboard or mouse press */ void waitForPress(); /** * Get the total number of frames played */ uint32 getTotalPlayTicks() const { return _frameCounter; } /** * Set the total number of frames played */ void setTotalPlayTicks(uint frames) { _frameCounter = frames; } /** * Flags the screen for redrawing */ void redraw() { _redraw = true; } /** * Sets the current cursor */ void setCursor(CursorId cursorId); /** * Sets whether the mouse cursor is visible * @remarks Normally the cursor is visible for all games, even for those that didn't have mouse originally, * so as to allow for common Glk functionality for selecting ranges of text */ void showMouseCursor(bool visible); /** * Set a timer interval * @param milli Time in millieseconds for intervals, or 0 for off */ void setTimerInterval(uint milli); /** * Returns true if it's time for a timer event */ bool isTimerExpired() const; }; } // End of namespace Glk #endif