vtgl.h (12086B)
1 /* See LICENSE for copyright details */ 2 #ifndef _VTGL_H_ 3 #define _VTGL_H_ 4 5 #include <stddef.h> 6 #include <stdint.h> 7 8 #ifndef asm 9 #define asm __asm__ 10 #endif 11 12 #ifndef typeof 13 #define typeof __typeof__ 14 #endif 15 16 #ifndef static_assert 17 #define static_assert _Static_assert 18 #endif 19 20 #define atomic_and(ptr, n) __atomic_and_fetch(ptr, n, __ATOMIC_RELEASE); 21 #define atomic_fetch_add(ptr, n) __atomic_fetch_add(ptr, n, __ATOMIC_RELEASE); 22 #define atomic_load(ptr) __atomic_load_n(ptr, __ATOMIC_ACQUIRE) 23 #define atomic_exchange_n(ptr, val) __atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST) 24 25 #define PI 3.1415926535897932384f 26 27 #define KB(a) ((a) << 10ULL) 28 #define MB(a) ((a) << 20ULL) 29 30 #define ARRAY_COUNT(a) (size)(sizeof(a) / sizeof(*a)) 31 #define ABS(a) ((a) < 0 ? (-a) : (a)) 32 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 33 #define CLAMP(x, a, b) ((x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 34 #define MAX(a, b) ((a) >= (b) ? (a) : (b)) 35 #define MIN(a, b) ((a) <= (b) ? (a) : (b)) 36 #define SGN(a) ((a) < 0 ? (-1) : (1)) 37 38 #define SAFE_RATIO_1(a, b) ((b) ? (a) / (b) : (a)) 39 40 #define ISCONTROLC0(c) ((c) <= 0x1F || (c) == 0x7F) 41 #define ISCONTROLC1(c) (BETWEEN((c), 0x80, 0x9F)) 42 #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) 43 #define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\t') 44 #define ISPRINT(c) BETWEEN((c), ' ', '~') 45 46 #define ISPOWEROFTWO(a) (((a) & ((a) - 1)) == 0) 47 48 /* NOTE: GLFW does not sequentially number keys so switch statement will never be optimized */ 49 #define ENCODE_KEY(action, mod, key) (((action) << 24) | ((mod) << 16) | ((key) & 0xFFFF)) 50 51 #define BACKLOG_SIZE (MB(16)) 52 #define BACKLOG_LINES (8192UL) 53 54 #define ALT_BACKLOG_SIZE (MB(2)) 55 #define ALT_BACKLOG_LINES (1024UL) 56 57 #define I32_MAX INT32_MAX 58 #define I64_MIN INT64_MIN 59 60 typedef float f32; 61 typedef double f64; 62 typedef char c8; 63 typedef int8_t i8; 64 typedef uint8_t u8; 65 typedef int16_t i16; 66 typedef uint16_t u16; 67 typedef int32_t i32; 68 typedef uint32_t u32; 69 typedef uint32_t b32; 70 typedef int64_t i64; 71 typedef uint64_t u64; 72 typedef ptrdiff_t iptr; 73 typedef ptrdiff_t size; 74 typedef size_t usize; 75 76 #include "intrinsics.c" 77 78 #ifdef _DEBUG 79 #define ASSERT(c) do { if (!(c)) debugbreak(); } while(0) 80 #define DEBUG_EXPORT 81 #else 82 #define ASSERT(c) do { (void)(c); } while(0) 83 #define DEBUG_EXPORT static 84 #endif 85 86 typedef struct { void *memory; size size; } MemoryBlock; 87 88 typedef struct { u8 *beg, *end; } Arena; 89 typedef struct { Arena *arena; u8 *old_beg; } TempArena; 90 91 typedef struct { size len; u8 *data; } s8; 92 #define s8(s) (s8){.len = ARRAY_COUNT(s) - 1, .data = (u8 *)s} 93 94 typedef s8 os_mapped_file; 95 96 typedef struct { 97 u8 *buf; 98 u32 cap; 99 u32 widx; 100 b32 errors; 101 } Stream; 102 103 /* NOTE: virtual memory ring buffer */ 104 typedef struct { 105 size cap; 106 size filled; 107 size widx; 108 u8 *buf; 109 } RingBuf; 110 111 typedef union { 112 struct { i32 x, y; }; 113 struct { i32 w, h; }; 114 i32 E[2]; 115 } iv2; 116 117 typedef union { 118 struct { f32 x, y; }; 119 struct { f32 w, h; }; 120 f32 E[2]; 121 } v2; 122 123 typedef struct { iv2 start, end; } Range; 124 #define INVALID_RANGE_END (iv2){.x = -1, .y = -1} 125 126 #define INVALID_FILE (-1) 127 enum file_attribute { 128 FA_READ = 1 << 0, 129 FA_WRITE = 1 << 1, 130 FA_APPEND = 1 << 2, 131 }; 132 133 /* NOTE: for now we will do the callback route but this will change if we do multithreading */ 134 #define PLATFORM_FILE_WATCH_CALLBACK_FN(name) void name(u8 *path, void *user_ctx) 135 typedef PLATFORM_FILE_WATCH_CALLBACK_FN(platform_file_watch_callback_fn); 136 137 #define PLATFORM_ADD_FILE_WATCH_FN(name) void name(u8 *path, platform_file_watch_callback_fn *fn, \ 138 void *user_ctx) 139 typedef PLATFORM_ADD_FILE_WATCH_FN(platform_add_file_watch_fn); 140 141 #define PLATFORM_ALLOCATE_RING_BUFFER_FN(name) void name(RingBuf *rb, size capacity) 142 typedef PLATFORM_ALLOCATE_RING_BUFFER_FN(platform_allocate_ring_buffer_fn); 143 144 #define PLATFORM_CLIPBOARD_FN(name) b32 name(Stream *buffer, u32 clipboard) 145 typedef PLATFORM_CLIPBOARD_FN(platform_clipboard_fn); 146 147 #define PLATFORM_READ_FILE_FN(name) s8 name(u8 *path, Arena *a) 148 typedef PLATFORM_READ_FILE_FN(platform_read_file_fn); 149 150 /* TODO: this should possibly just take a stream buffer */ 151 #define PLATFORM_READ_FN(name) size name(iptr file, s8 buffer) 152 typedef PLATFORM_READ_FN(platform_read_fn); 153 154 #define PLATFORM_SET_TERMINAL_SIZE_FN(name) void name(iptr child, i32 rows, i32 columns, \ 155 i32 window_width, i32 window_height) 156 typedef PLATFORM_SET_TERMINAL_SIZE_FN(platform_set_terminal_size_fn); 157 158 #define PLATFORM_WINDOW_TITLE_FN(name) void name(Stream *buffer) 159 typedef PLATFORM_WINDOW_TITLE_FN(platform_window_title_fn); 160 161 #define PLATFORM_WRITE_FN(name) b32 name(iptr file, s8 raw) 162 typedef PLATFORM_WRITE_FN(platform_write_fn); 163 164 typedef struct { 165 platform_add_file_watch_fn *add_file_watch; 166 platform_allocate_ring_buffer_fn *allocate_ring_buffer; 167 platform_clipboard_fn *get_clipboard; 168 platform_clipboard_fn *set_clipboard; 169 platform_read_file_fn *read_file; 170 platform_read_fn *read; 171 platform_set_terminal_size_fn *set_terminal_size; 172 platform_window_title_fn *get_window_title; 173 platform_window_title_fn *set_window_title; 174 platform_write_fn *write; 175 176 u8 path_separator; 177 } PlatformAPI; 178 179 /* NOTE: CLIPBOARD_1 need not be supported on all platforms */ 180 enum { 181 CLIPBOARD_0, 182 CLIPBOARD_1, 183 }; 184 185 /* TODO: for now these are just based on the GLFW keycodes directly. It might 186 * be better for the platform to define these values themselves */ 187 #define ACT_RELEASE 0 188 #define ACT_PRESS 1 189 #define ACT_REPEAT 2 190 191 #define KEY_SPACE 32 192 #define KEY_APOSTROPHE 39 /* ' */ 193 #define KEY_COMMA 44 /* , */ 194 #define KEY_MINUS 45 /* - */ 195 #define KEY_PERIOD 46 /* . */ 196 #define KEY_SLASH 47 /* / */ 197 #define KEY_0 48 198 #define KEY_1 49 199 #define KEY_2 50 200 #define KEY_3 51 201 #define KEY_4 52 202 #define KEY_5 53 203 #define KEY_6 54 204 #define KEY_7 55 205 #define KEY_8 56 206 #define KEY_9 57 207 #define KEY_SEMICOLON 59 /* ; */ 208 #define KEY_EQUAL 61 /* = */ 209 #define KEY_A 65 210 #define KEY_B 66 211 #define KEY_C 67 212 #define KEY_D 68 213 #define KEY_E 69 214 #define KEY_F 70 215 #define KEY_G 71 216 #define KEY_H 72 217 #define KEY_I 73 218 #define KEY_J 74 219 #define KEY_K 75 220 #define KEY_L 76 221 #define KEY_M 77 222 #define KEY_N 78 223 #define KEY_O 79 224 #define KEY_P 80 225 #define KEY_Q 81 226 #define KEY_R 82 227 #define KEY_S 83 228 #define KEY_T 84 229 #define KEY_U 85 230 #define KEY_V 86 231 #define KEY_W 87 232 #define KEY_X 88 233 #define KEY_Y 89 234 #define KEY_Z 90 235 #define KEY_LEFT_BRACKET 91 /* [ */ 236 #define KEY_BACKSLASH 92 /* \ */ 237 #define KEY_RIGHT_BRACKET 93 /* ] */ 238 #define KEY_GRAVE_ACCENT 96 /* ` */ 239 #define KEY_WORLD_1 161 /* non-US #1 */ 240 #define KEY_WORLD_2 162 /* non-US #2 */ 241 242 /* Function keys */ 243 #define KEY_ESCAPE 256 244 #define KEY_ENTER 257 245 #define KEY_TAB 258 246 #define KEY_BACKSPACE 259 247 #define KEY_INSERT 260 248 #define KEY_DELETE 261 249 #define KEY_RIGHT 262 250 #define KEY_LEFT 263 251 #define KEY_DOWN 264 252 #define KEY_UP 265 253 #define KEY_PAGE_UP 266 254 #define KEY_PAGE_DOWN 267 255 #define KEY_HOME 268 256 #define KEY_END 269 257 #define KEY_CAPS_LOCK 280 258 #define KEY_SCROLL_LOCK 281 259 #define KEY_NUM_LOCK 282 260 #define KEY_PRINT_SCREEN 283 261 #define KEY_PAUSE 284 262 #define KEY_F1 290 263 #define KEY_F2 291 264 #define KEY_F3 292 265 #define KEY_F4 293 266 #define KEY_F5 294 267 #define KEY_F6 295 268 #define KEY_F7 296 269 #define KEY_F8 297 270 #define KEY_F9 298 271 #define KEY_F10 299 272 #define KEY_F11 300 273 #define KEY_F12 301 274 #define KEY_F13 302 275 #define KEY_F14 303 276 #define KEY_F15 304 277 #define KEY_F16 305 278 #define KEY_F17 306 279 #define KEY_F18 307 280 #define KEY_F19 308 281 #define KEY_F20 309 282 #define KEY_F21 310 283 #define KEY_F22 311 284 #define KEY_F23 312 285 #define KEY_F24 313 286 #define KEY_F25 314 287 #define KEY_KP_0 320 288 #define KEY_KP_1 321 289 #define KEY_KP_2 322 290 #define KEY_KP_3 323 291 #define KEY_KP_4 324 292 #define KEY_KP_5 325 293 #define KEY_KP_6 326 294 #define KEY_KP_7 327 295 #define KEY_KP_8 328 296 #define KEY_KP_9 329 297 #define KEY_KP_DECIMAL 330 298 #define KEY_KP_DIVIDE 331 299 #define KEY_KP_MULTIPLY 332 300 #define KEY_KP_SUBTRACT 333 301 #define KEY_KP_ADD 334 302 #define KEY_KP_ENTER 335 303 #define KEY_KP_EQUAL 336 304 305 enum input_keys { 306 MOUSE_LEFT, 307 MOUSE_RIGHT, 308 MOUSE_MIDDLE, 309 MOUSE_EXTENDED_0, 310 MOUSE_EXTENDED_1, 311 312 KEY_LEFT_SHIFT, 313 KEY_LEFT_CONTROL, 314 KEY_LEFT_ALT, 315 KEY_LEFT_SUPER, 316 KEY_RIGHT_SHIFT, 317 KEY_RIGHT_CONTROL, 318 KEY_RIGHT_ALT, 319 KEY_RIGHT_SUPER, 320 KEY_MENU, 321 322 INPUT_KEY_COUNT, 323 }; 324 325 enum modifiers { 326 MOD_SHIFT = (1 << 0), 327 MOD_CONTROL = (1 << 1), 328 MOD_ALT = (1 << 2), 329 MOD_SUPER = (1 << 3), 330 331 MOD_MASK = (MOD_SHIFT|MOD_CONTROL|MOD_ALT|MOD_SUPER), 332 }; 333 334 typedef struct { 335 /* TODO: is this even supported or does GLFW only call you once per poll? */ 336 u16 transitions; 337 u16 ended_down; 338 } ButtonState; 339 340 typedef struct TerminalInput { 341 ButtonState keys[INPUT_KEY_COUNT]; 342 343 iv2 window_size; 344 345 b32 data_available; 346 b32 executable_reloaded; 347 b32 window_refreshed; 348 b32 window_focused; 349 b32 pending_updates; 350 351 u32 modifiers; 352 353 v2 mouse; 354 v2 last_mouse; 355 v2 mouse_scroll; 356 357 /* TODO: do we want the 32bit codepoints instead? */ 358 s8 character_input; 359 360 f32 dt; 361 } TerminalInput; 362 363 typedef struct TerminalMemory { 364 u64 memory_size; 365 void *memory; 366 367 u64 debug_memory_size; 368 void *debug_memory; 369 370 PlatformAPI platform_api; 371 } TerminalMemory; 372 373 /************************************************************/ 374 /* NOTE: functions provided by the terminal to the platform */ 375 /************************************************************/ 376 #define VTGL_INITIALIZE_FN(name) iv2 name(TerminalMemory *memory, iptr child, iv2 requested_cells, iv2 monitor_size) 377 typedef VTGL_INITIALIZE_FN(vtgl_initialize_fn); 378 379 #define VTGL_FRAME_STEP_FN(name) b32 name(TerminalMemory *memory, TerminalInput *input) 380 typedef VTGL_FRAME_STEP_FN(vtgl_frame_step_fn); 381 382 #define VTGL_RENDER_FRAME_FN(name) void name(TerminalMemory *memory, TerminalInput *input, Arena arena) 383 typedef VTGL_RENDER_FRAME_FN(vtgl_render_frame_fn); 384 385 #define VTGL_ACTIVE_SELECTION_FN(name) Range name(TerminalMemory *memory, Stream *out) 386 typedef VTGL_ACTIVE_SELECTION_FN(vtgl_active_selection_fn); 387 388 #define VTGL_HANDLE_KEYS_FN(name) void name(TerminalMemory *memory, TerminalInput *input, \ 389 i32 key, i32 action, u32 modifiers) 390 typedef VTGL_HANDLE_KEYS_FN(vtgl_handle_keys_fn); 391 392 #include "util.h" 393 #include "util.c" 394 395 #include "debug.h" 396 397 #ifdef __ARM_ARCH_ISA_A64 398 #include "platform_linux_aarch64.c" 399 #elif defined(__linux__) && (defined(__x86_64__) || defined(_M_X64)) 400 #include "platform_linux_amd64.c" 401 #else 402 #error Unsupported Platform! 403 #endif 404 405 #endif /*_VTGL_H_ */