refactored linux code to fit new entry point style, some x11 code added

This commit is contained in:
Matthew 2025-03-08 12:30:04 +11:00
parent 6bb0c2f134
commit f3ac3cc36c
11 changed files with 253 additions and 298 deletions

View File

@ -57,7 +57,7 @@ gcc_link="-lpthread -lm -lrt -ldl -l:libvma.a -lstdc++"
gcc_out="-o" gcc_out="-o"
link_dll="-fPIC" link_dll="-fPIC"
link_os_gfx="-lxcb -lvulkan" link_os_gfx="-lxcb -lX11 -lX11-xcb -lvulkan"
if [ -v gcc ]; then compile_debug="$gcc_debug"; fi if [ -v gcc ]; then compile_debug="$gcc_debug"; fi
if [ -v gcc ]; then compile_release="$gcc_release"; fi if [ -v gcc ]; then compile_release="$gcc_release"; fi

View File

@ -10,9 +10,31 @@
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
u8 *mem = (u8 *)MemAllocZeroed(MB(32));
Arena *arena = CreateArenaDebug(mem, MB(32), __LINE__);
isize renderer_mem_size = MB(8);
rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size);
Arena *renderer_arena = CreateArenaDebug(renderer_mem, MB(8), __LINE__);
Assert(CreatePlatformWindow(), "Failed to initialize the window"); Assert(CreatePlatformWindow(), "Failed to initialize the window");
InitializeGame();
Run(); GameInput *inputs = ArenaAlloc(arena, sizeof(GameInput) * 10);
u32 i_count = 0;
WaitForWindowEvent(inputs);
InitializeGame(renderer_arena);
while (!global_quit)
{
GetWindowEvents(inputs, &i_count);
RunCycle(inputs, i_count);
}
DestroyGame();
} }
#endif // __linux__ #endif // __linux__

View File

@ -10,6 +10,7 @@
#include "stb/stb_sprintf.h" #include "stb/stb_sprintf.h"
#include "shared_types.h"
#include "platform.h" #include "platform.h"
#include "util.h" #include "util.h"
#include "arena.h" #include "arena.h"

View File

@ -1,72 +1,17 @@
static void InitializeGame() static void InitializeGame(Arena *arena)
{ {
// Will keep adjusting memory as needed Assert(InitRenderer(arena), "Failed to initialize the renderer");
u8 *mem = (u8 *)MemAllocZeroed(MB(32));
Arena *arena = CreateArenaDebug(mem, MB(32), __LINE__);
isize renderer_mem_size = MB(8);
rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size);
Arena *renderer_arena = CreateArenaDebug(renderer_mem, MB(8), __LINE__);
Assert(InitRenderer(renderer_arena), "Failed to initialize the renderer");
} }
static void Run() static void DestroyGame()
{ {
b32 quit = false;
while (!quit)
{
if (HandleEvents()) break;
BeginFrame();
DrawTriangle();
FinishFrame();
}
DestroyRenderer(); DestroyRenderer();
} }
static b32 HandleEvents() static void RunCycle(GameInput *inputs, u32 i_count)
{ {
b32 quit = false; BeginFrame();
DrawTriangle();
WindowEvent e; FinishFrame();
while (GetWindowEvent(&e))
{
quit = ProcessEvent(&e);
}
return quit;
}
static b32 WaitForAndHandleEvent()
{
WindowEvent e;
WaitForWindowEvent(&e);
return ProcessEvent(&e);
}
static b32 ProcessEvent(WindowEvent *e)
{
b32 quit = false;
switch (e->type)
{
case EVENT_QUIT:
quit = true;
break;
case EVENT_RESIZE:
SetRenderResolution(e->resize.w, e->resize.h);
break;
case EVENT_MINIMIZE:
break;
case EVENT_SHOW:
break;
default:
break;
}
return quit;
} }

View File

