From 9b8fdb3de7a0b7f9d1fb1f1913a9a0110237217c Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 18 Jul 2018 14:42:43 +1000 Subject: [PATCH] C client now compiles on linux (with some missing functionality) --- src/Client/AsyncDownloader.c | 2 +- src/Client/Client.vcxproj | 2 ++ src/Client/Client.vcxproj.filters | 6 ++++ src/Client/DisplayDevice.h | 2 ++ src/Client/Game.c | 4 +-- src/Client/Platform.h | 6 ++-- src/Client/WinPlatform.c | 20 +++++++---- src/Client/X11DisplayDevice.c | 30 +++++++++++++++++ src/Client/X11ErrorHandler.c | 27 +++++++++++++++ src/Client/X11Platform.c | 55 +++++++++++++++++++++---------- src/Client/X11Window.c | 43 ++++++++++++++---------- 11 files changed, 150 insertions(+), 47 deletions(-) create mode 100644 src/Client/X11DisplayDevice.c create mode 100644 src/Client/X11ErrorHandler.c 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) {