summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-06-30 00:12:04 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-06-30 00:12:04 +0200
commite37019943cb77d8c0735b330339a139430202fd8 (patch)
tree705c83d2774db76c58dd9853b2beb25fa03968d7 /src
parentdb5c6b5e45134f3cce21ee7b9b5ba4ca8d1e909c (diff)
downloadcolobot-e37019943cb77d8c0735b330339a139430202fd8.tar.gz
colobot-e37019943cb77d8c0735b330339a139430202fd8.tar.bz2
colobot-e37019943cb77d8c0735b330339a139430202fd8.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/app/app.cpp332
-rw-r--r--src/app/app.h80
-rw-r--r--src/common/event.cpp164
-rw-r--r--src/common/event.h269
-rw-r--r--src/common/key.h34
-rw-r--r--src/common/misc.h2
-rw-r--r--src/graphics/common/engine.h2
7 files changed, 544 insertions, 339 deletions
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(&currentEvent, 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 <string.h>
-
-
-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 <string.h>
-#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);