@ -1,107 +1,6 @@
#pragma once #pragma once
typedef enum KeyboardInput_e static void RunCycle(GameInput *inputs, u32 i_count);
{ static void InitializeGame(Arena *arena);
KB_A, static void DestroyGame();
KB_B,
KB_C,
KB_D,
KB_E,
KB_F,
KB_G,
KB_H,
KB_I,
KB_J,
KB_K,
KB_L,
KB_M,
KB_N,
KB_O,
KB_P,
KB_Q,
KB_R,
KB_S,
KB_T,
KB_U,
KB_V,
KB_W,
KB_X,
KB_Y,
KB_Z,
KB_0,
KB_1,
KB_2,
KB_3,
KB_4,
KB_5,
KB_6,
KB_7,
KB_8,
KB_9,
KB_NUM_0,
KB_NUM_1,
KB_NUM_2,
KB_NUM_3,
KB_NUM_4,
KB_NUM_5,
KB_NUM_6,
KB_NUM_7,
KB_NUM_8,
KB_NUM_9,
KB_NUM_LOCK,
KB_NUM_SLASH,
KB_NUM_STAR,
KB_NUM_MIN
KB_NUM_PLUS
KB_NUM_ENTER,
KB_NUM_DEL,
KB_INSERT,
KB_DELETE,
KB_HOME,
KB_PAGE_UP,
KB_PAGE_DOWN,
KB_PRINT_SCREEN,
KB_SCROLL_LOCK,
KB_COMMA,
KB_PERIOD,
KB_BACK_SLASH,
KB_FORWARD_SLASH,
KB_MINUS,
KB_PLUS,
KB_F1,
KB_F2,
KB_F3,
KB_F4,
KB_F5,
KB_F6,
KB_F7,
KB_F8,
KB_F9,
KB_F10,
KB_F11,
KB_F12,
KB_UP,
KB_DOWN,
KB_LEFT,
KB_RIGHT,
KB_LEFT_CTRL,
KB_LEFT_ALT,
KB_LEFT_SHIFT,
KB_TAB,
KB_CAPS_LOCK,
KB_LEFT_SUPER,
KB_RIGHT_SUPER,
KB_ENTER,
KB_TILDE,
KB_ESC,
KB_SEMI_COLON,
KB_QUOTE,
KB_LEFT_BRACE,
KB_RIGHT_BRACE,
KB_BACK_SPACE
};
static void Run();
static b32 HandleEvents();
static b32 WaitForAndHandleEvent();
static b32 ProcessEvent(WindowEvent *e);

View File

