From e37019943cb77d8c0735b330339a139430202fd8 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 30 Jun 2012 00:12:04 +0200 Subject: Event handling, CApplication and switch to c++-11 - added/changed event structs and event queue in common/event.h - added event handling and some minor functions in CApplication - switched to --std=c++11 because of union in Event struct --- src/app/app.cpp | 332 ++++++++++++++++++++++++++----------------- src/app/app.h | 80 +++++++---- src/common/event.cpp | 164 +++++++++------------ src/common/event.h | 269 +++++++++++++++++++++++++---------- src/common/key.h | 34 +++++ src/common/misc.h | 2 +- src/graphics/common/engine.h | 2 +- 7 files changed, 544 insertions(+), 339 deletions(-) create mode 100644 src/common/key.h (limited to 'src') diff --git a/src/app/app.cpp b/src/app/app.cpp index 4005707..4367852 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -42,14 +42,14 @@ struct ApplicationPrivate //! Joystick SDL_Joystick *joystick; //! Index of joystick device - int joystickDevice; + int joystickIndex; ApplicationPrivate() { memset(¤tEvent, 0, sizeof(SDL_Event)); surface = NULL; joystick = NULL; - joystickDevice = 0; + joystickIndex = 0; } }; @@ -60,21 +60,22 @@ CApplication::CApplication() m_exitCode = 0; m_iMan = new CInstanceManager(); - m_event = new CEvent(m_iMan); - m_engine = 0; - m_robotMain = 0; - m_sound = 0; + m_eventQueue = new CEventQueue(m_iMan); + + m_engine = NULL; + m_robotMain = NULL; + m_sound = NULL; m_keyState = 0; m_axeKey = Math::Vector(0.0f, 0.0f, 0.0f); m_axeJoy = Math::Vector(0.0f, 0.0f, 0.0f); - m_vidMemTotal = 0; - m_active = false; - m_activateApp = false; - m_ready = false; - m_joystick = false; + m_active = false; + m_activateApp = false; + m_ready = false; + m_joystickEnabled = false; + m_time = 0.0f; for (int i = 0; i < 32; i++) @@ -84,13 +85,8 @@ CApplication::CApplication() m_windowTitle = "COLOBOT"; - m_appUseZBuffer = true; - m_appUseStereo = true; m_showStats = false; m_debugMode = false; - m_audioState = true; - m_audioTrack = true; - m_niceMouse = false; m_setupMode = true; ResetKey(); @@ -101,6 +97,9 @@ CApplication::~CApplication() delete m_private; m_private = NULL; + delete m_eventQueue; + m_eventQueue = NULL; + delete m_iMan; m_iMan = NULL; } @@ -116,14 +115,6 @@ Error CApplication::ParseArguments(int argc, char *argv[]) m_showStats = true; SetDebugMode(true); } - else if (arg == "-audiostate") - { - m_audioState = false; - } - else if (arg == "-audiotrack") - { - m_audioTrack = false; - } // TODO else {} report invalid argument } @@ -132,43 +123,32 @@ Error CApplication::ParseArguments(int argc, char *argv[]) bool CApplication::Create() { -/* -TODO - Full screen by default unless in debug mode - if (! m_debugMode) - m_deviceConfig.fullScreen = true; - - int full = 0; - if (GetProfileInt("Device", "FullScreen", full)) - m_deviceConfig.fullScreen = full == 1; -*/ - // Temporarily -- only in windowed mode m_deviceConfig.fullScreen = false; -/* -TODO // Create the 3D engine. - m_engine = new CEngine(m_iMan, this); + m_engine = new Gfx::CEngine(m_iMan, this); + /* TODO // Initialize the app's custom scene stuff if (! m_engine->OneTimeSceneInit()) { SystemDialog(SDT_ERROR, "COLOBOT - Error", m_engine->RetError()); return false; - } + }*/ - // Create the sound instance. +/* // Create the sound instance. m_sound = new CSound(m_iMan); // Create the robot application. - m_robotMain = new CRobotMain(m_iMan); -*/ + m_robotMain = new CRobotMain(m_iMan); */ - Uint32 initFlags = SDL_INIT_VIDEO; - if (m_joystick) - initFlags |= SDL_INIT_JOYSTICK; + + /* SDL initialization sequence */ + + + Uint32 initFlags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; if (SDL_Init(initFlags) < 0) { @@ -177,7 +157,7 @@ TODO } const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - if (! videoInfo) + if (videoInfo == NULL) { SystemDialog( SDT_ERROR, "COLOBOT - Error", "SDL error while getting video info:\n " + std::string(SDL_GetError()) ); return false; @@ -219,7 +199,7 @@ TODO m_private->surface = SDL_SetVideoMode(m_deviceConfig.width, m_deviceConfig.height, m_deviceConfig.bpp, videoFlags); - if (! m_private->surface) + if (m_private->surface == NULL) { SystemDialog( SDT_ERROR, "COLOBT - Error", std::string("SDL error while setting video mode:\n") + std::string(SDL_GetError()) ); @@ -228,38 +208,19 @@ TODO SDL_WM_SetCaption(m_windowTitle.c_str(), m_windowTitle.c_str()); + // Enable translating key codes of key press events to unicode chars SDL_EnableUNICODE(1); + // Enable joystick event generation + SDL_JoystickEventState(SDL_ENABLE); -/* -TODO - InitJoystick(); + // For now, enable joystick for testing + SetJoystickEnabled(true); - if ( !GetProfileInt("Setup", "Sound3D", b3D) ) - { - b3D = true; - } - m_pSound->SetDebugMode(m_bDebugMode); - m_pSound->Create(m_hWnd, b3D); - m_pSound->CacheAll(); - m_pSound->SetState(m_bAudioState); - m_pSound->SetAudioTrack(m_bAudioTrack); - m_pSound->SetCDpath(m_CDpath); - - // First execution? - if ( !GetProfileInt("Setup", "ObjectDirty", iValue) ) - { - m_pD3DEngine->FirstExecuteAdapt(true); - } - - // Creates the file colobot.ini at the first execution. - m_pRobotMain->CreateIni(); + // TODO ... - m_pRobotMain->ChangePhase(PHASE_WELCOME2); - m_engine->TimeInit(); -*/ // The app is ready to go m_ready = true; @@ -269,6 +230,9 @@ TODO void CApplication::Destroy() { + delete m_engine; + m_engine = NULL; + if (m_private->joystick != NULL) { SDL_JoystickClose(m_private->joystick); @@ -283,6 +247,19 @@ void CApplication::Destroy() SDL_Quit(); } +bool CApplication::OpenJoystick() +{ + m_private->joystick = SDL_JoystickOpen(m_private->joystickIndex); + if (m_private->joystick == NULL) + return false; +} + + +void CApplication::CloseJoystick() +{ + SDL_JoystickClose(m_private->joystick); +} + int CApplication::Run() { m_active = true; @@ -312,9 +289,9 @@ int CApplication::Run() if (m_active && m_ready) { Event event; - while (m_event->GetEvent(event)) + while (m_eventQueue->GetEvent(event)) { - if (event.event == EVENT_QUIT) + if (event.type == EVENT_QUIT) { goto end; // exit both loops } @@ -322,11 +299,6 @@ int CApplication::Run() //m_robotMain->EventProcess(event); } - //if ( !RetNiceMouse()) - //{ - // SetMouseType(m_engine->RetMouseType()); - //} - // If an error occurs, push quit event to the queue if (! Render()) { @@ -345,52 +317,135 @@ end: return m_exitCode; } +//! Translates SDL press state to PressState +PressState TranslatePressState(unsigned char state) +{ + if (state == SDL_PRESSED) + return STATE_PRESSED; + else + return STATE_RELEASED; +} + +/** Conversion of the position of the mouse to the following coordinates: + +x: 0=left, 1=right + +y: 0=down, 1=up +*/ +Math::Point CApplication::WindowToInterfaceCoords(int x, int y) +{ + return Math::Point((float)x / (float)m_deviceConfig.width, + 1.0f - (float)y / (float)m_deviceConfig.height); +} + + void CApplication::ParseEvent() { -/* Event event; + Event event; - if (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) + if ( (m_private->currentEvent.type == SDL_KEYDOWN) || + (m_private->currentEvent.type == SDL_KEYUP) ) { - if (m_private->currentEvent.button.button == SDL_BUTTON_LEFT) - event.event = EVENT_LBUTTONDOWN; - else if (m_private->currentEvent.button.button == SDL_BUTTON_RIGHT) - event.event = EVENT_RBUTTONDOWN; + if (m_private->currentEvent.type == SDL_KEYDOWN) + event.type = EVENT_KEY_DOWN; + else + event.type = EVENT_KEY_UP; + + event.data.key.key = m_private->currentEvent.key.keysym.sym; + event.data.key.mod = m_private->currentEvent.key.keysym.mod; + event.data.key.state = TranslatePressState(m_private->currentEvent.key.state); + event.data.key.unicode = m_private->currentEvent.key.keysym.unicode; } - else if (m_private->currentEvent.type == SDL_MOUSEBUTTONUP) + else if ( (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) || + (m_private->currentEvent.type == SDL_MOUSEBUTTONUP) ) { - if (m_private->currentEvent.button.button == SDL_BUTTON_LEFT) - event.event = EVENT_LBUTTONUP; - else if (m_private->currentEvent.button.button == SDL_BUTTON_RIGHT) - event.event = EVENT_RBUTTONUP; + if (m_private->currentEvent.type == SDL_MOUSEBUTTONDOWN) + event.type = EVENT_MOUSE_BUTTON_DOWN; + else + event.type = EVENT_MOUSE_BUTTON_UP; + + event.data.mouseButton.button = m_private->currentEvent.button.button; + event.data.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state); + event.data.mouseButton.pos = WindowToInterfaceCoords(m_private->currentEvent.button.x, m_private->currentEvent.button.y); } else if (m_private->currentEvent.type == SDL_MOUSEMOTION) { - event.event = EVENT_MOUSEMOVE; + event.type = EVENT_MOUSE_MOVE; + + event.data.mouseMove.state = TranslatePressState(m_private->currentEvent.button.state); + event.data.mouseMove.pos = WindowToInterfaceCoords(m_private->currentEvent.button.x, m_private->currentEvent.button.y); } - else if (m_private->currentEvent.type == SDL_KEYDOWN) + // TODO: joystick state polling instead of getting events + else if (m_private->currentEvent.type == SDL_JOYAXISMOTION) { - event.event = EVENT_KEYDOWN; + event.type = EVENT_JOY_AXIS; + + event.data.joyAxis.axis = m_private->currentEvent.jaxis.axis; + event.data.joyAxis.value = m_private->currentEvent.jaxis.value; } - else if (m_private->currentEvent.type == SDL_KEYUP) + else if ( (m_private->currentEvent.type == SDL_JOYBUTTONDOWN) || + (m_private->currentEvent.type == SDL_JOYBUTTONUP) ) { - event.event = EVENT_KEYUP; - } + if (m_private->currentEvent.type == SDL_JOYBUTTONDOWN) + event.type = EVENT_JOY_BUTTON_DOWN; + else + event.type = EVENT_JOY_BUTTON_UP; - if (m_robotMain != NULL && event.event != EVENT_NULL) - { - m_robotMain->EventProcess(event); + event.data.joyButton.button = m_private->currentEvent.jbutton.button; + event.data.joyButton.state = TranslatePressState(m_private->currentEvent.jbutton.state); } - if (m_engine != NULL) + + + if (m_robotMain != NULL && event.type != EVENT_NULL) { - m_engine->MsgProc( hWnd, uMsg, wParam, lParam ); + //m_robotMain->EventProcess(event); } - ProcessEvent(event);*/ + ProcessEvent(event); } void CApplication::ProcessEvent(Event event) { - + // Print the events in debug mode to test the code + if (m_debugMode) + { + switch (event.type) + { + case EVENT_KEY_DOWN: + case EVENT_KEY_UP: + printf("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP"); + printf(" key = %4x\n", event.data.key.key); + printf(" state = %s\n", (event.data.key.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); + printf(" mod = %4x\n", event.data.key.mod); + printf(" unicode = %4x\n", event.data.key.unicode); + break; + case EVENT_MOUSE_MOVE: + printf("EVENT_MOUSE_MOVE:\n"); + printf(" state = %s\n", (event.data.mouseMove.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); + printf(" pos = (%f, %f)\n", event.data.mouseMove.pos.x, event.data.mouseMove.pos.y); + break; + case EVENT_MOUSE_BUTTON_DOWN: + case EVENT_MOUSE_BUTTON_UP: + printf("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP"); + printf(" button = %d\n", event.data.mouseButton.button); + printf(" state = %s\n", (event.data.mouseButton.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); + printf(" pos = (%f, %f)\n", event.data.mouseButton.pos.x, event.data.mouseButton.pos.y); + break; + case EVENT_JOY_AXIS: + printf("EVENT_JOY_AXIS:\n"); + printf(" axis = %d\n", event.data.joyAxis.axis); + printf(" value = %d\n", event.data.joyAxis.value); + break; + case EVENT_JOY_BUTTON_DOWN: + case EVENT_JOY_BUTTON_UP: + printf("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP"); + printf(" button = %d\n", event.data.joyButton.button); + printf(" state = %s\n", (event.data.mouseButton.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); + break; + default: + break; + } + } } bool CApplication::Render() @@ -405,14 +460,27 @@ bool CApplication::Render() return true; } +/** Called in to toggle the pause state of the app. */ void CApplication::Pause(bool pause) { - // TODO -} + static long appPausedCount = 0L; -void CApplication::SetMousePos(Math::Point pos) -{ - // TODO + appPausedCount += ( pause ? +1 : -1 ); + m_ready = appPausedCount == 0; + + // Handle the first pause request (of many, nestable pause requests) + if( pause && ( 1 == appPausedCount ) ) + { + // Stop the scene from animating + //m_engine->TimeEnterGel(); + } + + // Final pause request done + if (appPausedCount == 0) + { + // Restart the scene + //m_engine->TimeExitGel(); + } } void CApplication::StepSimulation(float rTime) @@ -420,32 +488,29 @@ void CApplication::StepSimulation(float rTime) // TODO } -void SetShowStat(bool show) +void CApplication::SetShowStat(bool show) { - // TODO + m_showStats = show; } bool CApplication::RetShowStat() { - // TODO - return false; + return m_showStats; } void CApplication::SetDebugMode(bool mode) { - // TODO + m_debugMode = mode; } bool CApplication::RetDebugMode() { - // TODO - return false; + return m_debugMode; } bool CApplication::RetSetupMode() { - // TODO - return false; + return m_setupMode; } void CApplication::FlushPressKey() @@ -469,35 +534,36 @@ int CApplication::RetKey(int keyRank, int option) return 0; } -void CApplication::SetJoystick(bool enable) -{ - // TODO -} - -bool CApplication::RetJoystick() +void CApplication::SetMousePos(Math::Point pos) { // TODO - return false; } -void SetMouseType(Gfx::MouseType type) +void CApplication::SetMouseType(Gfx::MouseType type) { // TODO } -void SetNiceMouse(bool nice) +void CApplication::SetJoystickEnabled(bool enable) { - // TODO -} + m_joystickEnabled = enable; -bool CApplication::RetNiceMouse() -{ - return false; + if (m_joystickEnabled) + { + if (! OpenJoystick()) + { + m_joystickEnabled = false; + } + } + else + { + CloseJoystick(); + } } -bool CApplication::RetNiceMouseCap() +bool CApplication::RetJoystickEnabled() { - return false; + return m_joystickEnabled; } bool CApplication::WriteScreenShot(char *filename, int width, int height) diff --git a/src/app/app.h b/src/app/app.h index e83652c..9d689e2 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -60,44 +60,55 @@ public: //! Main event loop int Run(); -protected: - //! Cleans up before exit - void Destroy(); - //! Processes an SDL event to Event struct - void ParseEvent(); - //! Handles some incoming events - void ProcessEvent(Event event); - //! Renders the image in window - bool Render(); - -public: + //! Enters the pause mode void Pause(bool pause); - void StepSimulation(float rTime); - void SetMousePos(Math::Point pos); + //! Updates the simulation state + void StepSimulation(float rTime); void SetShowStat(bool show); bool RetShowStat(); + void SetDebugMode(bool mode); bool RetDebugMode(); + bool RetSetupMode(); + void SetJoystickEnabled(bool enable); + bool RetJoystickEnabled(); + void FlushPressKey(); void ResetKey(); void SetKey(int keyRank, int option, int key); int RetKey(int keyRank, int option); - void SetJoystick(bool enable); - bool RetJoystick(); - void SetMouseType(Gfx::MouseType type); - void SetNiceMouse(bool nice); - bool RetNiceMouse(); - bool RetNiceMouseCap(); + void SetMousePos(Math::Point pos); + + //? void SetNiceMouse(bool nice); + //? bool RetNiceMouse(); + //? bool RetNiceMouseCap(); bool WriteScreenShot(char *filename, int width, int height); protected: + //! Cleans up before exit + void Destroy(); + //! Processes an SDL event to Event struct + void ParseEvent(); + //! Handles some incoming events + void ProcessEvent(Event event); + //! Renders the image in window + bool Render(); + + //! Opens the joystick device + bool OpenJoystick(); + //! Closes the joystick device + void CloseJoystick(); + + //! Converts window coords to interface coords + Math::Point WindowToInterfaceCoords(int x, int y); + //HRESULT ConfirmDevice( DDCAPS* pddDriverCaps, D3DDEVICEDESC7* pd3dDeviceDesc ); //HRESULT Initialize3DEnvironment(); //HRESULT Change3DEnvironment(); @@ -113,14 +124,20 @@ protected: void OutputText(long x, long y, char* str); protected: + CInstanceManager* m_iMan; //! Private (SDL-dependent data) ApplicationPrivate* m_private; - CInstanceManager* m_iMan; + //! Global event queue + CEventQueue* m_eventQueue; + //! Current configuration of display device Gfx::DeviceConfig m_deviceConfig; + //! Graphics engine Gfx::CEngine* m_engine; - CEvent* m_event; - CRobotMain* m_robotMain; + //! Sound subsystem CSound* m_sound; + //! Main class of the proper game engine + CRobotMain* m_robotMain; + //! Code to return at exit int m_exitCode; @@ -128,19 +145,22 @@ protected: bool m_active; bool m_activateApp; bool m_ready; - bool m_joystick; - std::string m_windowTitle; - long m_vidMemTotal; - bool m_appUseZBuffer; - bool m_appUseStereo; bool m_showStats; bool m_debugMode; - bool m_audioState; - bool m_audioTrack; - bool m_niceMouse; bool m_setupMode; + bool m_joystickEnabled; + + std::string m_windowTitle; + + //? long m_vidMemTotal; + //? bool m_appUseZBuffer; + //? bool m_appUseStereo; + //? bool m_audioState; + //? bool m_audioTrack; + //? bool m_niceMouse; + int m_keyState; Math::Vector m_axeKey; Math::Vector m_axeJoy; diff --git a/src/common/event.cpp b/src/common/event.cpp index 9af4691..e8595d0 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -1,96 +1,68 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * 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 3 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, see http://www.gnu.org/licenses/. - -// event.cpp - -#include "common/iman.h" -#include "common/event.h" - -#include - - -Event::Event() -{ - event = EVENT_NULL; - param = 0; - axeX = 0.0f; - axeY = 0.0f; - axeZ = 0.0f; - keyState = 0; - rTime = 0.0f; -} - - -// Object's constructor. - -CEvent::CEvent(CInstanceManager* iMan) -{ - m_iMan = iMan; - m_iMan->AddInstance(CLASS_EVENT, this); - - Flush(); -} - -// Object's destructor. - -CEvent::~CEvent() -{ -} - - -// Empty the FIFO of events. - -void CEvent::Flush() -{ - m_head = 0; - m_tail = 0; - m_total = 0; -} - -// Produces an event. - -void CEvent::MakeEvent(Event &event, EventMsg msg) -{ - memset(&event, 0, sizeof(Event)); - event.event = msg; -} - -// Adds an event in the FIFO. - -bool CEvent::AddEvent(const Event &event) -{ - if ( m_total >= MAXEVENT ) return false; - - m_fifo[m_head++] = event; - if ( m_head >= MAXEVENT ) m_head = 0; - m_total ++; - - return true; -} - -// Removes an event from the FIFO. - -bool CEvent::GetEvent(Event &event) -{ - if ( m_head == m_tail ) return false; - - event = m_fifo[m_tail++]; - if ( m_tail >= MAXEVENT ) m_tail = 0; - m_total --; - - return true; -} - +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * 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 3 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, see http://www.gnu.org/licenses/. + +// event.cpp + +#include "common/event.h" +#include "common/iman.h" + + + +CEventQueue::CEventQueue(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_EVENT, this); + + Flush(); +} + +CEventQueue::~CEventQueue() +{ +} + +void CEventQueue::Flush() +{ + m_head = 0; + m_tail = 0; + m_total = 0; +} + +/** If the maximum size of queue has been reached, returns \c false. + Else, adds the event to the queue and returns \c true. */ +bool CEventQueue::AddEvent(const Event &event) +{ + if ( m_total >= MAX_EVENT_QUEUE ) return false; + + m_fifo[m_head++] = event; + if ( m_head >= MAX_EVENT_QUEUE ) m_head = 0; + m_total ++; + + return true; +} + +/** If the queue is empty, returns \c false. + Else, gets the event from the front, puts it into \a event and returns \c true. */ +bool CEventQueue::GetEvent(Event &event) +{ + if ( m_head == m_tail ) return false; + + event = m_fifo[m_tail++]; + if ( m_tail >= MAX_EVENT_QUEUE ) m_tail = 0; + m_total --; + + return true; +} + diff --git a/src/common/event.h b/src/common/event.h index 8174fab..e7ff552 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -19,40 +19,50 @@ #pragma once +#include "common/key.h" #include "math/point.h" +#include -#if !defined (WM_XBUTTONDOWN) -#define WM_XBUTTONDOWN 0x020B -#define WM_XBUTTONUP 0x020C -#define XBUTTON1 0x0001 -#define XBUTTON2 0x0002 -#endif +class CInstanceManager; +/** + \enum EventType + \brief Type of event message + */ +enum EventType +{ -class CInstanceManager; +// TODO: document the meaning of each value + EVENT_NULL = 0, -const int MAXEVENT = 100; + //! Event sent on user or system quit request + EVENT_QUIT = 1, -// Events. + //? EVENT_FRAME = 2, -enum EventMsg -{ - EVENT_NULL = 0, + //! Event sent after pressing a mouse button + EVENT_MOUSE_BUTTON_DOWN = 3, + //! Event sent after releasing a mouse button + EVENT_MOUSE_BUTTON_UP = 4, + //! Event sent after moving the mouse + EVENT_MOUSE_MOVE = 7, + //! Event sent after pressing a key + EVENT_KEY_DOWN = 8, + //! Event sent after releasing a key + EVENT_KEY_UP = 9, + + //? EVENT_CHAR = 10, + //? EVENT_FOCUS = 11, - EVENT_QUIT = 1, - EVENT_FRAME = 2, - EVENT_LBUTTONDOWN = 3, - EVENT_RBUTTONDOWN = 4, - EVENT_LBUTTONUP = 5, - EVENT_RBUTTONUP = 6, - EVENT_MOUSEMOVE = 7, - EVENT_KEYDOWN = 8, - EVENT_KEYUP = 9, - EVENT_CHAR = 10, - EVENT_FOCUS = 11, + //! Event sent after moving joystick axes + EVENT_JOY_AXIS = 12, + //! Event sent after pressing a joystick button + EVENT_JOY_BUTTON_DOWN = 13, + //! Event sent after releasing a joystick button + EVENT_JOY_BUTTON_UP = 14, EVENT_UPDINTERFACE = 20, EVENT_WIN = 30, @@ -525,60 +535,151 @@ enum EventMsg EVENT_STUDIO_STEP = 2053, EVENT_USER = 10000, - EVENT_FORCE_DWORD = 0x7fffffff + EVENT_FORCE_LONG = 0x7fffffff +}; + + +/** \enum PressState + \brief State of key/mouse button */ +enum PressState +{ + STATE_PRESSED, + STATE_RELEASED +}; + + +/** \struct KeyEventData + \brief Additional data for keyboard event */ +struct KeyEventData +{ + //! STATE_PRESSED or STATE_RELEASED */ + PressState state; + //! Key symbol: KEY(...) macro value (from common/key.h) + unsigned int key; + //! Keyboard modifiers: a bitmask made of KEY_MOD(...) macro values (from common/key.h) + unsigned int mod; + //! Unicode character + unsigned int unicode; + + KeyEventData() + : state(STATE_PRESSED), key(0), mod(0), unicode(0) {} +}; + +/** \struct MouseMotionEventData + \brief Additional data for mouse move event */ +struct MouseMoveEventData +{ + //! Current button state + unsigned char state; + //! Position of mouse in normalized coordinates (0..1) + Math::Point pos; + + MouseMoveEventData() + : state(STATE_PRESSED) {} +}; + +/** \struct MouseButtonEventData + \brief Additional data mouse button event */ +struct MouseButtonEventData +{ + //! The mouse button index + unsigned char button; + //! STATE_PRESSED or STATE_RELEASED + PressState state; + //! Position of mouse in normalized coordinates (0..1) + Math::Point pos; + + MouseButtonEventData() + : button(0), state(STATE_PRESSED) {} +}; + +/** \struct JoyAxisEventData + \brief Additional data for joystick axis event */ +struct JoyAxisEventData +{ + //! The joystick axis index + unsigned char axis; + //! The axis value (range: -32768 to 32767) + int value; + + JoyAxisEventData() + : axis(axis), value(value) {} +}; + +/** \struct JoyButtonEventData + \brief Joystick button event structure */ +struct JoyButtonEventData +{ + //! The joystick button index + unsigned char button; + //! STATE_PRESSED or STATE_RELEASED + PressState state; + + JoyButtonEventData() + : button(0), state(STATE_PRESSED) {} }; +// TODO: JoyHatEventData? JoyBallEventData? + + +/** + \struct Event + \brief Event sent by system, interface or game + + Event is described by its type (EventType) and the union + \a data contains additional data about the event. + Different members of the union are filled with different event types. + With some events, nothing is filled (it's zeroed out). + The union contains roughly the same information as SDL_Event struct + but packaged to independent structs and fields. + **/ struct Event { - EventMsg event; // event (EVENT *) - long param; // parameter - Math::Point pos; // mouse position (0 .. 1) - float axeX; // control the X axis (-1 .. 1) - float axeY; // control of the Y axis (-1 .. 1) - float axeZ; // control the Z axis (-1 .. 1) - short keyState; // state of the keyboard (KS_ *) - float rTime; // relative time - - Event(); + //! Type of event (EVENT_*) + EventType type; + /** + \union EventDataUnion + \brief Additional data associated with some events + + For the listed event, the given member is filled with data. + For other event types, it is filled with zeros. + */ + union EventDataUnion + { + //! Additional data for EVENT_KEY_DOWN and EVENT_KEY_UP + KeyEventData key; + //! Additional data for EVENT_MOUSE_BUTTON_DOWN and EVENT_MOUSE_BUTTON_UP + MouseButtonEventData mouseButton; + //! Additional data for EVENT_MOUSE_MOVE + MouseMoveEventData mouseMove; + //! Additional data for EVENT_JOY + JoyAxisEventData joyAxis; + //! Additional data for EVENT_JOY_AXIS + JoyButtonEventData joyButton; + + EventDataUnion() + { memset(this, 0, sizeof(EventDataUnion)); } + ~EventDataUnion() + {} + } data; + //? long param; // parameter + //? Math::Point pos; // mouse position (0 .. 1) + //? float axeX; // control the X axis (-1 .. 1) + //? float axeY; // control of the Y axis (-1 .. 1) + //? float axeZ; // control the Z axis (-1 .. 1) + //? short keyState; // state of the keyboard (KS_ *) + //? float rTime; // relative time + + Event(EventType aType = EVENT_NULL) : type(aType) {} }; -const int VK_BUTTON1 = (0x100+1); // joystick button 1 -const int VK_BUTTON2 = (0x100+2); // joystick button 2 -const int VK_BUTTON3 = (0x100+3); // joystick button 3 -const int VK_BUTTON4 = (0x100+4); // joystick button 4 -const int VK_BUTTON5 = (0x100+5); // joystick button 5 -const int VK_BUTTON6 = (0x100+6); // joystick button 6 -const int VK_BUTTON7 = (0x100+7); // joystick button 7 -const int VK_BUTTON8 = (0x100+8); // joystick button 8 -const int VK_BUTTON9 = (0x100+9); // joystick button 9 -const int VK_BUTTON10 = (0x100+10); // joystick button 10 -const int VK_BUTTON11 = (0x100+11); // joystick button 11 -const int VK_BUTTON12 = (0x100+12); // joystick button 12 -const int VK_BUTTON13 = (0x100+13); // joystick button 13 -const int VK_BUTTON14 = (0x100+14); // joystick button 14 -const int VK_BUTTON15 = (0x100+15); // joystick button 15 -const int VK_BUTTON16 = (0x100+16); // joystick button 16 -const int VK_BUTTON17 = (0x100+17); // joystick button 17 -const int VK_BUTTON18 = (0x100+18); // joystick button 18 -const int VK_BUTTON19 = (0x100+19); // joystick button 19 -const int VK_BUTTON20 = (0x100+20); // joystick button 20 -const int VK_BUTTON21 = (0x100+21); // joystick button 21 -const int VK_BUTTON22 = (0x100+22); // joystick button 22 -const int VK_BUTTON23 = (0x100+23); // joystick button 23 -const int VK_BUTTON24 = (0x100+24); // joystick button 24 -const int VK_BUTTON25 = (0x100+25); // joystick button 25 -const int VK_BUTTON26 = (0x100+26); // joystick button 26 -const int VK_BUTTON27 = (0x100+27); // joystick button 27 -const int VK_BUTTON28 = (0x100+28); // joystick button 28 -const int VK_BUTTON29 = (0x100+29); // joystick button 29 -const int VK_BUTTON30 = (0x100+30); // joystick button 30 -const int VK_BUTTON31 = (0x100+31); // joystick button 31 -const int VK_BUTTON32 = (0x100+32); // joystick button 32 - -const int VK_WHEELUP = (0x200+1); // Mousewheel up -const int VK_WHEELDOWN = (0x200+2); // Mousewheel down +/** + \enum KeyRank + \brief Slots for key assignment of user controls + */ +// TODO: move to global.h ? enum KeyRank { @@ -609,25 +710,37 @@ enum KeyRank }; +/** + \class CEventQueue + \brief Global event queue -class CEvent + Provides an interface to a global FIFO queue with events (both system- and user-generated). + The queue has a fixed maximum size but it should not be a problem. + */ +class CEventQueue { public: - CEvent(CInstanceManager* iMan); - ~CEvent(); + //! Constant maximum size of queue + static const int MAX_EVENT_QUEUE = 100; + +public: + //! Object's constructor + CEventQueue(CInstanceManager* iMan); + //! Object's destructor + ~CEventQueue(); + //! Empties the FIFO of events void Flush(); - void MakeEvent(Event &event, EventMsg msg); + //! Adds an event to the queue bool AddEvent(const Event &event); bool GetEvent(Event &event); protected: CInstanceManager* m_iMan; - - Event m_fifo[MAXEVENT]; - int m_head; - int m_tail; - int m_total; + Event m_fifo[MAX_EVENT_QUEUE]; + int m_head; + int m_tail; + int m_total; }; diff --git a/src/common/key.h b/src/common/key.h new file mode 100644 index 0000000..0ed6b54 --- /dev/null +++ b/src/common/key.h @@ -0,0 +1,34 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * 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 3 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, see http://www.gnu.org/licenses/. + +// key.h + +#pragma once + + +#include "SDL/SDL_keysym.h" + +/* Key definitions are specially defined here so that it is clear in other parts of the code + that these are used. It is to avoid having SDL-related enum values or #defines lying around + unchecked. With this approach it will be easier to maintain the code later on. */ + +// Key symbol defined as concatenation to SDLK_... +// If need arises, it can be changed to custom function or anything else +#define KEY(x) SDLK_ # x + +// Key modifier defined as concatenation to KMOD_... +// If need arises, it can be changed to custom function or anything else +#define KEY_MOD(x) KMOD_ # x diff --git a/src/common/misc.h b/src/common/misc.h index e863b69..4853856 100644 --- a/src/common/misc.h +++ b/src/common/misc.h @@ -219,7 +219,7 @@ const int KS_NUMMINUS = (1<<15); // Procedures. -extern EventMsg GetUniqueEventMsg(); +extern EventType GetUniqueEventType(); extern char RetNoAccent(char letter); extern char RetToUpper(char letter); diff --git a/src/graphics/common/engine.h b/src/graphics/common/engine.h index 6d2937c..0d93ea2 100644 --- a/src/graphics/common/engine.h +++ b/src/graphics/common/engine.h @@ -481,7 +481,7 @@ public: void SetLightMode(bool present); bool RetLightMode(); - void SetEditIndentMode(bool auto); + void SetEditIndentMode(bool autoIndent); bool RetEditIndentMode(); void SetEditIndentValue(int value); -- cgit v1.2.3-1-g7c22