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