diff --git a/src/Client/AsyncDownloader.c b/src/Client/AsyncDownloader.c
index dd3c81616..08c534fa1 100644
--- a/src/Client/AsyncDownloader.c
+++ b/src/Client/AsyncDownloader.c
@@ -212,7 +212,7 @@ bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, Int32* progress) {
static void AsyncDownloader_ProcessRequest(struct AsyncRequest* request) {
String url = String_FromRawArray(request->URL);
Platform_Log2("Downloading from %s (type %b)", &url, &request->RequestType);
- Stopwatch stopwatch; UInt32 elapsedMS;
+ struct Stopwatch stopwatch; UInt32 elapsedMS;
void* handle;
ReturnCode result;
diff --git a/src/Client/Client.vcxproj b/src/Client/Client.vcxproj
index 796b8041e..88f51fcb8 100644
--- a/src/Client/Client.vcxproj
+++ b/src/Client/Client.vcxproj
@@ -298,6 +298,8 @@
+
+
diff --git a/src/Client/Client.vcxproj.filters b/src/Client/Client.vcxproj.filters
index 8711eee04..294d0f10b 100644
--- a/src/Client/Client.vcxproj.filters
+++ b/src/Client/Client.vcxproj.filters
@@ -566,5 +566,11 @@
Source Files\Platform
+
+ Source Files\Platform
+
+
+ Source Files\Platform
+
\ No newline at end of file
diff --git a/src/Client/DisplayDevice.h b/src/Client/DisplayDevice.h
index 7bce22996..c2d833c4a 100644
--- a/src/Client/DisplayDevice.h
+++ b/src/Client/DisplayDevice.h
@@ -19,10 +19,12 @@ struct DisplayDevice {
struct Rectangle2D Bounds;
void* Metadata;
};
+
/* The primary / default / main display device. */
struct DisplayDevice DisplayDevice_Default;
/* Initialises per-platform display device. */
void DisplayDevice_Init(void);
+void* DisplayDevice_Meta[3];
#if !CC_BUILD_D3D9
struct ColorFormat {
diff --git a/src/Client/Game.c b/src/Client/Game.c
index adecf197c..e33a1da0f 100644
--- a/src/Client/Game.c
+++ b/src/Client/Game.c
@@ -552,7 +552,7 @@ void Game_Load(void) {
ServerConnection_BeginConnect();
}
-Stopwatch game_frameTimer;
+struct Stopwatch game_frameTimer;
Real32 game_limitMs;
void Game_SetFpsLimitMethod(FpsLimit method) {
Game_FpsLimit = method;
@@ -751,7 +751,7 @@ void Game_Free(void* obj) {
Options_Save();
}
-Stopwatch game_renderTimer;
+struct Stopwatch game_renderTimer;
void Game_Run(Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device) {
Int32 x = device->Bounds.X + (device->Bounds.Width - width) / 2;
Int32 y = device->Bounds.Y + (device->Bounds.Height - height) / 2;
diff --git a/src/Client/Platform.h b/src/Client/Platform.h
index b568f19e6..fcf1edd88 100644
--- a/src/Client/Platform.h
+++ b/src/Client/Platform.h
@@ -80,9 +80,9 @@ void Platform_EventFree(void* handle);
void Platform_EventSignal(void* handle);
void Platform_EventWait(void* handle);
-typedef Int64 Stopwatch;
-void Stopwatch_Start(Stopwatch* timer);
-Int32 Stopwatch_ElapsedMicroseconds(Stopwatch* timer);
+struct Stopwatch { UInt16 Data[2]; };
+void Stopwatch_Start(struct Stopwatch* timer);
+Int32 Stopwatch_ElapsedMicroseconds(struct Stopwatch* timer);
ReturnCode Platform_StartShell(STRING_PURE String* args);
void Platform_FontMake(struct FontDesc* desc, STRING_PURE String* fontName, UInt16 size, UInt16 style);
diff --git a/src/Client/WinPlatform.c b/src/Client/WinPlatform.c
index 38510c8ed..ac8db7863 100644
--- a/src/Client/WinPlatform.c
+++ b/src/Client/WinPlatform.c
@@ -349,22 +349,28 @@ void Platform_EventWait(void* handle) {
WaitForSingleObject((HANDLE)handle, INFINITE);
}
-void Stopwatch_Start(Stopwatch* timer) {
+void Stopwatch_Measure(struct Stopwatch* timer) {
if (stopwatch_highResolution) {
- QueryPerformanceCounter(timer);
+ LARGE_INTEGER value;
+ QueryPerformanceCounter(&value);
+ timer->Data[0] = value.QuadPart;
} else {
- GetSystemTimeAsFileTime(timer);
+ FILETIME value;
+ GetSystemTimeAsFileTime(&value);
+ timer->Data[0] = (Int64)value.dwLowDateTime | ((Int64)value.dwHighDateTime << 32);
}
}
+void Stopwatch_Start(struct Stopwatch* timer) { Stopwatch_Measure(timer); }
/* TODO: check this is actually accurate */
-Int32 Stopwatch_ElapsedMicroseconds(Stopwatch* timer) {
- Int64 start = *timer, end;
+Int32 Stopwatch_ElapsedMicroseconds(struct Stopwatch* timer) {
+ Int64 start = timer->Data[0];
+ Stopwatch_Measure(timer);
+ Int64 end = timer->Data[0];
+
if (stopwatch_highResolution) {
- QueryPerformanceCounter(&end);
return (Int32)(((end - start) * 1000 * 1000) / stopwatch_freq.QuadPart);
} else {
- GetSystemTimeAsFileTime(&end);
return (Int32)((end - start) / 10);
}
}
diff --git a/src/Client/X11DisplayDevice.c b/src/Client/X11DisplayDevice.c
new file mode 100644
index 000000000..284bb8fcf
--- /dev/null
+++ b/src/Client/X11DisplayDevice.c
@@ -0,0 +1,30 @@
+#include "DisplayDevice.h"
+#if CC_BUILD_X11
+#include "Typedefs.h"
+#include "ErrorHandler.h"
+#include
+
+void DisplayDevice_Init(void) {
+ Display* display = XOpenDisplay(NULL);
+ if (display == NULL) {
+ ErrorHandler_Fail("Failed to open display");
+ }
+
+ int screen = XDefaultScreen(display);
+ Window rootWin = XRootWindow(display, screen);
+
+ /* TODO: Use Xinerama and XRandR for querying these */
+ int screens = XScreenCount(display), i;
+ for (i = 0; i < screens; i++) {
+ struct DisplayDevice device = { 0 };
+ device.Bounds.Width = DisplayWidth(display, i);
+ device.Bounds.Height = DisplayHeight(display, i);
+ device.BitsPerPixel = DefaultDepth(display, i);
+ if (i == screen) DisplayDevice_Default = device;
+ }
+
+ DisplayDevice_Meta[0] = display;
+ DisplayDevice_Meta[1] = screen;
+ DisplayDevice_Meta[2] = rootWin;
+}
+#endif
\ No newline at end of file
diff --git a/src/Client/X11ErrorHandler.c b/src/Client/X11ErrorHandler.c
new file mode 100644
index 000000000..b57307d21
--- /dev/null
+++ b/src/Client/X11ErrorHandler.c
@@ -0,0 +1,27 @@
+#include "ErrorHandler.h"
+#if CC_BUILD_X11
+#include "Platform.h"
+
+void ErrorHandler_Init(const UChar* logFile) {
+ /* TODO: Implement this */
+}
+
+void ErrorHandler_Log(STRING_PURE String* msg) {
+ /* TODO: Implement this */
+}
+
+void ErrorHandler_Fail(const UChar* raw_msg) {
+ /* TODO: Implement this */
+ Platform_Exit(1);
+}
+
+void ErrorHandler_FailWithCode(ReturnCode code, const UChar* raw_msg) {
+ /* TODO: Implement this */
+ Platform_Exit(code);
+}
+
+void ErrorHandler_ShowDialog(const UChar* title, const UChar* msg) {
+ /* TODO: Implement this */
+}
+
+#endif
diff --git a/src/Client/X11Platform.c b/src/Client/X11Platform.c
index 177c4a6f9..f10629d34 100644
--- a/src/Client/X11Platform.c
+++ b/src/Client/X11Platform.c
@@ -3,6 +3,7 @@
#include "PackedCol.h"
#include "Drawer2D.h"
#include "Stream.h"
+#include "Funcs.h"
#include "ErrorHandler.h"
#include "Constants.h"
#include
@@ -45,7 +46,11 @@ void Platform_Free(void) {
}
void Platform_Exit(ReturnCode code) { exit(code); }
-STRING_PURE String Platform_GetCommandLineArgs(void);
+
+STRING_PURE String Platform_GetCommandLineArgs(void) {
+ /* TODO: Implement this */
+ return String_MakeNull();
+}
void* Platform_MemAlloc(UInt32 numElems, UInt32 elemsSize) {
return malloc(numElems * elemsSize);
@@ -227,7 +232,7 @@ void* Platform_ThreadStartCallback(void* lpParam) {
pthread_t threadList[3]; Int32 threadIndex;
void* Platform_ThreadStart(Platform_ThreadFunc* func) {
- if (threadIndex == Array_Elems(threadIndex)) ErrorHandler_Fail("Cannot allocate thread");
+ if (threadIndex == Array_Elems(threadList)) ErrorHandler_Fail("Cannot allocate thread");
pthread_t* ptr = &threadList[threadIndex];
int result = pthread_create(ptr, NULL, Platform_ThreadStartCallback, func);
@@ -291,24 +296,40 @@ void Platform_EventSignal(void* handle) {
}
void Platform_EventWait(void* handle) {
- int result = pthread_cond_wait((pthread_cond_t*)handle, event_mutex);
+ int result = pthread_cond_wait((pthread_cond_t*)handle, &event_mutex);
ErrorHandler_CheckOrFail(result, "Waiting event");
}
-void Stopwatch_Start(Stopwatch* timer);
-Int32 Stopwatch_ElapsedMicroseconds(Stopwatch* timer);
+void Stopwatch_Measure(struct Stopwatch* timer) {
+ struct timespec value;
+ /* TODO: CLOCK_MONOTONIC_RAW ?? */
+ clock_gettime(CLOCK_MONOTONIC, &value);
+ timer->Data[0] = value.tv_sec;
+ timer->Data[1] = value.tv_nsec;
+}
+void Stopwatch_Start(struct Stopwatch* timer) { Stopwatch_Measure(timer); }
-void Platform_FontMake(struct FontDesc* desc, STRING_PURE String* fontName, UInt16 size, UInt16 style);
-void Platform_FontFree(struct FontDesc* desc);
-struct Size2D Platform_TextMeasure(struct DrawTextArgs* args);
-void Platform_SetBitmap(struct Bitmap* bmp);
-struct Size2D Platform_TextDraw(struct DrawTextArgs* args, Int32 x, Int32 y, PackedCol col);
-void Platform_ReleaseBitmap(void);
+/* TODO: check this is actually accurate */
+Int32 Stopwatch_ElapsedMicroseconds(struct Stopwatch* timer) {
+ Int64 startS = timer->Data[0], startNS = timer->Data[1];
+ Stopwatch_Measure(timer);
+ Int64 endS = timer->Data[0], endNS = timer->Data[1];
+ return (endS - startS) * (1000 * 1000) + (endNS - startNS) / 1000;
+}
-void Platform_HttpInit(void);
-ReturnCode Platform_HttpMakeRequest(struct AsyncRequest* request, void** handle);
-ReturnCode Platform_HttpGetRequestHeaders(struct AsyncRequest* request, void* handle, UInt32* size);
-ReturnCode Platform_HttpGetRequestData(struct AsyncRequest* request, void* handle, void** data, UInt32 size, volatile Int32* progress);
-ReturnCode Platform_HttpFreeRequest(void* handle);
-ReturnCode Platform_HttpFree(void);
+/* TODO: Implement these stubs */
+void Platform_FontMake(struct FontDesc* desc, STRING_PURE String* fontName, UInt16 size, UInt16 style) { }
+void Platform_FontFree(struct FontDesc* desc) { }
+struct Size2D Platform_TextMeasure(struct DrawTextArgs* args) { }
+void Platform_SetBitmap(struct Bitmap* bmp) { }
+struct Size2D Platform_TextDraw(struct DrawTextArgs* args, Int32 x, Int32 y, PackedCol col) { }
+void Platform_ReleaseBitmap(void) { }
+
+/* TODO: Implement these stubs */
+void Platform_HttpInit(void) { }
+ReturnCode Platform_HttpMakeRequest(struct AsyncRequest* request, void** handle) { return 1; }
+ReturnCode Platform_HttpGetRequestHeaders(struct AsyncRequest* request, void* handle, UInt32* size) { return 1; }
+ReturnCode Platform_HttpGetRequestData(struct AsyncRequest* request, void* handle, void** data, UInt32 size, volatile Int32* progress) { return 1; }
+ReturnCode Platform_HttpFreeRequest(void* handle) { return 1; }
+ReturnCode Platform_HttpFree(void) { return 1; }
#endif
diff --git a/src/Client/X11Window.c b/src/Client/X11Window.c
index 5fd413b8d..a2a842dee 100644
--- a/src/Client/X11Window.c
+++ b/src/Client/X11Window.c
@@ -14,10 +14,9 @@
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
-/* TODO: Move to Platform code */
Display* win_display;
-Window win_rootWin;
int win_screen;
+Window win_rootWin;
Window win_handle;
XVisualInfo win_visual;
@@ -149,6 +148,10 @@ void Window_RegisterAtoms(void) {
static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode);
void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title,
struct GraphicsMode* mode, struct DisplayDevice* device) {
+ win_display = DisplayDevice_Meta[0];
+ win_screen = DisplayDevice_Meta[1];
+ win_rootWin = DisplayDevice_Meta[2];
+
/* Open a display connection to the X server, and obtain the screen and root window */
UInt64 addr = (UInt64)win_display;
Platform_Log3("Display: %y, Screen %i, Root window: %y", &addr, &win_screen, &win_rootWin);
@@ -376,6 +379,12 @@ void Window_Close(void) {
XFlush(win_display);
}
+void Window_Destroy(void) {
+ XSync(win_display, true);
+ XDestroyWindow(win_display, win_handle);
+ Window_Exists = false;
+}
+
void Window_RefreshBorders(void) {
Atom prop_type;
int prop_format;
@@ -423,7 +432,7 @@ void Window_ToggleKey(XKeyEvent* keyEvent, bool pressed) {
Key key = Window_MapKey(keysym1);
if (key == Key_None) key = Window_MapKey(keysym2);
- if (key != Key_None) Keyboard_Set(key, pressed);
+ if (key != Key_None) Key_SetPressed(key, pressed);
}
Atom Window_GetSelectionProperty(XEvent* e) {
@@ -460,11 +469,11 @@ void Window_ProcessEvents(void) {
case ClientMessage:
if (!win_isExiting && e.xclient.data.l[0] == wm_destroy) {
Platform_LogConst("Exit message received.");
- RaiseClosing();
+ Event_RaiseVoid(&WindowEvents_Closing);
win_isExiting = true;
Window_Destroy();
- RaiseClosed();
+ Event_RaiseVoid(&WindowEvents_Closed);
} break;
case DestroyNotify:
@@ -503,25 +512,25 @@ void Window_ProcessEvents(void) {
break;
case ButtonPress:
- if (e.xbutton.button == 1) Mouse_Set(MouseButton_Left, true);
- else if (e.xbutton.button == 2) Mouse_Set(MouseButton_Middle, true);
- else if (e.xbutton.button == 3) Mouse_Set(MouseButton_Right, true);
+ if (e.xbutton.button == 1) Mouse_SetPressed(MouseButton_Left, true);
+ else if (e.xbutton.button == 2) Mouse_SetPressed(MouseButton_Middle, true);
+ else if (e.xbutton.button == 3) Mouse_SetPressed(MouseButton_Right, true);
else if (e.xbutton.button == 4) Mouse_SetWheel(Mouse_Wheel + 1);
else if (e.xbutton.button == 5) Mouse_SetWheel(Mouse_Wheel - 1);
- else if (e.xbutton.button == 6) Keyboard_Set(Key_XButton1, true);
- else if (e.xbutton.button == 7) Keyboard_Set(Key_XButton2, true);
+ else if (e.xbutton.button == 6) Key_SetPressed(Key_XButton1, true);
+ else if (e.xbutton.button == 7) Key_SetPressed(Key_XButton2, true);
break;
case ButtonRelease:
- if (e.xbutton.button == 1) Mouse_Set(MouseButton_Left, false);
- else if (e.xbutton.button == 2) Mouse_Set(MouseButton_Middle, false);
- else if (e.xbutton.button == 3) Mouse_Set(MouseButton_Right, false);
- else if (e.xbutton.button == 6) Keyboard_Set(Key_XButton1, false);
- else if (e.xbutton.button == 7) Keyboard_Set(Key_XButton2, false);
+ if (e.xbutton.button == 1) Mouse_SetPressed(MouseButton_Left, false);
+ else if (e.xbutton.button == 2) Mouse_SetPressed(MouseButton_Middle, false);
+ else if (e.xbutton.button == 3) Mouse_SetPressed(MouseButton_Right, false);
+ else if (e.xbutton.button == 6) Key_SetPressed(Key_XButton1, false);
+ else if (e.xbutton.button == 7) Key_SetPressed(Key_XButton2, false);
break;
case MotionNotify:
- Mouse_SetPos(e.xmotion.x, e.xmotion.y);
+ Mouse_SetPosition(e.xmotion.x, e.xmotion.y);
break;
case FocusIn:
@@ -544,7 +553,7 @@ void Window_ProcessEvents(void) {
case PropertyNotify:
if (e.xproperty.atom == net_wm_state) {
- Event_RaiseVoid(&WindowEvents_StateChanged);
+ Event_RaiseVoid(&WindowEvents_WindowStateChanged);
}
//if (e.xproperty.atom == net_frame_extents) {