Commit 49e34ac5 authored by gerstrong@gmail.com's avatar gerstrong@gmail.com

Merge branch 'master' into testing

parents e5e6aac1 a5b69951
# CMake file for development of Commander Genius (taken from OLX)
# This CMake file is used under Linux normally.
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.7)
Project(CommanderGenius)
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake")
option(USE_VIRTUALPAD "Enable Onscreen Virtual Gamepad support " yes)
if(USE_VIRTUALPAD)
ADD_DEFINITIONS(-DVIRTUALPAD)
endif(USE_VIRTUALPAD)
# Use COmpile TIme REducer
include(cotire)
include(FindSDL2_mixer)
option(USE_PYTHON3 "Use Python3 scripts" yes)
......@@ -32,7 +38,7 @@ string(REGEX REPLACE "[\r\n]" "" CG_VERSION "${CG_VERSION}")
# Since shell script get_version is not processed properly on windows, we have to define manually here.
# TODO: Better system for defining the version
IF(WIN32)
set(CG_VERSION "2.2.5")
set(CG_VERSION "2.3.0")
endif()
# Generate the README file with the correct version string
......
# CMake file for development of Commander Genius (taken from OLX)
# This CMake file is used under Linux normally.
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.7)
Project(GsKit)
OPTION(USE_SDL2 "SDL2 support" Yes)
option(USE_PYTHON3 "Use Python3 scripts" yes)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
......@@ -76,14 +80,21 @@ endif(USE_SDL2)
# Use python3 for AI scripting and more!
IF(USE_PYTHON3)
# Look for Python (Version 3.0 or later is required)
FIND_PACKAGE(PythonLibs)
ADD_DEFINITIONS(-DUSE_PYTHON3=1)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS})
LINK_LIBRARIES(${PYTHON_LIBRARIES})
FIND_PACKAGE(Python3 COMPONENTS Interpreter Development)
if(Python3_FOUND)
ADD_DEFINITIONS(-DUSE_PYTHON3=1)
INCLUDE_DIRECTORIES(${Python3_INCLUDE_DIRS})
LINK_LIBRARIES(${Python3_LIBRARIES})
message(STATUS "Python3_LIBRARIES = ${Python3_LIBRARIES}")
message(STATUS "Python3_INCLUDE_DIRS = ${Python3_INCLUDE_DIRS}")
else()
message(FATAL_ERROR "Python3 not found!")
endif()
ENDIF()
Project(GsKit)
# From this point files are globbed for compilation and project setup
file(GLOB_RECURSE ALL_SRCS_GSKIT_BASE *.c* *.h*)
......@@ -106,7 +117,8 @@ endif()
IF(OPENGL)
# OpenGL Parsing
find_package(OpenGL REQUIRED)
set(OpenGL_GL_PREFERENCE GLVND)
find_package(OpenGL REQUIRED)
ADD_DEFINITIONS(-DGL)
ADD_DEFINITIONS(-DUSE_OPENGL)
......
This diff is collapsed.
......@@ -11,8 +11,9 @@
#include <SDL.h>
#include <string>
#include <list>
#include <vector>
#include <base/utils/Geometry.h>
#include <base/GsEvent.h>
#include <base/GsEventContainer.h>
#include <base/InputEvents.h>
#include <base/Singleton.h>
......@@ -159,6 +160,8 @@ class CInput : public GsSingleton<CInput>
public:
CInput();
virtual ~CInput();
/**
* @brief transMouseRelCoord transforms a mouse click from the screen coordinates to the relative coordinates
* @param Pos Resulting relative coordinate to handle
......@@ -294,6 +297,7 @@ public:
*/
void pushBackButtonEventExtEng();
#ifdef VIRTUALPAD
// One virtual input overlay can be active be processed. This is useful for game to ported on mobile devices
std::unique_ptr<GsVirtualInput> mpVirtPad;
......@@ -305,9 +309,20 @@ public:
{
mVPadConfigState = value;
}
#endif
private:
bool processKeys(int value);
void processJoystickAxis();
void processJoystickHat();
void processJoystickButton(int value);
void processMouse();
void processMouse(SDL_Event& ev);
void processMouse(int x, int y, bool down, int index);
// Input Events
CEventContainer m_EventList;
......@@ -335,7 +350,9 @@ private:
int m_cmdpulse;
short m_joydeadzone;
#ifdef VIRTUALPAD
bool mVPadConfigState = false;
#endif
bool immediate_keytable[KEYTABLE_SIZE];
bool last_immediate_keytable[KEYTABLE_SIZE];
......@@ -343,22 +360,13 @@ private:
struct rm_type
{
rm_type():
mappingInput(false) {}
// For mapping new Commands
bool mappingInput;
Uint8 mapDevice;
int mapPosition;
bool mappingInput = false;
Uint8 mapDevice = 0;
int mapPosition = 0;
} remapper;
bool processKeys(int value);
void processJoystickAxis();
void processJoystickHat();
void processJoystickButton(int value);
void processMouse();
void processMouse(SDL_Event& ev);
void processMouse(int x, int y, bool down, int index);
SDL_sem *mpPollSem = nullptr;
};
......
......@@ -251,15 +251,14 @@ void GsApp::runMainCycle()
curr = timerTicks();
if(gTimer.resetLogicSignal())
start = curr;
start = curr;
if(vsyncEnabled)
{
start = timerTicks();
// Game cycle
{
{
// Poll Inputs
gInput.pollEvents();
......
......@@ -5,8 +5,8 @@
* Author: gerstrong
*/
#ifndef __GSAPP_H_
#define __GSAPP_H_
#ifndef GSAPP_H_
#define GSAPP_H_
#include <base/GsEvent.h>
#include <base/GsEngine.h>
......@@ -28,7 +28,7 @@ public:
GsAppEventSink(GsApp* pApp) :
mpApp(pApp) {}
void pumpEvent(const CEvent *ev);
void pumpEvent(const CEvent *ev) override;
private:
GsApp* mpApp;
......@@ -59,10 +59,6 @@ public:
void pumpEvent(const CEvent *evPtr);
/*
int m_startGame_no;
int m_startLevel;*/
private:
......@@ -73,4 +69,4 @@ private:
// It's a simple quit event which will force CG to close the App
struct GMQuit : CEvent {};
#endif /* __GSAPP_H_ */
#endif /* GSAPP_H */
#include "GsEvent.h"
CEvent::~CEvent()
{}
GsEventSink::~GsEventSink()
{}
#ifndef __GSEVENT_H_
#define __GSEVENT_H_
#ifndef GSEVENT_H
#define GSEVENT_H
#include "base/Singleton.h"
#include <ctime>
#include <vector>
#include <deque>
#include <list>
#include <memory>
struct CEvent { virtual ~CEvent() {} };
struct CEvent { virtual ~CEvent(); };
struct InvokeFunctorEvent : CEvent
{
......@@ -22,146 +17,13 @@ struct InvokeFunctorEvent : CEvent
class GsEventSink
{
public:
virtual void pumpEvent(const CEvent *ev) = 0;
};
class CEventContainer : public GsSingleton<CEventContainer>
{
public:
CEventContainer() :
pausetime(0),
timepoint(0),
mFlush(false)
{}
size_t size() { return m_EventList.size(); }
bool empty() { return m_EventList.empty(); }
void clear() { m_EventList.clear(); }
/**
* @brief regSink will register the sink in the Container
* when you are destroying the object, you must call unregSink() first!
* Otherwise app might crash.
* @param pSink pointer to the sink to be registered
*/
void regSink(GsEventSink *pSink)
{
mSinkPtrList.push_back(pSink);
}
void unregSink(GsEventSink *pSink)
{
mSinkPtrList.remove(pSink);
}
void processSinks()
{
// First check if there are pendingEvents to be processed
if(m_EventList.empty())
return;
// Make a copy of that list, because the original
// could change, while pumping happens
for(auto &ev : m_EventList)
{
mPumpEventPtrs.push_back(ev);
}
// We don't need anything from this list anymore
m_EventList.clear();
for( GsEventSink* sink : mSinkPtrList )
{
for( auto &event : mPumpEventPtrs )
{
sink->pumpEvent( event.get() );
if(mFlush)
break;
}
if(mFlush)
break;
}
mPumpEventPtrs.clear();
mFlush = false;
}
virtual ~GsEventSink();
void flush()
{
m_EventList.clear();
mFlush = true;
}
void add(std::shared_ptr<CEvent>& ev)
{
m_EventList.push_back(ev);
}
// template version
template <class _T>
void add()
{
_T *ev = new _T;
m_EventList.push_back(std::shared_ptr<CEvent>(ev));
}
void add(CEvent *ev)
{
m_EventList.push_back(std::shared_ptr<CEvent>(ev));
}
void wait(const float time)
{
timepoint = clock();
pausetime = static_cast<clock_t>(time*static_cast<float>(CLOCKS_PER_SEC));
}
void update()
{
if(pausetime<=0.0f)
return;
const clock_t newTime = clock();
const clock_t passed = newTime-timepoint;
timepoint = newTime;
pausetime -= passed;
return;
}
std::deque< std::shared_ptr<CEvent> >::iterator erase(std::deque< std::shared_ptr<CEvent> >::iterator &it)
{ return m_EventList.erase(it); }
std::deque< std::shared_ptr<CEvent> >::iterator begin() { return m_EventList.begin(); }
std::deque< std::shared_ptr<CEvent> >::iterator end() { return m_EventList.end(); }
template<typename T> T* occurredEvent();
void pop_Event() { m_EventList.pop_front(); }
private:
std::list< GsEventSink* > mSinkPtrList;
std::deque< std::shared_ptr<CEvent> > m_EventList;
std::vector< std::shared_ptr<CEvent> > mPumpEventPtrs;
clock_t pausetime = 0;
clock_t timepoint = 0;
bool mFlush = false;
virtual void pumpEvent(const CEvent *ev) = 0;
};
template<typename T>
T* CEventContainer::occurredEvent()
{
if(m_EventList.empty() || pausetime > 0 )
return nullptr;
return dynamic_cast<T*> (m_EventList.front().get());
}
#define gEventManager CEventContainer::get()
#endif /* __GSEVENT_H_ */
#endif /* GSEVENT_H */
#include "GsEventContainer.h"
void CEventContainer::processSinks()
{
// First check if there are pendingEvents to be processed
if(m_EventList.empty())
return;
// Make a copy of that list, because the original
// could change, while pumping happens
for(auto &ev : m_EventList)
{
mPumpEventPtrs.push_back(ev);
}
// We don't need anything from this list anymore
m_EventList.clear();
for( GsEventSink* sink : mSinkPtrList )
{
for( auto &event : mPumpEventPtrs )
{
sink->pumpEvent( event.get() );
if(mFlush)
break;
}
if(mFlush)
break;
}
mPumpEventPtrs.clear();
mFlush = false;
}
void CEventContainer::update()
{
if(pausetime<=0.0f)
return;
const clock_t newTime = clock();
const clock_t passed = newTime-timepoint;
timepoint = newTime;
pausetime -= passed;
return;
}
#ifndef GSEVENTCONTAINER_H
#define GSEVENTCONTAINER_H
#include "GsEvent.h"
#include <vector>
#include <deque>
#include <list>
#include <memory>
#include <ctime>
#define gEventManager CEventContainer::get()
class CEventContainer : public GsSingleton<CEventContainer>
{
public:
size_t size() { return m_EventList.size(); }
bool empty() { return m_EventList.empty(); }
void clear() { m_EventList.clear(); }
/**
* @brief regSink will register the sink in the Container
* when you are destroying the object, you must call unregSink() first!
* Otherwise app might crash.
* @param pSink pointer to the sink to be registered
*/
void regSink(GsEventSink *pSink)
{
mSinkPtrList.push_back(pSink);
}
void unregSink(GsEventSink *pSink)
{
mSinkPtrList.remove(pSink);
}
/**
* @brief processSinks processor of the added event within the applications
*/
void processSinks();
void flush()
{
m_EventList.clear();
mFlush = true;
}
void add(std::shared_ptr<CEvent>& ev)
{
m_EventList.push_back(ev);
}
// template version
template <class _T>
void add()
{
_T *ev = new _T;
m_EventList.push_back(std::shared_ptr<CEvent>(ev));
}
void add(CEvent *ev)
{
m_EventList.push_back(std::shared_ptr<CEvent>(ev));
}
void wait(const float time)
{
timepoint = clock();
pausetime = static_cast<clock_t>(time*static_cast<float>(CLOCKS_PER_SEC));
}
void update();
std::deque< std::shared_ptr<CEvent> >::iterator erase(std::deque< std::shared_ptr<CEvent> >::iterator &it)
{ return m_EventList.erase(it); }
std::deque< std::shared_ptr<CEvent> >::iterator begin() { return m_EventList.begin(); }
std::deque< std::shared_ptr<CEvent> >::iterator end() { return m_EventList.end(); }
template<typename T> T* occurredEvent();
void pop_Event() { m_EventList.pop_front(); }
private:
std::list< GsEventSink* > mSinkPtrList;
std::deque< std::shared_ptr<CEvent> > m_EventList;
std::vector< std::shared_ptr<CEvent> > mPumpEventPtrs;
clock_t pausetime = 0;
clock_t timepoint = 0;
bool mFlush = false;
};
template<typename T>
T* CEventContainer::occurredEvent()
{
if(m_EventList.empty() || pausetime > 0 )
return nullptr;
return dynamic_cast<T*> (m_EventList.front().get());
}
#endif /* GSEVENTCONTAINER_H */
#ifndef __GSGEAR_H__
#define __GSGEAR_H__
#ifndef GSGEAR_H__
#define GSGEAR_H__
/**
\description GsGear is pretty much what ensures a correct connection
......@@ -15,9 +15,9 @@
class GsGear
{
public:
virtual void pumpEvent(const CEvent *evPtr) {}
virtual void pumpEvent(const CEvent *) {}
virtual void run(const float deltaT) = 0;
virtual void render() {}
};
#endif // __GSGEAR_H__
#endif // GSGEAR_H__
......@@ -6,7 +6,7 @@
#include <set>
class stInputCommand;
struct stInputCommand;
class TouchButton
{
......@@ -40,6 +40,12 @@ public:
this->w, this->h);
}
/**
* @brief loadPicture load the button-picture from a given file
* @param picFile file to load
*/
bool loadPicture(const std::string &picFile);
/**
* @brief loadEmdbeddedPicture Load picture from internal memory
* @param data
......@@ -48,25 +54,17 @@ public:
bool loadEmdbeddedPicture(const unsigned char *data,
const unsigned int size);
/**
* @brief render The actual render function.
* @param dark Should the texture be rendered dark?
*/
void render(const bool dark);
stInputCommand* cmd = nullptr;
//stInputCommand* cmd = nullptr;
int immediateIndex = 0;
float x = 0.0f, y = 0.0f, w = 0.0f, h = 0.0f;
bool invisible = true;
bool invisible = true;
GsTexture mTexture;
GsTexture mTextureDark;
#if SDL_VERSION_ATLEAST(2, 0, 0)
#if SDL_VERSION_ATLEAST(2, 0, 0)
void clearFingers();
......@@ -74,23 +72,14 @@ public:
void removeFingerId(const SDL_FingerID fid);
bool hasFingersPressing() const
bool hasFingers() const
{
if(mMouseDown)
return true;
return !mFingerSet.empty();
}
std::set<SDL_FingerID> mFingerSet;
#endif
// Happens when user tried to put the button to a different location
bool beingRepositioned = false;
bool mMouseDown = false;
};
/**
......@@ -146,7 +135,6 @@ public:
virtual void processConfig() = 0;
/**
* @brief renderConfig Render configuration dialog of the dialog
*/
......@@ -196,9 +184,9 @@ protected:
bool mEnabled = true;
//GsSurface mOverlay;
float mTranslucency = 0.5f;