Open source Star Ruler 2 source code!
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
#pragma once
|
||||
#include "os/key_consts.h"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
namespace os {
|
||||
|
||||
enum WindowMode {
|
||||
WM_Fullscreen,
|
||||
WM_Window,
|
||||
};
|
||||
|
||||
enum KeyAction {
|
||||
KA_Pressed = 1,
|
||||
KA_Released = 2,
|
||||
KA_Repeated = 1+4,
|
||||
};
|
||||
|
||||
struct WindowData {
|
||||
int width, height;
|
||||
int redbits, greenbits, bluebits, alphabits;
|
||||
int depthbits, stencilbits;
|
||||
int aa_samples;
|
||||
int refreshRate;
|
||||
bool resizable;
|
||||
int verticalSync;
|
||||
WindowMode mode;
|
||||
std::string targetMonitor;
|
||||
bool overrideMonitor;
|
||||
|
||||
WindowData()
|
||||
: width(1024), height(768),
|
||||
redbits(8), greenbits(8), bluebits(8),
|
||||
alphabits(8), depthbits(8), stencilbits(8),
|
||||
aa_samples(4), refreshRate(0), resizable(false),
|
||||
verticalSync(1), mode(WM_Window), overrideMonitor(false) {}
|
||||
};
|
||||
|
||||
enum OSCallback {
|
||||
OSC_WindowResize,
|
||||
OSC_WindowClose,
|
||||
OSC_Key,
|
||||
OSC_CharKey,
|
||||
OSC_MouseMove,
|
||||
OSC_MouseButton,
|
||||
OSC_MouseWheel,
|
||||
|
||||
OSC_COUNT
|
||||
};
|
||||
|
||||
template<class Arg0,class Arg1>
|
||||
struct DriverCallbacks_2 {
|
||||
typedef std::function<bool(Arg0,Arg1)> cb;
|
||||
std::list<cb> callbacks;
|
||||
|
||||
//Adds the callback to the list, earlier if priority
|
||||
void add(cb func, bool priority = false) {
|
||||
if(priority)
|
||||
callbacks.push_front(func);
|
||||
else
|
||||
callbacks.push_back(func);
|
||||
}
|
||||
|
||||
//Removes a callback previously added to the list
|
||||
void remove(cb func) {
|
||||
callbacks.remove_if([func](cb f) {
|
||||
return func.template target<bool(Arg0,Arg1)>() == f.template target<bool(Arg0,Arg1)>();
|
||||
});
|
||||
}
|
||||
//Calls each callback in order, stopping if true is returned
|
||||
void operator()(Arg0 arg0, Arg1 arg1) {
|
||||
for(auto i = callbacks.begin(), end = callbacks.end(); i != end; ++i)
|
||||
if((*i)(arg0,arg1))
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
template<class Arg0>
|
||||
struct DriverCallbacks_1 {
|
||||
typedef std::function<bool(Arg0)> cb;
|
||||
std::list<cb> callbacks;
|
||||
|
||||
//Adds the callback to the list, earlier if priority
|
||||
void add(cb func, bool priority = false) {
|
||||
if(priority)
|
||||
callbacks.push_front(func);
|
||||
else
|
||||
callbacks.push_back(func);
|
||||
}
|
||||
|
||||
//Removes a callback previously added to the list
|
||||
void remove(cb func) {
|
||||
callbacks.remove_if([func](cb f) {
|
||||
return func.template target<bool(Arg0)>() == f.template target<bool(Arg0)>();
|
||||
});
|
||||
}
|
||||
//Calls each callback in order, stopping if true is returned
|
||||
void operator()(Arg0 arg0) {
|
||||
for(auto i = callbacks.begin(), end = callbacks.end(); i != end; ++i)
|
||||
if((*i)(arg0))
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
struct DriverCallbacks {
|
||||
typedef std::function<bool()> cb;
|
||||
std::list<cb> callbacks;
|
||||
|
||||
//Adds the callback to the list, earlier if priority
|
||||
void add(cb func, bool priority = false) {
|
||||
if(priority)
|
||||
callbacks.push_front(func);
|
||||
else
|
||||
callbacks.push_back(func);
|
||||
}
|
||||
|
||||
//Removes a callback previously added to the list
|
||||
void remove(cb func) {
|
||||
callbacks.remove_if([func](cb f) {
|
||||
return func.template target<bool()>() == f.template target<bool()>();
|
||||
});
|
||||
}
|
||||
|
||||
//Calls each callback in order, stopping if true is returned
|
||||
void operator()() {
|
||||
for(auto i = callbacks.begin(), end = callbacks.end(); i != end; ++i)
|
||||
if((*i)())
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
class OSDriver {
|
||||
public:
|
||||
struct VideoMode {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned refresh;
|
||||
};
|
||||
|
||||
DriverCallbacks onWindowClose;
|
||||
DriverCallbacks_1<unsigned> onCharTyped;
|
||||
DriverCallbacks_2<double,double> onScroll;
|
||||
DriverCallbacks_2<int,int> onResize, onMouseButton, onMouseMoved, onKeyEvent;
|
||||
|
||||
bool shiftKey, altKey, ctrlKey;
|
||||
int win_width, win_height;
|
||||
|
||||
int mouse_x, mouse_y;
|
||||
int leftButton, rightButton, middleButton;
|
||||
|
||||
virtual bool systemRandom(unsigned char* buffer, unsigned bytes) = 0;
|
||||
|
||||
virtual void setVerticalSync(int waitFrames) = 0;
|
||||
|
||||
virtual void swapBuffers(double minWait_s = 0) = 0;
|
||||
//NOTE: If you need to keep the program awake but can't render, use this instead of swapBuffers
|
||||
// Skips the elapsed time with minimal impact on timers
|
||||
virtual void handleEvents(unsigned minWait_ms = 100) = 0;
|
||||
|
||||
virtual void createWindow(WindowData& data) = 0;
|
||||
virtual void setWindowTitle(const char* str) = 0;
|
||||
virtual void setWindowSize(int width, int height) = 0;
|
||||
virtual void closeWindow() = 0;
|
||||
virtual bool isWindowFocused() = 0;
|
||||
virtual bool isWindowMinimized() = 0;
|
||||
virtual bool isMouseOver() = 0;
|
||||
virtual void flashWindow() = 0;
|
||||
virtual void getVideoModes(std::vector<VideoMode>& output) = 0;
|
||||
virtual void getMonitorNames(std::vector<std::string>& output) = 0;
|
||||
|
||||
virtual void getDesktopSize(unsigned& width, unsigned& height) = 0;
|
||||
|
||||
virtual void resetTimer() = 0;
|
||||
//Returns time since last reset in ms
|
||||
virtual int getTime() const = 0;
|
||||
//Returns time since last reset in seconds
|
||||
virtual double getAccurateTime() const = 0;
|
||||
|
||||
//Returns the current system time for the frame
|
||||
virtual double getFrameTime() const = 0;
|
||||
|
||||
//Resets the game timer (implied by resetTimer())
|
||||
virtual void resetGameTime(double time) = 0;
|
||||
//Returns the current game time
|
||||
virtual double getGameTime() const = 0;
|
||||
//Sets the game speed as a factor of real time
|
||||
virtual void setGameSpeed(double factor) = 0;
|
||||
//Returns the current game speed
|
||||
virtual double getGameSpeed() const = 0;
|
||||
|
||||
virtual unsigned getProcessorCount() = 0;
|
||||
|
||||
virtual void sleep(int milliseconds) = 0;
|
||||
|
||||
virtual unsigned getDoubleClickTime() const = 0;
|
||||
virtual void getMousePos(int& x, int& y) = 0;
|
||||
virtual void getLastMousePos(int& x, int& y) = 0;
|
||||
virtual void setMousePos(int x, int y) = 0;
|
||||
virtual void setCursorVisible(bool visible) = 0;
|
||||
virtual void setCursorLocked(bool locked) = 0;
|
||||
//Sets whether the cursor should currently lock if set to
|
||||
virtual void setCursorShouldLock(bool locked) = 0;
|
||||
|
||||
virtual void setClipboard(const std::string& text) = 0;
|
||||
virtual std::string getClipboard() = 0;
|
||||
|
||||
virtual int getCharForKey(int key) = 0;
|
||||
virtual int getKeyForChar(unsigned char chr) = 0;
|
||||
|
||||
OSDriver() : shiftKey(false), altKey(false), ctrlKey(false),
|
||||
win_width(0), win_height(0), mouse_x(0), mouse_y(0),
|
||||
leftButton(false), rightButton(false), middleButton(false) {}
|
||||
virtual ~OSDriver() {}
|
||||
};
|
||||
|
||||
};
|
||||
@@ -0,0 +1,569 @@
|
||||
#include "os/glfw_driver.h"
|
||||
#include "compat/misc.h"
|
||||
#include "compat/gl.h"
|
||||
#include "main/game_platform.h"
|
||||
#include "main/references.h"
|
||||
#include "main/logging.h"
|
||||
#include "threads.h"
|
||||
#include "vec2.h"
|
||||
#include <list>
|
||||
#include <math.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef WIN_MODE
|
||||
#include <sys/time.h>
|
||||
#include <random>
|
||||
#else
|
||||
|
||||
//Undef duplicate macros from glfw
|
||||
#undef APIENTRY
|
||||
#undef WINGDIAPI
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WinCrypt.h>
|
||||
#include "os/resource.h"
|
||||
#endif
|
||||
|
||||
//We use std::max instead
|
||||
#undef max
|
||||
|
||||
extern bool game_running;
|
||||
|
||||
namespace os {
|
||||
|
||||
void redirectWindowClose(GLFWwindow*);
|
||||
void redirectWindowResize(GLFWwindow*,int, int);
|
||||
void redirectSpecialKey(GLFWwindow*,int key, int scan, int action, int mods);
|
||||
void redirectCharKey(GLFWwindow*,unsigned);
|
||||
void redirectMouseButton(GLFWwindow*,int button, int action, int mods);
|
||||
void redirectMouseMove(GLFWwindow*,double x, double y);
|
||||
void redirectMouseWheel(GLFWwindow*,double x, double y);
|
||||
void trackMouseOver(GLFWwindow*,int over);
|
||||
void glfwError(int, const char*);
|
||||
|
||||
class GLFWDriver;
|
||||
GLFWDriver* driver = 0;
|
||||
|
||||
class GLFWDriver : public OSDriver {
|
||||
union Callback {
|
||||
std::function<bool(void)>* f_v;
|
||||
std::function<bool(int)>* f_i;
|
||||
std::function<bool(int,int)>* f_ii;
|
||||
|
||||
Callback(decltype(f_v) p_f_v) : f_v(p_f_v) {}
|
||||
Callback(decltype(f_i) p_f_i) : f_i(p_f_i) {}
|
||||
Callback(decltype(f_ii) p_f_ii) : f_ii(p_f_ii) {}
|
||||
};
|
||||
|
||||
std::list<Callback> callbacks[OSC_COUNT];
|
||||
GLFWwindow* window;
|
||||
|
||||
public:
|
||||
#ifndef WIN_MODE
|
||||
timeval start_time;
|
||||
#else
|
||||
ULARGE_INTEGER start_time;
|
||||
|
||||
LARGE_INTEGER start_time_hq, start_time_hq_freq;
|
||||
#endif
|
||||
|
||||
bool mouseOver;
|
||||
bool canLock, shouldLock;
|
||||
|
||||
double frameTime, gameTime, gameSpeed;
|
||||
|
||||
GLFWDriver() : window(0), mouseOver(true), canLock(false), shouldLock(false) {
|
||||
glfwSetErrorCallback(glfwError);
|
||||
glfwInit();
|
||||
resetTimer();
|
||||
}
|
||||
|
||||
~GLFWDriver() {
|
||||
driver = 0;
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
bool systemRandom(unsigned char* buffer, unsigned bytes) {
|
||||
#ifdef WIN_MODE
|
||||
HCRYPTPROV provider;
|
||||
|
||||
//Attempt to acquire the context if it exists, then make it if it does not
|
||||
BOOL ctx = CryptAcquireContext(&provider, "SR2SysRand", NULL, PROV_RSA_AES, NULL);
|
||||
if(!ctx)
|
||||
ctx = CryptAcquireContext(&provider, "SR2SysRand", NULL, PROV_RSA_AES, CRYPT_NEWKEYSET);
|
||||
|
||||
if(ctx) {
|
||||
BOOL success = CryptGenRandom(provider, bytes, buffer);
|
||||
CryptReleaseContext(provider, NULL);
|
||||
|
||||
return success != 0;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
std::random_device rd;
|
||||
for(unsigned i = 0; i < bytes; ++i)
|
||||
buffer[i] = (unsigned char)rd();
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setVerticalSync(int waitFrames) {
|
||||
glfwSwapInterval(waitFrames);
|
||||
}
|
||||
|
||||
void swapBuffers(double minWait_s) {
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
if(devices.cloud)
|
||||
devices.cloud->update();
|
||||
|
||||
double waitTill = frameTime + minWait_s;
|
||||
double curTime = getAccurateTime();
|
||||
|
||||
while(curTime < waitTill) {
|
||||
glfwPollEvents();
|
||||
if(devices.cloud)
|
||||
devices.cloud->update();
|
||||
threads::sleep(0);
|
||||
curTime = getAccurateTime();
|
||||
}
|
||||
|
||||
if(gameSpeed > 0 && game_running) {
|
||||
double delta = curTime - frameTime;
|
||||
if(delta > 0.5)
|
||||
delta = 0.5;
|
||||
gameTime += delta * gameSpeed;
|
||||
}
|
||||
|
||||
frameTime = curTime;
|
||||
}
|
||||
|
||||
void handleEvents(unsigned minWait_ms) {
|
||||
glfwPollEvents();
|
||||
frameTime = getAccurateTime();
|
||||
threads::sleep(minWait_ms);
|
||||
}
|
||||
|
||||
void getDesktopSize(unsigned& width, unsigned& height) {
|
||||
auto* primary = glfwGetPrimaryMonitor();
|
||||
if(primary == nullptr) {
|
||||
width = 1280;
|
||||
height = 720;
|
||||
return;
|
||||
}
|
||||
auto& desktop = *glfwGetVideoMode(primary);
|
||||
width = desktop.width;
|
||||
height = desktop.height;
|
||||
}
|
||||
|
||||
void createWindow(WindowData& data) {
|
||||
glfwWindowHint(GLFW_SAMPLES, data.aa_samples);
|
||||
glfwWindowHint(GLFW_REFRESH_RATE, data.refreshRate);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||
|
||||
GLFWmonitor* monitor = nullptr;
|
||||
if(data.mode == WM_Fullscreen) {
|
||||
monitor = glfwGetPrimaryMonitor();
|
||||
|
||||
if(!data.targetMonitor.empty()) {
|
||||
int count = 0;
|
||||
GLFWmonitor** monitors = glfwGetMonitors(&count);
|
||||
for(int i = 0; i < count; ++i) {
|
||||
if(data.targetMonitor == glfwGetMonitorName(monitors[i])) {
|
||||
monitor = monitors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(monitor && !data.overrideMonitor) {
|
||||
int count = 0;
|
||||
const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
|
||||
bool match = false;
|
||||
for(int i = 0; i < count; ++i) {
|
||||
auto& mode = modes[i];
|
||||
if(mode.width == data.width && mode.height == data.height && (data.refreshRate == 0 || data.refreshRate == mode.refreshRate)) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!match) {
|
||||
monitor = nullptr;
|
||||
data.mode = WM_Window;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(data.mode != WM_Fullscreen && (data.width == 0 || data.height == 0)) {
|
||||
GLFWmonitor* primary = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(primary);
|
||||
|
||||
data.width = mode->width;
|
||||
data.height = mode->height;
|
||||
}
|
||||
|
||||
window = glfwCreateWindow(data.width, data.height, "Star Ruler 2", monitor, nullptr);
|
||||
|
||||
if(window == 0)
|
||||
window = glfwCreateWindow(1024,768, "Star Ruler 2 - Error Creating Window", nullptr, nullptr);
|
||||
|
||||
if(window == 0) {
|
||||
error("Could not create window.");
|
||||
return;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
glfwGetWindowSize(window, &win_width, &win_height);
|
||||
glfwSwapInterval( data.verticalSync );
|
||||
|
||||
if(data.mode == WM_Fullscreen)
|
||||
setCursorVisible(true);
|
||||
|
||||
glfwSetWindowCloseCallback(window, redirectWindowClose);
|
||||
glfwSetWindowSizeCallback(window, redirectWindowResize);
|
||||
glfwSetKeyCallback(window, redirectSpecialKey);
|
||||
glfwSetCharCallback(window, redirectCharKey);
|
||||
glfwSetMouseButtonCallback(window, redirectMouseButton);
|
||||
glfwSetScrollCallback(window, redirectMouseWheel);
|
||||
glfwSetCursorPosCallback(window, redirectMouseMove);
|
||||
glfwSetCursorEnterCallback(window, trackMouseOver);
|
||||
|
||||
#ifdef WIN_MODE
|
||||
HICON hSmallIcon = (HICON) LoadImage ( 0, "sr2.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE | LR_DEFAULTCOLOR );
|
||||
SendMessage ( GetActiveWindow(), WM_SETICON, ICON_SMALL, (long)hSmallIcon );
|
||||
#endif
|
||||
}
|
||||
|
||||
void getVideoModes(std::vector<OSDriver::VideoMode>& output) {
|
||||
int count = 0;
|
||||
const GLFWvidmode* modes;
|
||||
auto* primary = glfwGetPrimaryMonitor();
|
||||
if(primary)
|
||||
modes = glfwGetVideoModes(primary, &count);
|
||||
output.reserve(count);
|
||||
output.resize(0);
|
||||
|
||||
std::set<uint64_t> sizes;
|
||||
|
||||
for(int i = 0; i < count; ++i) {
|
||||
VideoMode m;
|
||||
auto& mode = modes[i];
|
||||
m.width = mode.width;
|
||||
m.height = mode.height;
|
||||
m.refresh = mode.refreshRate;
|
||||
|
||||
uint64_t size = (uint64_t)m.width << 16 | (uint64_t)m.height | ((uint64_t)mode.refreshRate << 32);
|
||||
|
||||
if(sizes.find(size) == sizes.end()) {
|
||||
sizes.insert(size);
|
||||
output.push_back(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getMonitorNames(std::vector<std::string>& output) {
|
||||
int count = 0;
|
||||
GLFWmonitor** monitors = glfwGetMonitors(&count);
|
||||
output.resize(count);
|
||||
for(int i = 0; i < count; ++i)
|
||||
output[i] = glfwGetMonitorName(monitors[i]);
|
||||
}
|
||||
|
||||
bool isWindowFocused() override {
|
||||
return glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
|
||||
}
|
||||
|
||||
bool isWindowMinimized() override {
|
||||
return glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0;
|
||||
}
|
||||
|
||||
void flashWindow() override {
|
||||
glfwFlashWindow(window);
|
||||
}
|
||||
|
||||
bool isMouseOver() {
|
||||
return mouseOver;
|
||||
}
|
||||
|
||||
void setClipboard(const std::string& text) {
|
||||
glfwSetClipboardString(window, text.c_str());
|
||||
}
|
||||
|
||||
std::string getClipboard() {
|
||||
const char* str = glfwGetClipboardString(window);
|
||||
if(str)
|
||||
return std::string(str);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
int getCharForKey(int key) {
|
||||
return glfwGetCharForKey(key);
|
||||
}
|
||||
|
||||
int getKeyForChar(unsigned char chr) {
|
||||
return glfwGetKeyForChar(chr);
|
||||
}
|
||||
|
||||
unsigned getDoubleClickTime() const {
|
||||
#ifdef _MSC_VER
|
||||
return GetDoubleClickTime();
|
||||
#else
|
||||
//TODO: Get user's setting on linux
|
||||
return 200;
|
||||
#endif
|
||||
}
|
||||
|
||||
void getLastMousePos(int& x, int& y) {
|
||||
x = mouse_x;
|
||||
y = mouse_y;
|
||||
}
|
||||
|
||||
void getMousePos(int& x, int& y) {
|
||||
double dx, dy;
|
||||
glfwGetCursorPos(window, &dx,&dy);
|
||||
x = (int)floor(dx);
|
||||
y = (int)floor(dy);
|
||||
}
|
||||
|
||||
void setMousePos(int x, int y) {
|
||||
glfwSetCursorPos(window, x,y);
|
||||
}
|
||||
|
||||
void setCursorVisible(bool visible) {
|
||||
glfwSetInputMode(window, GLFW_CURSOR, visible ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_HIDDEN);
|
||||
}
|
||||
|
||||
void setCursorLocked(bool locked) {
|
||||
if(canLock == locked)
|
||||
return;
|
||||
canLock = locked;
|
||||
if(shouldLock) {
|
||||
if(locked)
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED);
|
||||
else
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_FREE);
|
||||
}
|
||||
}
|
||||
|
||||
void setCursorShouldLock(bool locked) {
|
||||
if(shouldLock == locked)
|
||||
return;
|
||||
shouldLock = locked;
|
||||
if(canLock) {
|
||||
if(locked)
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_CAPTURED);
|
||||
else
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_FREE);
|
||||
}
|
||||
}
|
||||
|
||||
void sleep(int milliseconds) {
|
||||
threads::sleep(milliseconds);
|
||||
}
|
||||
|
||||
void resetTimer() {
|
||||
#ifndef WIN_MODE
|
||||
gettimeofday(&start_time, 0);
|
||||
#else
|
||||
FILETIME cur_time;
|
||||
GetSystemTimeAsFileTime(&cur_time);
|
||||
start_time.HighPart = cur_time.dwHighDateTime;
|
||||
start_time.LowPart = cur_time.dwLowDateTime;
|
||||
|
||||
QueryPerformanceFrequency(&start_time_hq_freq);
|
||||
QueryPerformanceCounter(&start_time_hq);
|
||||
#endif
|
||||
frameTime = 0.0;
|
||||
resetGameTime(0);
|
||||
}
|
||||
|
||||
int getTime() const {
|
||||
#ifndef WIN_MODE
|
||||
timeval cur_time;
|
||||
gettimeofday(&cur_time, 0);
|
||||
|
||||
return (int)(
|
||||
1000 * (cur_time.tv_sec - start_time.tv_sec)
|
||||
+ (cur_time.tv_usec - start_time.tv_usec) / 1000);
|
||||
#else
|
||||
|
||||
FILETIME cur_ftime;
|
||||
GetSystemTimeAsFileTime(&cur_ftime);
|
||||
ULARGE_INTEGER cur_time;
|
||||
cur_time.HighPart = cur_ftime.dwHighDateTime;
|
||||
cur_time.LowPart = cur_ftime.dwLowDateTime;
|
||||
|
||||
const double ticksPerSecond = 10000000.0;
|
||||
auto timeInSeconds = (double)(cur_time.QuadPart - start_time.QuadPart) / ticksPerSecond;
|
||||
|
||||
return int(timeInSeconds * 1000.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
double getAccurateTime() const {
|
||||
#ifndef WIN_MODE
|
||||
timeval cur_time;
|
||||
gettimeofday(&cur_time, 0);
|
||||
|
||||
return (double)(cur_time.tv_sec - start_time.tv_sec)
|
||||
+ (double)(cur_time.tv_usec - start_time.tv_usec)/1000000.0;
|
||||
#else
|
||||
LARGE_INTEGER cur_time, cur_freq;
|
||||
QueryPerformanceCounter(&cur_time);
|
||||
QueryPerformanceFrequency(&cur_freq);
|
||||
|
||||
return (double)cur_time.QuadPart / (double)cur_freq.QuadPart - (double)start_time_hq.QuadPart / (double)start_time_hq_freq.QuadPart;
|
||||
#endif
|
||||
}
|
||||
|
||||
void resetGameTime(double time) {
|
||||
//Game time starts slightly ahead of render time
|
||||
gameTime = time;
|
||||
gameSpeed = 1;
|
||||
}
|
||||
|
||||
double getGameTime() const {
|
||||
return gameTime;
|
||||
}
|
||||
|
||||
double getFrameTime() const {
|
||||
return frameTime;
|
||||
}
|
||||
|
||||
double getGameSpeed() const {
|
||||
return gameSpeed;
|
||||
}
|
||||
|
||||
void setGameSpeed(double speed) {
|
||||
gameSpeed = speed;
|
||||
}
|
||||
|
||||
unsigned getProcessorCount() {
|
||||
return std::max(threads::getNumberOfProcessors(),1u);
|
||||
}
|
||||
|
||||
void setWindowTitle(const char* str) {
|
||||
glfwSetWindowTitle(window, str);
|
||||
}
|
||||
|
||||
void setWindowSize(int width, int height){
|
||||
glfwSetWindowSize(window, width, height);
|
||||
}
|
||||
|
||||
void closeWindow() {
|
||||
glfwDestroyWindow(window);
|
||||
}
|
||||
};
|
||||
|
||||
void redirectWindowClose(GLFWwindow*) {
|
||||
driver->onWindowClose();
|
||||
}
|
||||
|
||||
void redirectWindowResize(GLFWwindow*, int w, int h) {
|
||||
driver->onResize(w,h);
|
||||
driver->win_width = w;
|
||||
driver->win_height = h;
|
||||
glViewport(0, 0, w, h);
|
||||
}
|
||||
|
||||
void redirectSpecialKey(GLFWwindow*, int key, int scan, int action, int mods) {
|
||||
driver->shiftKey = (mods & GLFW_MOD_SHIFT) != 0;
|
||||
driver->ctrlKey = (mods & GLFW_MOD_CONTROL) != 0;
|
||||
driver->altKey = (mods & GLFW_MOD_ALT) != 0;
|
||||
|
||||
bool pressed;
|
||||
int keyaction;
|
||||
switch(action) {
|
||||
case GLFW_PRESS:
|
||||
pressed = true;
|
||||
keyaction = KA_Pressed;
|
||||
break;
|
||||
case GLFW_RELEASE:
|
||||
pressed = false;
|
||||
keyaction = KA_Released;
|
||||
break;
|
||||
case GLFW_REPEAT:
|
||||
pressed = true;
|
||||
keyaction = KA_Repeated;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switch(key) {
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
case GLFW_KEY_RIGHT_SHIFT:
|
||||
driver->shiftKey = pressed;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
case GLFW_KEY_RIGHT_CONTROL:
|
||||
driver->ctrlKey = pressed;
|
||||
break;
|
||||
|
||||
case GLFW_KEY_LEFT_ALT:
|
||||
case GLFW_KEY_RIGHT_ALT:
|
||||
driver->altKey = pressed;
|
||||
break;
|
||||
}
|
||||
|
||||
driver->onKeyEvent(key, keyaction);
|
||||
}
|
||||
|
||||
void redirectCharKey(GLFWwindow*, unsigned key) {
|
||||
driver->onCharTyped(key);
|
||||
}
|
||||
|
||||
void redirectMouseButton(GLFWwindow*, int button, int action, int mods) {
|
||||
bool pressed = action == GLFW_PRESS;
|
||||
|
||||
driver->shiftKey = (mods & GLFW_MOD_SHIFT) != 0;
|
||||
driver->ctrlKey = (mods & GLFW_MOD_CONTROL) != 0;
|
||||
driver->altKey = (mods & GLFW_MOD_ALT) != 0;
|
||||
|
||||
switch(button) {
|
||||
case GLFW_MOUSE_BUTTON_LEFT:
|
||||
driver->leftButton = pressed;
|
||||
break;
|
||||
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
driver->rightButton = pressed;
|
||||
break;
|
||||
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
driver->middleButton = pressed;
|
||||
break;
|
||||
}
|
||||
|
||||
driver->onMouseButton(button, pressed);
|
||||
}
|
||||
|
||||
void redirectMouseMove(GLFWwindow*, double x, double y) {
|
||||
driver->onMouseMoved((int)x, (int)y);
|
||||
driver->mouse_x = (int)x;
|
||||
driver->mouse_y = (int)y;
|
||||
}
|
||||
|
||||
void redirectMouseWheel(GLFWwindow*, double x, double y) {
|
||||
driver->onScroll(x, y);
|
||||
}
|
||||
|
||||
void trackMouseOver(GLFWwindow*,int over) {
|
||||
driver->mouseOver = over == GL_TRUE;
|
||||
}
|
||||
|
||||
void glfwError(int code, const char* msg) {
|
||||
error("GLFW Error %d: %s", code, msg);
|
||||
}
|
||||
|
||||
OSDriver* getGLFWDriver() {
|
||||
if(!driver)
|
||||
driver = new GLFWDriver();
|
||||
return driver;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "os/driver.h"
|
||||
|
||||
namespace os {
|
||||
OSDriver* getGLFWDriver();
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
namespace os {
|
||||
|
||||
enum SpecialKey {
|
||||
KEY_A = 65,
|
||||
KEY_ESC = 256,
|
||||
KEY_ENTER,
|
||||
KEY_TAB,
|
||||
KEY_BACKSPACE,
|
||||
KEY_INSERT,
|
||||
KEY_DEL,
|
||||
KEY_RIGHT,
|
||||
KEY_LEFT,
|
||||
KEY_DOWN,
|
||||
KEY_UP,
|
||||
KEY_PAGEUP,
|
||||
KEY_PAGEDOWN,
|
||||
KEY_HOME,
|
||||
KEY_END,
|
||||
KEY_CAPS_LOCK = 280,
|
||||
KEY_SCROLL_LOCK,
|
||||
KEY_NUM_LOCK,
|
||||
KEY_PRINT_SCREEN,
|
||||
KEY_PAUSE,
|
||||
KEY_F1 = 290,
|
||||
KEY_F2,
|
||||
KEY_F3,
|
||||
KEY_F4,
|
||||
KEY_F5,
|
||||
KEY_F6,
|
||||
KEY_F7,
|
||||
KEY_F8,
|
||||
KEY_F9,
|
||||
KEY_F10,
|
||||
KEY_F11,
|
||||
KEY_F12,
|
||||
KEY_F13,
|
||||
KEY_F14,
|
||||
KEY_F15,
|
||||
KEY_F16,
|
||||
KEY_F17,
|
||||
KEY_F18,
|
||||
KEY_F19,
|
||||
KEY_F20,
|
||||
KEY_F21,
|
||||
KEY_F22,
|
||||
KEY_F23,
|
||||
KEY_F24,
|
||||
KEY_F25,
|
||||
KEY_KP_0 = 320,
|
||||
KEY_KP_1,
|
||||
KEY_KP_2,
|
||||
KEY_KP_3,
|
||||
KEY_KP_4,
|
||||
KEY_KP_5,
|
||||
KEY_KP_6,
|
||||
KEY_KP_7,
|
||||
KEY_KP_8,
|
||||
KEY_KP_9,
|
||||
KEY_KP_DECIMAL,
|
||||
KEY_KP_DIVIDE,
|
||||
KEY_KP_MULTIPLY,
|
||||
KEY_KP_SUBTRACT,
|
||||
KEY_KP_ADD,
|
||||
KEY_KP_ENTER,
|
||||
KEY_KP_EQUAL,
|
||||
KEY_LSHIFT = 340,
|
||||
KEY_LCTRL,
|
||||
KEY_LALT,
|
||||
KEY_LSUPER,
|
||||
KEY_RSHIFT,
|
||||
KEY_RCTRL,
|
||||
KEY_RALT,
|
||||
KEY_RSUPER,
|
||||
KEY_MENU,
|
||||
|
||||
KEY_JOY_A,
|
||||
KEY_JOY_B,
|
||||
KEY_JOY_X,
|
||||
KEY_JOY_Y,
|
||||
KEY_JOY_UP,
|
||||
KEY_JOY_LEFT,
|
||||
KEY_JOY_DOWN,
|
||||
KEY_JOY_RIGHT,
|
||||
KEY_JOY_LB,
|
||||
KEY_JOY_LT,
|
||||
KEY_JOY_L3,
|
||||
KEY_JOY_RB,
|
||||
KEY_JOY_RT,
|
||||
KEY_JOY_R3,
|
||||
KEY_JOY_SELECT,
|
||||
KEY_JOY_START
|
||||
};
|
||||
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by Star Ruler 2.rc
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user