summaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-07-22 22:05:12 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-07-22 22:05:12 +0200
commit8797569d33c4917eb8f8a1dc2341aac7b5815315 (patch)
tree839aca030b0d3ed36cef15b051fbfd4bf8ecb754 /src/app
parent86ea086790a677d6de6a836e7562814d3ba30bd1 (diff)
downloadcolobot-8797569d33c4917eb8f8a1dc2341aac7b5815315.tar.gz
colobot-8797569d33c4917eb8f8a1dc2341aac7b5815315.tar.bz2
colobot-8797569d33c4917eb8f8a1dc2341aac7b5815315.zip
Texture & mouse functions; refactoring & fixes
- cleaned up and added documentation to engine.h - refactored CEngine interface and associated structs - added mouse handling functions in CApplication & CEngine - fixed bugs in projection matrix setting - changed texture loading & handling - added const-values in CDevice & CGLDevice - changed event management in CApplication - other minor changes & bugfixes
Diffstat (limited to 'src/app')
-rw-r--r--src/app/app.cpp208
-rw-r--r--src/app/app.h67
-rw-r--r--src/app/main.cpp4
3 files changed, 188 insertions, 91 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 6a71f64..4812102 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -22,6 +22,7 @@
#include "app/system.h"
#include "common/logger.h"
#include "common/iman.h"
+#include "common/image.h"
#include "graphics/opengl/gldevice.h"
@@ -31,6 +32,9 @@
#include <stdio.h>
+template<> CApplication* CSingleton<CApplication>::mInstance = NULL;
+
+
//! Interval of timer called to update joystick state
const int JOYSTICK_TIMER_INTERVAL = 1000/30;
@@ -70,14 +74,9 @@ struct ApplicationPrivate
};
-CApplication* CApplication::m_appInstance = NULL;
-
CApplication::CApplication()
{
- assert(m_appInstance == NULL);
- m_appInstance = this;
-
m_private = new ApplicationPrivate();
m_exitCode = 0;
@@ -107,6 +106,8 @@ CApplication::CApplication()
m_debugMode = false;
m_setupMode = true;
+ m_dataPath = "./data";
+
ResetKey();
}
@@ -120,29 +121,49 @@ CApplication::~CApplication()
delete m_iMan;
m_iMan = NULL;
-
- m_appInstance = NULL;
}
-Error CApplication::ParseArguments(int argc, char *argv[])
+bool CApplication::ParseArguments(int argc, char *argv[])
{
+ bool waitDataDir = false;
+
for (int i = 1; i < argc; ++i)
{
std::string arg = argv[i];
+ if (waitDataDir)
+ {
+ waitDataDir = false;
+ m_dataPath = arg;
+ }
+
if (arg == "-debug")
{
m_showStats = true;
SetDebugMode(true);
}
- // TODO else {} report invalid argument
+ else if (arg == "-datadir")
+ {
+ waitDataDir = true;
+ }
+ else
+ {
+ m_exitCode = 1;
+ return false;
+ }
}
- return ERR_OK;
+ // Data dir not given?
+ if (waitDataDir)
+ return false;
+
+ return true;
}
bool CApplication::Create()
{
+ // TODO: verify that data directory exists
+
// Temporarily -- only in windowed mode
m_private->deviceConfig.fullScreen = false;
@@ -365,7 +386,7 @@ void CApplication::CloseJoystick()
Uint32 JoystickTimerCallback(Uint32 interval, void *)
{
- CApplication *app = CApplication::GetInstance();
+ CApplication *app = CApplication::GetInstancePointer();
if ((app == NULL) || (! app->GetJoystickEnabled()))
return 0; // don't run the timer again
@@ -434,43 +455,82 @@ int CApplication::Run()
{
m_active = true;
- while (m_private->currentEvent.type != SDL_QUIT)
+ while (true)
{
// Use SDL_PeepEvents() if the app is active, so we can use idle time to
// render the scene. Else, use SDL_PollEvent() to avoid eating CPU time.
int count = 0;
- if (m_active)
- {
- SDL_PumpEvents();
- count = SDL_PeepEvents(&m_private->currentEvent, 1, SDL_GETEVENT, SDL_ALLEVENTS);
- }
- else
- {
- SDL_PollEvent(&m_private->currentEvent);
- }
- // If received an event
- if ((m_active && count > 0) || (!m_active))
+ // To be sure no old event remains
+ m_private->currentEvent.type = SDL_NOEVENT;
+
+ bool haveEvent = true;
+ while (haveEvent)
{
- ParseEvent();
+ haveEvent = false;
+
+ if (m_active)
+ {
+ SDL_PumpEvents();
+ count = SDL_PeepEvents(&m_private->currentEvent, 1, SDL_GETEVENT, SDL_ALLEVENTS);
+ }
+ else
+ {
+ count = SDL_PollEvent(&m_private->currentEvent);
+ }
+
+ // If received an event
+ if (count > 0)
+ {
+ haveEvent = true;
+
+ Event event = ParseEvent();
+
+ if (event.type == EVENT_QUIT)
+ goto end; // exit the loop
+
+ if (event.type != EVENT_NULL)
+ {
+ bool passOn = ProcessEvent(event);
+
+ if (m_engine != NULL && passOn)
+ passOn = m_engine->ProcessEvent(event);
+
+ if (passOn)
+ m_eventQueue->AddEvent(event);
+ }
+ }
}
- // Render a frame during idle time (no messages are waiting)
+ // Enter game update & frame rendering only if active
if (m_active && m_ready)
{
Event event;
while (m_eventQueue->GetEvent(event))
{
if (event.type == EVENT_QUIT)
- {
goto end; // exit both loops
+
+ bool passOn = true;
+
+ // Skip system events (they have been processed earlier)
+ if (! event.systemEvent)
+ {
+ passOn = ProcessEvent(event);
+
+ if (passOn && m_engine != NULL)
+ passOn = m_engine->ProcessEvent(event);
}
- //m_robotMain->EventProcess(event);
+ /*if (passOn && m_robotMain != NULL)
+ m_robotMain->ProcessEvent(event); */
}
+ // Update game and render a frame during idle time (no messages are waiting)
+ bool ok = Render();
+
// If an error occurs, push quit event to the queue
- if (! Render())
+ if (! ok)
{
SDL_Event quitEvent;
memset(&quitEvent, 0, sizeof(SDL_Event));
@@ -481,7 +541,6 @@ int CApplication::Run()
}
end:
- //m_sound->StopMusic();
Destroy();
return m_exitCode;
@@ -501,23 +560,34 @@ PressState TranslatePressState(unsigned char state)
return STATE_RELEASED;
}
-/** Conversion of the position of the mouse to the following coordinates:
-
-x: 0=left, 1=right
+/** Conversion of the position of the mouse from window coords to interface coords:
+ - x: 0=left, 1=right
+ - y: 0=down, 1=up */
+Math::Point CApplication::WindowToInterfaceCoords(Math::IntPoint pos)
+{
+ return Math::Point( (float)pos.x / (float)m_private->deviceConfig.width,
+ 1.0f - (float)pos.y / (float)m_private->deviceConfig.height);
+}
-y: 0=down, 1=up
-*/
-Math::Point CApplication::WindowToInterfaceCoords(int x, int y)
+Math::IntPoint CApplication::InterfaceToWindowCoords(Math::Point pos)
{
- return Math::Point((float)x / (float)m_private->deviceConfig.width,
- 1.0f - (float)y / (float)m_private->deviceConfig.height);
+ return Math::IntPoint((int)(pos.x * m_private->deviceConfig.width),
+ (int)((1.0f - pos.y) * m_private->deviceConfig.height));
}
-void CApplication::ParseEvent()
+/** The SDL event parsed is stored internally.
+ If event is not available or is not understood, returned event is of type EVENT_NULL. */
+Event CApplication::ParseEvent()
{
Event event;
- if ( (m_private->currentEvent.type == SDL_KEYDOWN) ||
+ event.systemEvent = true;
+
+ if (m_private->currentEvent.type == SDL_QUIT)
+ {
+ event.type = EVENT_QUIT;
+ }
+ else if ( (m_private->currentEvent.type == SDL_KEYDOWN) ||
(m_private->currentEvent.type == SDL_KEYUP) )
{
if (m_private->currentEvent.type == SDL_KEYDOWN)
@@ -540,16 +610,15 @@ void CApplication::ParseEvent()
event.mouseButton.button = m_private->currentEvent.button.button;
event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state);
- event.mouseButton.pos = WindowToInterfaceCoords(m_private->currentEvent.button.x, m_private->currentEvent.button.y);
+ event.mouseButton.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
else if (m_private->currentEvent.type == SDL_MOUSEMOTION)
{
event.type = EVENT_MOUSE_MOVE;
event.mouseMove.state = TranslatePressState(m_private->currentEvent.button.state);
- event.mouseMove.pos = WindowToInterfaceCoords(m_private->currentEvent.button.x, m_private->currentEvent.button.y);
+ event.mouseMove.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
- // TODO: joystick state polling instead of getting events
else if (m_private->currentEvent.type == SDL_JOYAXISMOTION)
{
event.type = EVENT_JOY_AXIS;
@@ -569,16 +638,13 @@ void CApplication::ParseEvent()
event.joyButton.state = TranslatePressState(m_private->currentEvent.jbutton.state);
}
-
- if (m_robotMain != NULL && event.type != EVENT_NULL)
- {
- //m_robotMain->EventProcess(event);
- }
-
- ProcessEvent(event);
+ return event;
}
-void CApplication::ProcessEvent(Event event)
+/** Processes incoming events. It is the first function called after an event is captures.
+ Function returns \c true if the event is to be passed on to other processing functions
+ or \c false if not. */
+bool CApplication::ProcessEvent(const Event &event)
{
CLogger *l = GetLogger();
// Print the events in debug mode to test the code
@@ -621,8 +687,12 @@ void CApplication::ProcessEvent(Event event)
break;
}
}
+
+ // By default, pass on all events
+ return true;
}
+/** Renders the frame and swaps buffers as necessary. Returns \c false on error. */
bool CApplication::Render()
{
bool result = m_engine->Render();
@@ -709,14 +779,39 @@ int CApplication::GetKey(int keyRank, int option)
return 0;
}
-void CApplication::SetMousePos(Math::Point pos)
+void CApplication::SetGrabInput(bool grab)
{
- // TODO
+ SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
}
-void CApplication::SetMouseType(Gfx::MouseType type)
+bool CApplication::GetGrabInput()
{
- // TODO
+ int result = SDL_WM_GrabInput(SDL_GRAB_QUERY);
+ return result == SDL_GRAB_ON;
+}
+
+void CApplication::SetSystemMouseVisible(bool visible)
+{
+ SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
+}
+
+bool CApplication::GetSystemMouseVisibile()
+{
+ int result = SDL_ShowCursor(SDL_QUERY);
+ return result == SDL_ENABLE;
+}
+
+
+void CApplication::SetSystemMousePos(Math::Point pos)
+{
+ Math::IntPoint windowPos = InterfaceToWindowCoords(pos);
+ SDL_WarpMouse(windowPos.x, windowPos.y);
+ m_systemMousePos = pos;
+}
+
+Math::Point CApplication::GetSystemMousePos()
+{
+ return m_systemMousePos;
}
void CApplication::SetJoystickEnabled(bool enable)
@@ -766,3 +861,8 @@ void CApplication::OutputText(long x, long y, char* str)
{
// TODO
}
+
+std::string CApplication::GetDataFilePath(const std::string& dirName, const std::string& fileName)
+{
+ return m_dataPath + "/" + dirName + "/" + fileName;
+}
diff --git a/src/app/app.h b/src/app/app.h
index ed2bd9a..576ed62 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -21,6 +21,7 @@
#include "common/misc.h"
+#include "common/singleton.h"
#include "graphics/common/device.h"
#include "graphics/common/engine.h"
@@ -33,8 +34,8 @@ class CEvent;
class CRobotMain;
class CSound;
-struct ApplicationPrivate;
+struct ApplicationPrivate;
/**
* \class CApplication
@@ -67,7 +68,7 @@ struct ApplicationPrivate;
* The events are further handled in CRobotMain class.
*
*/
-class CApplication
+class CApplication : public CSingleton<CApplication>
{
public:
//! Constructor (can only be called once!)
@@ -75,13 +76,9 @@ public:
//! Destructor
~CApplication();
- //! Returns the only CApplication instance
- static CApplication* GetInstance()
- { return m_appInstance; }
-
public:
//! Parses commandline arguments
- Error ParseArguments(int argc, char *argv[]);
+ bool ParseArguments(int argc, char *argv[]);
//! Initializes the application
bool Create();
//! Main event loop
@@ -117,20 +114,31 @@ public:
void SetKey(int keyRank, int option, int key);
int GetKey(int keyRank, int option);
- void SetMouseType(Gfx::MouseType type);
- void SetMousePos(Math::Point pos);
+ //! Sets the grab mode for input (keyboard & mouse)
+ void SetGrabInput(bool grab);
+ //! Returns the grab mode
+ bool GetGrabInput();
+
+ //! Sets the visiblity of system mouse cursor
+ void SetSystemMouseVisible(bool visible);
+ //! Returns the visiblity of system mouse cursor
+ bool GetSystemMouseVisibile();
- //? void SetNiceMouse(bool nice);
- //? bool GetNiceMouse();
- //? bool GetNiceMouseCap();
+ //! Sets the position of system mouse cursor (in interface coords)
+ void SetSystemMousePos(Math::Point pos);
+ //! Returns the position of system mouse cursor (in interface coords)
+ Math::Point GetSystemMousePos();
bool WriteScreenShot(char *filename, int width, int height);
+ //! Returns the full path to a file in data directory
+ std::string GetDataFilePath(const std::string &dirName, const std::string &fileName);
+
protected:
- //! Processes an SDL event to Event struct
- void ParseEvent();
+ //! Processes the captured SDL event to Event struct
+ Event ParseEvent();
//! Handles some incoming events
- void ProcessEvent(Event event);
+ bool ProcessEvent(const Event &event);
//! Renders the image in window
bool Render();
@@ -140,16 +148,9 @@ protected:
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();
- //HRESULT CreateZBuffer(GUID* pDeviceGUID);
- //HRESULT Render3DEnvironment();
- //VOID Cleanup3DEnvironment();
- //VOID DeleteDeviceObjects();
- //VOID DisplayFrameworkError( HRESULT, DWORD );
+ Math::Point WindowToInterfaceCoords(Math::IntPoint pos);
+ //! Converts the interface coords to window coords
+ Math::IntPoint InterfaceToWindowCoords(Math::Point pos);
void InitText();
void DrawSuppl();
@@ -157,8 +158,6 @@ protected:
void OutputText(long x, long y, char* str);
protected:
- //! The only instance of CApplication
- static CApplication* m_appInstance;
//! Instance manager
CInstanceManager* m_iMan;
//! Private (SDL-dependent data)
@@ -185,21 +184,16 @@ protected:
bool m_debugMode;
bool m_setupMode;
+ //! Whether joystick is enabled
bool m_joystickEnabled;
+ //! Text set as window title
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;
- Math::Point m_mousePos;
+ Math::Point m_systemMousePos;
long m_mouseWheel;
//! Current state of joystick axes; may be updated from another thread
@@ -209,5 +203,8 @@ protected:
float m_time;
long m_key[50][2];
+
+ //! Path to directory with data files
+ std::string m_dataPath;
};
diff --git a/src/app/main.cpp b/src/app/main.cpp
index f857037..9eea6e4 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -69,10 +69,10 @@ int main(int argc, char *argv[])
CApplication app; // single instance of the application
- Error err = app.ParseArguments(argc, argv);
- if (err != ERR_OK)
+ if (! app.ParseArguments(argc, argv))
{
SystemDialog(SDT_ERROR, "COLOBOT", "Invalid commandline arguments!\n");
+ return app.GetExitCode();
}
int code = 0;