scummvm/engines/glk/events.h

309 lines
6.5 KiB
C++

/* 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<Event> {
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