@ -87,21 +87,11 @@ b32 CreatePlatformWindow()
return _CreateWindow(); return _CreateWindow();
} }
Window *GetWindowPtr() GameWindow *GetWindowPtr()
{ {
return _GetWindow(); return _GetWindow();
} }
b32 GetWindowEvent(WindowEvent *event)
{
return _GetWindowEvent(event);
}
void WaitForWindowEvent(WindowEvent *event)
{
_WaitForWindowEvent(event);
}
WindowSize GetWindowSize() WindowSize GetWindowSize()
{ {
return _GetWindowSize(); return _GetWindowSize();

View File

@ -62,8 +62,6 @@ i32 EPrintf(const char *fmt, ...);
// Window Functions // Window Functions
b32 CreatePlatformWindow(); b32 CreatePlatformWindow();
b32 GetWindowEvent(WindowEvent *event);
void WaitForWindowEvent(WindowEvent *event);
WindowSize GetWindowSize(); WindowSize GetWindowSize();
b32 NeedWindowResize(); b32 NeedWindowResize();
b32 ShouldQuit(); b32 ShouldQuit();

View File

@ -1,11 +1,11 @@
// TODO(MA): Do stuff for general unix platforms some day // TODO(MA): Do stuff for general unix platforms some day
static Window linux_window = { static GameWindow linux_window = {
.w = 1920, .w = 1920,
.h = 1080, .h = 1080,
}; };
b32 global_quit = false;
// Init // Init
@ -140,14 +140,16 @@ isize _GetPageSize()
b32 _CreateWindow() b32 _CreateWindow()
{ {
Window *window = &linux_window; GameWindow *window = &linux_window;
int screen_index; window->display = XOpenDisplay(NULL);
window->connection = xcb_connect(NULL, &screen_index); if (!window->display)
return false;
if (!window->connection) {
window->connection = XGetXCBConnection(window->display);
if (!window->connection)
return false; return false;
}
xcb_void_cookie_t cookie; xcb_void_cookie_t cookie;
xcb_generic_error_t *error; xcb_generic_error_t *error;
@ -244,7 +246,7 @@ b32 _CreateWindow()
return true; return true;
} }
Window *_GetWindow() { GameWindow *_GetWindow() {
return &linux_window; return &linux_window;
} }
@ -256,22 +258,20 @@ WindowSize _GetWindowSize()
}; };
} }
b32 _GetWindowEvent(WindowEvent *event) void GetWindowEvents(GameInput *inputs, u32 *i_count)
{ {
return HandleWindowEvent(event, false); HandleWindowEvent(inputs, i_count, false);
} }
void _WaitForWindowEvent(WindowEvent *event) b32 WaitForWindowEvent(GameInput *input)
{ {
HandleWindowEvent(event, true); u32 i_count;
HandleWindowEvent(input, &i_count, true);
return i_count > 0;
} }
b32 HandleWindowEvent(WindowEvent *event, b32 wait_for_event) void HandleWindowEvent(GameInput *inputs, u32 *i_count, b32 wait_for_event)
{ {
Assert(event != NULL, "GetWindowEvent received a null pointer");
b32 valid_event = false;
b32 no_event = false;
do do
{ {
xcb_generic_event_t *e; xcb_generic_event_t *e;
@ -286,45 +286,40 @@ b32 HandleWindowEvent(WindowEvent *event, b32 wait_for_event)
switch (e->response_type & ~0x80) switch (e->response_type & ~0x80)
{ {
case XCB_CLIENT_MESSAGE: case XCB_CLIENT_MESSAGE:
xcb_client_message_event_t *msg = (xcb_client_message_event_t *)e;
if (msg->data.data32[0] == linux_window.close_event)
{ {
event->type = EVENT_QUIT; xcb_client_message_event_t *msg = (xcb_client_message_event_t *)e;
valid_event = true; if (msg->data.data32[0] == linux_window.close_event)
} {
if (msg->data.data32[0] == linux_window.minimize_event) global_quit = true;
{ }
event->type = EVENT_MINIMIZE; } break;
valid_event = true;
linux_window.w = 0;
linux_window.h = 0;
}
break;
case XCB_UNMAP_NOTIFY:
break;
case XCB_EXPOSE: case XCB_EXPOSE:
event->type = EVENT_SHOW;
xcb_expose_event_t *expose_e = (xcb_expose_event_t *)e;
linux_window.w = expose_e->width;
linux_window.h = expose_e->height;
break;
case XCB_CONFIGURE_NOTIFY:
xcb_configure_notify_event_t *configure_event = (xcb_configure_notify_event_t *)e;
if (linux_window.w != configure_event->width || linux_window.h != configure_event->height)
{ {
event->type = EVENT_RESIZE; xcb_expose_event_t *expose_e = (xcb_expose_event_t *)e;
valid_event = true; linux_window.w = expose_e->width;
linux_window.h = expose_e->height;
} break;
case XCB_CONFIGURE_NOTIFY:
{
xcb_configure_notify_event_t *configure_event = (xcb_configure_notify_event_t *)e;
event->resize.w = configure_event->width; if (linux_window.w != configure_event->width || linux_window.h != configure_event->height)
event->resize.h = configure_event->height; {
linux_window.w = configure_event->width;
linux_window.w = configure_event->width; linux_window.h = configure_event->height;
linux_window.h = configure_event->height; SetRenderResolution(linux_window.w, linux_window.h);
} }
} break;
break; case XCB_KEY_RELEASE:
case XCB_KEY_PRESS:
{
xcb_key_press_event_t *keyboard_e = (xcb_key_press_event_t *)e;
b8 pressed = e->response_type == XCB_KEY_PRESS;
xcb_keycode_t code = keyboard_e->detail;
KeySym keysym = XkbKeycodeToKeysym(linux_window.display, (KeyCode)code, 0, 0);
} break;
// case XCB_BUTTON_PRESS: (mouse input)
// case XCB_BUTTON_RELEASE:
default: default:
break; break;
} }
@ -335,11 +330,19 @@ b32 HandleWindowEvent(WindowEvent *event, b32 wait_for_event)
{ {
break; break;
} }
} while(!wait_for_event);
}
KeyboardInput ConvertInputEvent(u32 x_key)
{
KeyboardInput key = KB_NONE;
switch (x_key)
{
} while(!valid_event && !wait_for_event); }
return valid_event; return key;
} }
b32 ChangeWorkingDir(const char *) b32 ChangeWorkingDir(const char *)
@ -365,4 +368,3 @@ b32 _ShouldQuit()
{ {
return false; return false;
} }

View File

@ -3,6 +3,9 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <X11/XKBlib.h>
#include <X11/Xlib-xcb.h>
#include <X11/Xlib.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
@ -35,37 +38,14 @@
XCB_CHECK_CURRENT_ERROR(window, error, message); \ XCB_CHECK_CURRENT_ERROR(window, error, message); \
} while (0) } while (0)
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef intptr_t intptr;
typedef uintptr_t uintptr;
typedef ssize_t isize;
typedef size_t usize;
typedef float f32;
typedef double f64;
typedef uint8_t b8;
typedef uint32_t b32;
typedef void * rawptr;
typedef struct { typedef struct {
Display *display;
xcb_connection_t *connection; xcb_connection_t *connection;
xcb_window_t window; xcb_window_t window;
xcb_atom_t close_event; xcb_atom_t close_event;
xcb_atom_t minimize_event; xcb_atom_t minimize_event;
u16 w, h; u16 w, h;
} Window; } GameWindow;
typedef struct { typedef struct {
void *lib; void *lib;
@ -75,36 +55,6 @@ typedef struct {
void *fn; void *fn;
} Function; } Function;
// X11
typedef struct
{
} XConnectRequest;
typedef struct {
u8 opcode;
u16 len; // length in units of 4 bytes
u8 data;
// Extra data
} XRequest;
typedef struct {
u32 len;
} XReply;
typedef struct {
} XError;
typedef struct {
} XEvent;
typedef u32 XWindow;
typedef u32 XAtom;
typedef u32 XVisID;
// Platform API // Platform API
// Init Functions // Init Functions
@ -125,11 +75,12 @@ i32 _EPrintf(const char *fmt, va_list arg);
// Window Functions // Window Functions
b32 _CreateWindow(); b32 _CreateWindow();
Window *_GetWindow(); GameWindow *_GetWindow();
b32 _GetWindowEvent(WindowEvent *event); void GetWindowEvents(GameInput *inputs, u32 *i_count);
void _WaitForWindowEvent(WindowEvent *event); b32 WaitForWindowEvent(GameInput *input);
WindowSize _GetWindowSize(); WindowSize _GetWindowSize();
b32 HandleWindowEvent(WindowEvent *event, b32 wait_for_event); void HandleWindowEvent(GameInput *inputs, u32 *input_count, b32 wait_for_event);
KeyboardInput ConvertInputEvent(u32 x_key);
// Platform API END // Platform API END

View File

@ -745,7 +745,7 @@ static b32 InitVkDeviceFunctions() {
#ifdef __linux__ #ifdef __linux__
static b32 CreateSurface() static b32 CreateSurface()
{ {
Window *window = GetWindowPtr(); GameWindow *window = GetWindowPtr();
VkXcbSurfaceCreateInfoKHR surface_info = { VkXcbSurfaceCreateInfoKHR surface_info = {
.sType = STYPE(XCB_SURFACE_CREATE_INFO_KHR), .sType = STYPE(XCB_SURFACE_CREATE_INFO_KHR),
.connection = window->connection, .connection = window->connection,

147
src/shared_types.h Normal file
View File

@ -0,0 +1,147 @@
#pragma once
#ifdef __linux__
#include <stdint.h>
#include <sys/types.h>
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef intptr_t intptr;
typedef uintptr_t uintptr;
typedef ssize_t isize;
typedef size_t usize;
typedef float f32;
typedef double f64;
typedef uint8_t b8;
typedef uint32_t b32;
typedef void * rawptr;
#elif _WIN32
#elif __APPLE__ || __MACH__
#else // unix
#endif
typedef enum KeyboardInput_e
{
KB_NONE,
KB_A,
KB_B,
KB_C,
KB_D,
KB_E,
KB_F,
KB_G,
KB_H,
KB_I,
KB_J,
KB_K,
KB_L,
KB_M,
KB_N,
KB_O,
KB_P,
KB_Q,
KB_R,
KB_S,
KB_T,
KB_U,
KB_V,
KB_W,
KB_X,
KB_Y,
KB_Z,
KB_0,
KB_1,
KB_2,
KB_3,
KB_4,
KB_5,
KB_6,
KB_7,
KB_8,
KB_9,
KB_NUM_0,
KB_NUM_1,
KB_NUM_2,
KB_NUM_3,
KB_NUM_4,
KB_NUM_5,
KB_NUM_6,
KB_NUM_7,
KB_NUM_8,
KB_NUM_9,
KB_NUM_LOCK,
KB_NUM_SLASH,
KB_NUM_STAR,
KB_NUM_MIN,
KB_NUM_PLUS,
KB_NUM_ENTER,
KB_NUM_DEL,
KB_INSERT,
KB_DELETE,
KB_HOME,
KB_PAGE_UP,
KB_PAGE_DOWN,
KB_PRINT_SCREEN,
KB_SCROLL_LOCK,
KB_COMMA,
KB_PERIOD,
KB_BACK_SLASH,
KB_FORWARD_SLASH,
KB_MINUS,
KB_PLUS,
KB_F1,
KB_F2,
KB_F3,
KB_F4,
KB_F5,
KB_F6,
KB_F7,
KB_F8,
KB_F9,
KB_F10,
KB_F11,
KB_F12,
KB_UP,
KB_DOWN,
KB_LEFT,
KB_RIGHT,
KB_LEFT_CTRL,
KB_LEFT_ALT,
KB_LEFT_SHIFT,
KB_TAB,
KB_CAPS_LOCK,
KB_LEFT_SUPER,
KB_RIGHT_SUPER,
KB_ENTER,
KB_TILDE,
KB_ESC,
KB_SEMI_COLON,
KB_QUOTE,
KB_LEFT_BRACE,
KB_RIGHT_BRACE,
KB_BACK_SPACE,
KB_MAX
} KeyboardInput;
typedef struct
{
KeyboardInput code;
b8 pressed;
} GameInput; // TODO: add gamepad input