mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-14 06:13:45 +00:00
push orca target and old bindings
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
//+build js, wasi, freestanding, essence
|
||||
//+build js, wasi, freestanding, essence, orca
|
||||
//+private
|
||||
package runtime
|
||||
|
||||
|
||||
14
base/runtime/os_specific_orca.odin
Normal file
14
base/runtime/os_specific_orca.odin
Normal file
@@ -0,0 +1,14 @@
|
||||
//+build orca
|
||||
//+private
|
||||
package runtime
|
||||
|
||||
// TODO
|
||||
// foreign import
|
||||
// fd_write :: proc "contextless" ()
|
||||
import "core:sys/wasm/wasi"
|
||||
|
||||
_stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||
data := (wasi.ciovec_t)(data)
|
||||
n, err := wasi.fd_write(1, {data})
|
||||
return int(n), _OS_Errno(err)
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
//+private
|
||||
package runtime
|
||||
|
||||
// TODO reimplement fd_write
|
||||
import "core:sys/wasm/wasi"
|
||||
|
||||
_stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||
|
||||
@@ -25,6 +25,17 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
||||
RtlMoveMemory(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
} else when ODIN_OS == .Orca {
|
||||
memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
|
||||
if ptr != nil && len != 0 {
|
||||
b := byte(val)
|
||||
p := ([^]byte)(ptr)
|
||||
for i := 0; i < len; i += 1 {
|
||||
p[i] = b
|
||||
}
|
||||
}
|
||||
return ptr
|
||||
}
|
||||
} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) {
|
||||
@(link_name="memset", linkage="strong", require)
|
||||
memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
|
||||
|
||||
109
core/os/os_orca.odin
Normal file
109
core/os/os_orca.odin
Normal file
@@ -0,0 +1,109 @@
|
||||
package os
|
||||
|
||||
import "core:sys/wasm/wasi"
|
||||
import "base:runtime"
|
||||
|
||||
Handle :: distinct i32
|
||||
Errno :: distinct i32
|
||||
|
||||
ERROR_NONE :: Errno(wasi.errno_t.SUCCESS)
|
||||
|
||||
O_RDONLY :: 0x00000
|
||||
O_WRONLY :: 0x00001
|
||||
O_RDWR :: 0x00002
|
||||
O_CREATE :: 0x00040
|
||||
O_EXCL :: 0x00080
|
||||
O_NOCTTY :: 0x00100
|
||||
O_TRUNC :: 0x00200
|
||||
O_NONBLOCK :: 0x00800
|
||||
O_APPEND :: 0x00400
|
||||
O_SYNC :: 0x01000
|
||||
O_ASYNC :: 0x02000
|
||||
O_CLOEXEC :: 0x80000
|
||||
|
||||
stdin: Handle = 0
|
||||
stdout: Handle = 1
|
||||
stderr: Handle = 2
|
||||
current_dir: Handle = 3
|
||||
|
||||
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
iovs := wasi.ciovec_t(data)
|
||||
n, err := wasi.fd_write(wasi.fd_t(fd), {iovs})
|
||||
return int(n), Errno(err)
|
||||
}
|
||||
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||
iovs := wasi.iovec_t(data)
|
||||
n, err := wasi.fd_read(wasi.fd_t(fd), {iovs})
|
||||
return int(n), Errno(err)
|
||||
}
|
||||
write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
||||
iovs := wasi.ciovec_t(data)
|
||||
n, err := wasi.fd_pwrite(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
|
||||
return int(n), Errno(err)
|
||||
}
|
||||
read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
||||
iovs := wasi.iovec_t(data)
|
||||
n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
|
||||
return int(n), Errno(err)
|
||||
}
|
||||
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
|
||||
oflags: wasi.oflags_t
|
||||
if mode & O_CREATE == O_CREATE {
|
||||
oflags += {.CREATE}
|
||||
}
|
||||
if mode & O_EXCL == O_EXCL {
|
||||
oflags += {.EXCL}
|
||||
}
|
||||
if mode & O_TRUNC == O_TRUNC {
|
||||
oflags += {.TRUNC}
|
||||
}
|
||||
|
||||
rights: wasi.rights_t = {.FD_SEEK, .FD_FILESTAT_GET}
|
||||
switch mode & (O_RDONLY|O_WRONLY|O_RDWR) {
|
||||
case O_RDONLY: rights += {.FD_READ}
|
||||
case O_WRONLY: rights += {.FD_WRITE}
|
||||
case O_RDWR: rights += {.FD_READ, .FD_WRITE}
|
||||
}
|
||||
|
||||
fdflags: wasi.fdflags_t
|
||||
if mode & O_APPEND == O_APPEND {
|
||||
fdflags += {.APPEND}
|
||||
}
|
||||
if mode & O_NONBLOCK == O_NONBLOCK {
|
||||
fdflags += {.NONBLOCK}
|
||||
}
|
||||
if mode & O_SYNC == O_SYNC {
|
||||
fdflags += {.SYNC}
|
||||
}
|
||||
fd, err := wasi.path_open(wasi.fd_t(current_dir),{.SYMLINK_FOLLOW},path,oflags,rights,{},fdflags)
|
||||
return Handle(fd), Errno(err)
|
||||
}
|
||||
close :: proc(fd: Handle) -> Errno {
|
||||
err := wasi.fd_close(wasi.fd_t(fd))
|
||||
return Errno(err)
|
||||
}
|
||||
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
||||
n, err := wasi.fd_seek(wasi.fd_t(fd), wasi.filedelta_t(offset), wasi.whence_t(whence))
|
||||
return i64(n), Errno(err)
|
||||
}
|
||||
current_thread_id :: proc "contextless" () -> int {
|
||||
return 0
|
||||
}
|
||||
@(private)
|
||||
_processor_core_count :: proc() -> int {
|
||||
return 1
|
||||
}
|
||||
|
||||
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
||||
stat, err := wasi.fd_filestat_get(wasi.fd_t(fd))
|
||||
if err != nil {
|
||||
return 0, Errno(err)
|
||||
}
|
||||
return i64(stat.size), 0
|
||||
}
|
||||
|
||||
|
||||
exit :: proc "contextless" (code: int) -> ! {
|
||||
runtime._cleanup_runtime_contextless()
|
||||
wasi.proc_exit(wasi.exitcode_t(code))
|
||||
}
|
||||
58
core/sys/orca/algebra.odin
Normal file
58
core/sys/orca/algebra.odin
Normal file
@@ -0,0 +1,58 @@
|
||||
package orca
|
||||
|
||||
import "core:math"
|
||||
|
||||
// TODO use orcas or native?
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
mat2x3_mul_m :: proc(lhs, rhs: mat2x3) -> mat2x3 ---
|
||||
mat2x3_inv :: proc(x: mat2x3) -> mat2x3 ---
|
||||
mat2x3_mul :: proc(m: mat2x3, p: vec2) -> vec2 ---
|
||||
mat2x3_rotate :: proc(radians: f32) -> mat2x3 ---
|
||||
mat2x3_translate :: proc(x, y: f32) -> mat2x3 ---
|
||||
}
|
||||
|
||||
// mat2x3_mul_m :: proc "contextless" (lhs, rhs: mat2x3) -> (res: mat2x3) {
|
||||
// res[0] = lhs[0] * rhs[0] + lhs[1] * rhs[3]
|
||||
// res[1] = lhs[0] * rhs[1] + lhs[1] * rhs[4]
|
||||
// res[2] = lhs[0] * rhs[2] + lhs[1] * rhs[5] + lhs[2]
|
||||
// res[3] = lhs[3] * rhs[0] + lhs[4] * rhs[3]
|
||||
// res[4] = lhs[3] * rhs[1] + lhs[4] * rhs[4]
|
||||
// res[5] = lhs[3] * rhs[2] + lhs[4] * rhs[5] + lhs[5]
|
||||
// return
|
||||
// }
|
||||
|
||||
// mat2x3_inv :: proc "contextless" (x: mat2x3) -> (res: mat2x3) {
|
||||
// res[0] = x[4] / (x[0] * x[4] - x[1] * x[3])
|
||||
// res[1] = x[1] / (x[1] * x[3] - x[0] * x[4])
|
||||
// res[3] = x[3] / (x[1] * x[3] - x[0] * x[4])
|
||||
// res[4] = x[0] / (x[0] * x[4] - x[1] * x[3])
|
||||
// res[2] = -(x[2] * res[0] + x[5] * res[1])
|
||||
// res[5] = -(x[2] * res[3] + x[5] * res[4])
|
||||
// return
|
||||
// }
|
||||
|
||||
// mat2x3_mul :: proc "contextless" (m: mat2x3, p: vec2) -> vec2 {
|
||||
// return {
|
||||
// p.x * m[0] + p.y * m[1] + m[2],
|
||||
// p.x * m[3] + p.y * m[4] + m[5],
|
||||
// }
|
||||
// }
|
||||
|
||||
// mat2x3_rotate :: proc "contextless" (radians: f32) -> mat2x3 {
|
||||
// sinRot := math.sin(radians)
|
||||
// cosRot := math.cos(radians)
|
||||
// rot := mat2x3 {
|
||||
// cosRot, -sinRot, 0,
|
||||
// sinRot, cosRot, 0,
|
||||
// }
|
||||
// return rot
|
||||
// }
|
||||
|
||||
// mat2x3_translate :: proc "contextless" (x, y: f32) -> mat2x3 {
|
||||
// return {
|
||||
// 1, 0, x,
|
||||
// 0, 1, y,
|
||||
// }
|
||||
// }
|
||||
366
core/sys/orca/app.odin
Normal file
366
core/sys/orca/app.odin
Normal file
@@ -0,0 +1,366 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
|
||||
window :: u64
|
||||
|
||||
mouse_cursor :: enum c.int {
|
||||
ARROW,
|
||||
RESIZE_0,
|
||||
RESIZE_90,
|
||||
RESIZE_45,
|
||||
RESIZE_135,
|
||||
TEXT,
|
||||
}
|
||||
|
||||
window_style :: enum u32 {
|
||||
NO_TITLE = 0x01 << 0,
|
||||
FIXED_SIZE = 0x01 << 1,
|
||||
NO_CLOSE = 0x01 << 2,
|
||||
NO_MINIFY = 0x01 << 3,
|
||||
NO_FOCUS = 0x01 << 4,
|
||||
FLOAT = 0x01 << 5,
|
||||
POPUPMENU = 0x01 << 6,
|
||||
NO_BUTTONS = 0x01 << 7
|
||||
}
|
||||
|
||||
event_type :: enum c.int {
|
||||
NONE,
|
||||
KEYBOARD_MODS, //TODO: remove, keep only key?
|
||||
KEYBOARD_KEY,
|
||||
KEYBOARD_CHAR,
|
||||
MOUSE_BUTTON,
|
||||
MOUSE_MOVE,
|
||||
MOUSE_WHEEL,
|
||||
MOUSE_ENTER,
|
||||
MOUSE_LEAVE,
|
||||
CLIPBOARD_PASTE,
|
||||
WINDOW_RESIZE,
|
||||
WINDOW_MOVE,
|
||||
WINDOW_FOCUS,
|
||||
WINDOW_UNFOCUS,
|
||||
WINDOW_HIDE, // rename to minimize?
|
||||
WINDOW_SHOW, // rename to restore?
|
||||
WINDOW_CLOSE,
|
||||
PATHDROP,
|
||||
FRAME,
|
||||
QUIT
|
||||
}
|
||||
|
||||
key_action :: enum c.int {
|
||||
NO_ACTION,
|
||||
PRESS,
|
||||
RELEASE,
|
||||
REPEAT
|
||||
}
|
||||
|
||||
key_code :: enum c.int {
|
||||
KEY_UNKNOWN = '\x00',
|
||||
KEY_SPACE = ' ',
|
||||
KEY_APOSTROPHE = '\'',
|
||||
KEY_COMMA = ',',
|
||||
KEY_MINUS = '-',
|
||||
KEY_PERIOD = '.',
|
||||
KEY_SLASH = '/',
|
||||
KEY_0 = '0',
|
||||
KEY_1 = '1',
|
||||
KEY_2 = '2',
|
||||
KEY_3 = '3',
|
||||
KEY_4 = '4',
|
||||
KEY_5 = '5',
|
||||
KEY_6 = '6',
|
||||
KEY_7 = '7',
|
||||
KEY_8 = '8',
|
||||
KEY_9 = '9',
|
||||
KEY_SEMICOLON = ';',
|
||||
KEY_EQUAL = '=',
|
||||
KEY_LEFT_BRACKET = '[',
|
||||
KEY_BACKSLASH = '\\',
|
||||
KEY_RIGHT_BRACKET = ']',
|
||||
KEY_GRAVE_ACCENT = '`',
|
||||
KEY_A = 'a',
|
||||
KEY_B = 'b',
|
||||
KEY_C = 'c',
|
||||
KEY_D = 'd',
|
||||
KEY_E = 'e',
|
||||
KEY_F = 'f',
|
||||
KEY_G = 'g',
|
||||
KEY_H = 'h',
|
||||
KEY_I = 'i',
|
||||
KEY_J = 'j',
|
||||
KEY_K = 'k',
|
||||
KEY_L = 'l',
|
||||
KEY_M = 'm',
|
||||
KEY_N = 'n',
|
||||
KEY_O = 'o',
|
||||
KEY_P = 'p',
|
||||
KEY_Q = 'q',
|
||||
KEY_R = 'r',
|
||||
KEY_S = 's',
|
||||
KEY_T = 't',
|
||||
KEY_U = 'u',
|
||||
KEY_V = 'v',
|
||||
KEY_W = 'w',
|
||||
KEY_X = 'x',
|
||||
KEY_Y = 'y',
|
||||
KEY_Z = 'z',
|
||||
KEY_WORLD_1 = 161,
|
||||
KEY_WORLD_2 = 162,
|
||||
KEY_ESCAPE = 256,
|
||||
KEY_ENTER = 257,
|
||||
KEY_TAB = 258,
|
||||
KEY_BACKSPACE = 259,
|
||||
KEY_INSERT = 260,
|
||||
KEY_DELETE = 261,
|
||||
KEY_RIGHT = 262,
|
||||
KEY_LEFT = 263,
|
||||
KEY_DOWN = 264,
|
||||
KEY_UP = 265,
|
||||
KEY_PAGE_UP = 266,
|
||||
KEY_PAGE_DOWN = 267,
|
||||
KEY_HOME = 268,
|
||||
KEY_END = 269,
|
||||
KEY_CAPS_LOCK = 280,
|
||||
KEY_SCROLL_LOCK = 281,
|
||||
KEY_NUM_LOCK = 282,
|
||||
KEY_PRINT_SCREEN = 283,
|
||||
KEY_PAUSE = 284,
|
||||
KEY_F1 = 290,
|
||||
KEY_F2 = 291,
|
||||
KEY_F3 = 292,
|
||||
KEY_F4 = 293,
|
||||
KEY_F5 = 294,
|
||||
KEY_F6 = 295,
|
||||
KEY_F7 = 296,
|
||||
KEY_F8 = 297,
|
||||
KEY_F9 = 298,
|
||||
KEY_F10 = 299,
|
||||
KEY_F11 = 300,
|
||||
KEY_F12 = 301,
|
||||
KEY_F13 = 302,
|
||||
KEY_F14 = 303,
|
||||
KEY_F15 = 304,
|
||||
KEY_F16 = 305,
|
||||
KEY_F17 = 306,
|
||||
KEY_F18 = 307,
|
||||
KEY_F19 = 308,
|
||||
KEY_F20 = 309,
|
||||
KEY_F21 = 310,
|
||||
KEY_F22 = 311,
|
||||
KEY_F23 = 312,
|
||||
KEY_F24 = 313,
|
||||
KEY_F25 = 314,
|
||||
KEY_KP_0 = 320,
|
||||
KEY_KP_1 = 321,
|
||||
KEY_KP_2 = 322,
|
||||
KEY_KP_3 = 323,
|
||||
KEY_KP_4 = 324,
|
||||
KEY_KP_5 = 325,
|
||||
KEY_KP_6 = 326,
|
||||
KEY_KP_7 = 327,
|
||||
KEY_KP_8 = 328,
|
||||
KEY_KP_9 = 329,
|
||||
KEY_KP_DECIMAL = 330,
|
||||
KEY_KP_DIVIDE = 331,
|
||||
KEY_KP_MULTIPLY = 332,
|
||||
KEY_KP_SUBTRACT = 333,
|
||||
KEY_KP_ADD = 334,
|
||||
KEY_KP_ENTER = 335,
|
||||
KEY_KP_EQUAL = 336,
|
||||
KEY_LEFT_SHIFT = 340,
|
||||
KEY_LEFT_CONTROL = 341,
|
||||
KEY_LEFT_ALT = 342,
|
||||
KEY_LEFT_SUPER = 343,
|
||||
KEY_RIGHT_SHIFT = 344,
|
||||
KEY_RIGHT_CONTROL = 345,
|
||||
KEY_RIGHT_ALT = 346,
|
||||
KEY_RIGHT_SUPER = 347,
|
||||
KEY_MENU = 348,
|
||||
}
|
||||
|
||||
scan_code :: enum c.int {
|
||||
SCANCODE_UNKNOWN = 0,
|
||||
SCANCODE_SPACE = 32,
|
||||
SCANCODE_APOSTROPHE = 39,
|
||||
SCANCODE_COMMA = 44,
|
||||
SCANCODE_MINUS = 45,
|
||||
SCANCODE_PERIOD = 46,
|
||||
SCANCODE_SLASH = 47,
|
||||
SCANCODE_0 = 48,
|
||||
SCANCODE_1 = 49,
|
||||
SCANCODE_2 = 50,
|
||||
SCANCODE_3 = 51,
|
||||
SCANCODE_4 = 52,
|
||||
SCANCODE_5 = 53,
|
||||
SCANCODE_6 = 54,
|
||||
SCANCODE_7 = 55,
|
||||
SCANCODE_8 = 56,
|
||||
SCANCODE_9 = 57,
|
||||
SCANCODE_SEMICOLON = 59,
|
||||
SCANCODE_EQUAL = 61,
|
||||
SCANCODE_LEFT_BRACKET = 91,
|
||||
SCANCODE_BACKSLASH = 92,
|
||||
SCANCODE_RIGHT_BRACKET = 93,
|
||||
SCANCODE_GRAVE_ACCENT = 96,
|
||||
SCANCODE_A = 97,
|
||||
SCANCODE_B = 98,
|
||||
SCANCODE_C = 99,
|
||||
SCANCODE_D = 100,
|
||||
SCANCODE_E = 101,
|
||||
SCANCODE_F = 102,
|
||||
SCANCODE_G = 103,
|
||||
SCANCODE_H = 104,
|
||||
SCANCODE_I = 105,
|
||||
SCANCODE_J = 106,
|
||||
SCANCODE_K = 107,
|
||||
SCANCODE_L = 108,
|
||||
SCANCODE_M = 109,
|
||||
SCANCODE_N = 110,
|
||||
SCANCODE_O = 111,
|
||||
SCANCODE_P = 112,
|
||||
SCANCODE_Q = 113,
|
||||
SCANCODE_R = 114,
|
||||
SCANCODE_S = 115,
|
||||
SCANCODE_T = 116,
|
||||
SCANCODE_U = 117,
|
||||
SCANCODE_V = 118,
|
||||
SCANCODE_W = 119,
|
||||
SCANCODE_X = 120,
|
||||
SCANCODE_Y = 121,
|
||||
SCANCODE_Z = 122,
|
||||
SCANCODE_WORLD_1 = 161,
|
||||
SCANCODE_WORLD_2 = 162,
|
||||
SCANCODE_ESCAPE = 256,
|
||||
SCANCODE_ENTER = 257,
|
||||
SCANCODE_TAB = 258,
|
||||
SCANCODE_BACKSPACE = 259,
|
||||
SCANCODE_INSERT = 260,
|
||||
SCANCODE_DELETE = 261,
|
||||
SCANCODE_RIGHT = 262,
|
||||
SCANCODE_LEFT = 263,
|
||||
SCANCODE_DOWN = 264,
|
||||
SCANCODE_UP = 265,
|
||||
SCANCODE_PAGE_UP = 266,
|
||||
SCANCODE_PAGE_DOWN = 267,
|
||||
SCANCODE_HOME = 268,
|
||||
SCANCODE_END = 269,
|
||||
SCANCODE_CAPS_LOCK = 280,
|
||||
SCANCODE_SCROLL_LOCK = 281,
|
||||
SCANCODE_NUM_LOCK = 282,
|
||||
SCANCODE_PRINT_SCREEN = 283,
|
||||
SCANCODE_PAUSE = 284,
|
||||
SCANCODE_F1 = 290,
|
||||
SCANCODE_F2 = 291,
|
||||
SCANCODE_F3 = 292,
|
||||
SCANCODE_F4 = 293,
|
||||
SCANCODE_F5 = 294,
|
||||
SCANCODE_F6 = 295,
|
||||
SCANCODE_F7 = 296,
|
||||
SCANCODE_F8 = 297,
|
||||
SCANCODE_F9 = 298,
|
||||
SCANCODE_F10 = 299,
|
||||
SCANCODE_F11 = 300,
|
||||
SCANCODE_F12 = 301,
|
||||
SCANCODE_F13 = 302,
|
||||
SCANCODE_F14 = 303,
|
||||
SCANCODE_F15 = 304,
|
||||
SCANCODE_F16 = 305,
|
||||
SCANCODE_F17 = 306,
|
||||
SCANCODE_F18 = 307,
|
||||
SCANCODE_F19 = 308,
|
||||
SCANCODE_F20 = 309,
|
||||
SCANCODE_F21 = 310,
|
||||
SCANCODE_F22 = 311,
|
||||
SCANCODE_F23 = 312,
|
||||
SCANCODE_F24 = 313,
|
||||
SCANCODE_F25 = 314,
|
||||
SCANCODE_KP_0 = 320,
|
||||
SCANCODE_KP_1 = 321,
|
||||
SCANCODE_KP_2 = 322,
|
||||
SCANCODE_KP_3 = 323,
|
||||
SCANCODE_KP_4 = 324,
|
||||
SCANCODE_KP_5 = 325,
|
||||
SCANCODE_KP_6 = 326,
|
||||
SCANCODE_KP_7 = 327,
|
||||
SCANCODE_KP_8 = 328,
|
||||
SCANCODE_KP_9 = 329,
|
||||
SCANCODE_KP_DECIMAL = 330,
|
||||
SCANCODE_KP_DIVIDE = 331,
|
||||
SCANCODE_KP_MULTIPLY = 332,
|
||||
SCANCODE_KP_SUBTRACT = 333,
|
||||
SCANCODE_KP_ADD = 334,
|
||||
SCANCODE_KP_ENTER = 335,
|
||||
SCANCODE_KP_EQUAL = 336,
|
||||
SCANCODE_LEFT_SHIFT = 340,
|
||||
SCANCODE_LEFT_CONTROL = 341,
|
||||
SCANCODE_LEFT_ALT = 342,
|
||||
SCANCODE_LEFT_SUPER = 343,
|
||||
SCANCODE_RIGHT_SHIFT = 344,
|
||||
SCANCODE_RIGHT_CONTROL = 345,
|
||||
SCANCODE_RIGHT_ALT = 346,
|
||||
SCANCODE_RIGHT_SUPER = 347,
|
||||
SCANCODE_MENU = 348,
|
||||
}
|
||||
|
||||
keymod_flags :: enum c.int {
|
||||
NONE = 0x00,
|
||||
ALT = 0x01,
|
||||
SHIFT = 0x02,
|
||||
CTRL = 0x04,
|
||||
CMD = 0x08,
|
||||
MAIN_MODIFIER = 0x10 /* CMD on Mac, CTRL on Win32 */
|
||||
}
|
||||
|
||||
mouse_button :: enum c.int {
|
||||
LEFT = 0x00,
|
||||
RIGHT = 0x01,
|
||||
MIDDLE = 0x02,
|
||||
EXT1 = 0x03,
|
||||
EXT2 = 0x04,
|
||||
}
|
||||
|
||||
// keyboard and mouse buttons input
|
||||
key_event :: struct {
|
||||
action: key_action,
|
||||
scanCode: scan_code,
|
||||
keyCode: key_code,
|
||||
button: mouse_button,
|
||||
mods: keymod_flags,
|
||||
clickCount: u8,
|
||||
}
|
||||
|
||||
// character input
|
||||
char_event :: struct {
|
||||
codepoint: utf32,
|
||||
sequence: [8]c.char,
|
||||
seqLen: u8,
|
||||
}
|
||||
|
||||
// mouse move/scroll
|
||||
mouse_event :: struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
deltaX: f32,
|
||||
deltaY: f32,
|
||||
mods: keymod_flags,
|
||||
}
|
||||
|
||||
// window resize / move
|
||||
move_event :: struct {
|
||||
frame: rect,
|
||||
content: rect,
|
||||
}
|
||||
|
||||
event :: struct {
|
||||
//TODO clipboard and path drop
|
||||
window: window,
|
||||
type: event_type,
|
||||
|
||||
_: struct #raw_union {
|
||||
key: key_event,
|
||||
character: char_event,
|
||||
mouse: mouse_event,
|
||||
move: move_event,
|
||||
paths: str8_list,
|
||||
}
|
||||
}
|
||||
246
core/sys/orca/graphics.odin
Normal file
246
core/sys/orca/graphics.odin
Normal file
@@ -0,0 +1,246 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
|
||||
// types
|
||||
color :: [4]f32
|
||||
utf32 :: u32
|
||||
|
||||
// handles
|
||||
surface :: u64
|
||||
font :: u64
|
||||
image :: u64
|
||||
canvas :: u64
|
||||
|
||||
joint_type :: enum c.int {
|
||||
MITER,
|
||||
BEVEL,
|
||||
NONE,
|
||||
}
|
||||
|
||||
cap_type :: enum c.int {
|
||||
NONE,
|
||||
SQUARE,
|
||||
}
|
||||
|
||||
font_metrics :: struct {
|
||||
ascent: f32, // the extent above the baseline (by convention a positive value extends above the baseline)
|
||||
descent: f32, // the extent below the baseline (by convention, positive value extends below the baseline)
|
||||
lineGap: f32, // spacing between one row's descent and the next row's ascent
|
||||
xHeight: f32, // height of the lower case letter 'x'
|
||||
capHeight: f32, // height of the upper case letter 'M'
|
||||
width: f32, // maximum width of the font
|
||||
}
|
||||
|
||||
glyph_metrics :: struct {
|
||||
ink: rect,
|
||||
advance: vec2,
|
||||
}
|
||||
|
||||
text_metrics :: struct {
|
||||
ink: rect,
|
||||
logical: rect,
|
||||
advance: vec2,
|
||||
}
|
||||
|
||||
rect_atlas :: struct {
|
||||
arena: ^arena,
|
||||
size: vec2i,
|
||||
pos: vec2i,
|
||||
lineHeight: u32,
|
||||
}
|
||||
|
||||
image_region :: struct {
|
||||
image: image,
|
||||
rect: rect,
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// graphics surface
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
surface_nil :: proc() -> surface ---
|
||||
surface_is_nil :: proc() -> c.bool ---
|
||||
surface_canvas :: proc() -> surface ---
|
||||
surface_gles :: proc() -> surface ---
|
||||
surface_destroy :: proc(surface: surface) ---
|
||||
|
||||
surface_select :: proc(surface: surface) ---
|
||||
surface_deselect :: proc() ---
|
||||
surface_present :: proc(surface: surface) ---
|
||||
|
||||
surface_get_size :: proc(surface: surface) -> vec2 ---
|
||||
surface_contents_scaling :: proc(surface: surface) -> vec2 ---
|
||||
surface_bring_to_front :: proc(surface: surface) ---
|
||||
surface_send_to_back :: proc(surface: surface) ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// 2D canvas command buffer
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
canvas_nil :: proc() -> canvas ---
|
||||
canvas_is_nil :: proc(canvas: canvas) -> c.bool ---
|
||||
canvas_create :: proc() -> canvas ---
|
||||
canvas_destroy :: proc(canvas: canvas) ---
|
||||
canvas_set_current :: proc(_canvas: canvas) -> canvas ---
|
||||
canvas_select :: proc(_canvas: canvas) -> canvas ---
|
||||
render :: proc(canvas: canvas) ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// transform and clipping
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
matrix_push :: proc(mat: mat2x3) ---
|
||||
matrix_multiply_push :: proc(mat: mat2x3) ---
|
||||
matrix_pop :: proc() ---
|
||||
matrix_top :: proc() -> mat2x3 ---
|
||||
|
||||
clip_push :: proc(x, y, w, h: f32) ---
|
||||
clip_pop :: proc() ---
|
||||
clip_top :: proc() -> rect ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// graphics attributes setting/getting
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
set_color :: proc(color: color) ---
|
||||
set_color_rgba :: proc(r, g, b, a: f32) ---
|
||||
set_width :: proc(width: f32) ---
|
||||
set_tolerance :: proc(tolerance: f32) ---
|
||||
set_joint :: proc(joint: joint_type) ---
|
||||
set_max_joint_excursion :: proc(maxJointExcursion: f32) ---
|
||||
set_cap :: proc(cap: cap_type) ---
|
||||
set_font :: proc(font: font) ---
|
||||
set_font_size :: proc(size: f32) ---
|
||||
set_text_flip :: proc(flip: c.bool) ---
|
||||
set_image :: proc(image: image) ---
|
||||
set_image_source_region :: proc(region: rect) ---
|
||||
|
||||
get_color :: proc() -> color ---
|
||||
get_width :: proc() -> f32 ---
|
||||
get_tolerance :: proc() -> f32 ---
|
||||
get_joint :: proc() -> joint_type ---
|
||||
get_max_joint_excursion :: proc() -> f32 ---
|
||||
get_cap :: proc() -> cap_type ---
|
||||
get_font :: proc() -> font ---
|
||||
get_font_size :: proc() -> f32 ---
|
||||
get_text_flip :: proc() -> bool ---
|
||||
get_image :: proc() -> image ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// path construction
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
get_position :: proc() -> vec2 ---
|
||||
move_to :: proc(x, y: f32) ---
|
||||
line_to :: proc(x, y: f32) ---
|
||||
quadratic_to :: proc(x1, y1, x2, y2: f32) ---
|
||||
cubic_to :: proc(x1, y1, x2, y2, x3, y3: f32) ---
|
||||
close_path :: proc() ---
|
||||
|
||||
glyph_outlines :: proc(glyphIndices: str32) -> rect ---
|
||||
codepoints_outlines :: proc(str: str32) ---
|
||||
text_outlines :: proc(str: str8) ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// clear/fill/stroke
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
clear :: proc() ---
|
||||
fill :: proc() ---
|
||||
stroke :: proc() ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// shapes helpers
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
rectangle_fill :: proc(x, y, w, h: f32) ---
|
||||
rectangle_stroke :: proc(x, y, w, h: f32) ---
|
||||
rounded_rectangle_fill :: proc(x, y, w, h, r: f32) ---
|
||||
rounded_rectangle_stroke :: proc(x, y, w, h, r: f32) ---
|
||||
ellipse_fill :: proc(x, y, rx, ry: f32) ---
|
||||
ellipse_stroke :: proc(x, y, rx, ry: f32) ---
|
||||
circle_fill :: proc(x, y, r: f32) ---
|
||||
circle_stroke :: proc(x, y, r: f32) ---
|
||||
arc :: proc(x, y, r, arcAngle, startAngle: f32) ---
|
||||
image_draw :: proc(image: image, rect: rect) ---
|
||||
image_draw_region :: proc(image: image, srcRegion, dstRegion: rect) ---
|
||||
|
||||
text_fill :: proc(x, y: f32, text: str8) ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// fonts
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
font_nil :: proc() -> font ---
|
||||
font_is_nil :: proc(font: font) -> c.bool ---
|
||||
|
||||
font_create_from_memory :: proc(mem: str8, rangeCount: u32, ranges: [^]unicode_range) -> font ---
|
||||
font_create_from_file :: proc(file: file, rangeCount: u32, ranges: [^]unicode_range) -> font ---
|
||||
font_create_from_path :: proc(path: str8, rangeCount: u32, ranges: [^]unicode_range) -> font ---
|
||||
|
||||
font_destroy :: proc(font: font) ---
|
||||
|
||||
font_get_glyph_indices :: proc(font: font, codePoints: str32, backing: str32) -> str32 ---
|
||||
font_push_glyph_indices :: proc(arena: ^arena, font: font, codePoints: str32) -> str32 ---
|
||||
font_get_glyph_index :: proc(font: font, codePoint: utf32) -> u32 ---
|
||||
|
||||
font_get_metrics :: proc(font: font, emSize: f32) -> font_metrics ---
|
||||
font_get_metrics_unscaled :: proc(font: font) -> font_metrics ---
|
||||
font_get_scale_for_em_pixels :: proc(font: font, emSize: f32) -> f32 ---
|
||||
|
||||
font_text_metrics_utf32 :: proc(font: font, fontSize: f32, codepoints: str32) -> text_metrics ---
|
||||
font_text_metrics :: proc(font: font, fontSize: f32, text: str8) -> text_metrics ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// images
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
image_nil :: proc() -> image ---
|
||||
image_is_nil :: proc(a: image) -> c.bool ---
|
||||
|
||||
image_create :: proc(surface: surface, width, height: u32) -> image ---
|
||||
image_create_from_rgba8 :: proc(surface: surface, width, height: u32, pixels: [^]u8) -> image ---
|
||||
image_create_from_memory :: proc(surface: surface, mem: str8, flip: c.bool) -> image ---
|
||||
image_create_from_file :: proc(surface: surface, file: file, flip: c.bool) -> image ---
|
||||
image_create_from_path :: proc(surface: surface, path: str8, flip: c.bool) -> image ---
|
||||
|
||||
image_destroy :: proc(image: image) ---
|
||||
|
||||
image_upload_region_rgba8 :: proc(image: image, region: rect, pixels: [^]u8) ---
|
||||
image_size :: proc(image: image) -> vec2 ---
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// image atlas
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
rect_atlas_create :: proc(arena: ^arena, width, height: i32) -> ^rect_atlas ---
|
||||
rect_atlas_alloc :: proc(atlas: ^rect_atlas, width, height: i32) -> rect ---
|
||||
rect_atlas_recycle :: proc(atlas: ^rect_atlas, rect: rect) ---
|
||||
|
||||
image_atlas_allfrom_rgba8 :: proc(atlas: ^rect_atlas, backingImage: image, width, height: u32, pixels: [^]u8) -> image_region ---
|
||||
image_atlas_allfrom_memory :: proc(atlas: ^rect_atlas, backingImage: image, mem: str8, flip: c.bool) -> image_region ---
|
||||
image_atlas_allfrom_file :: proc(atlas: ^rect_atlas, backingImage: image, file: file, flip: c.bool) -> image_region ---
|
||||
image_atlas_allfrom_path :: proc(atlas: ^rect_atlas, backingImage: image, path: str8, flip: c.bool) -> image_region ---
|
||||
|
||||
image_atlas_recycle :: proc(atlas: ^rect_atlas, imageRgn: image_region) ---
|
||||
}
|
||||
59
core/sys/orca/input_state.odin
Normal file
59
core/sys/orca/input_state.odin
Normal file
@@ -0,0 +1,59 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
|
||||
key_state :: struct {
|
||||
lastUpdate: u64,
|
||||
transitionCount: u32,
|
||||
repeatCount: u32,
|
||||
down: c.bool,
|
||||
sysClicked: c.bool,
|
||||
sysDoubleClicked: c.bool,
|
||||
sysTripleClicked: c.bool,
|
||||
}
|
||||
|
||||
keyboard_state :: struct {
|
||||
keys: [len(key_code)]key_state,
|
||||
mods: keymod_flags,
|
||||
}
|
||||
|
||||
mouse_state :: struct {
|
||||
lastUpdate: u64,
|
||||
posValid: c.bool,
|
||||
pos: vec2,
|
||||
delta: vec2,
|
||||
wheel: vec2,
|
||||
|
||||
_: struct #raw_union {
|
||||
buttons: [len(mouse_button)]key_state,
|
||||
|
||||
_: struct {
|
||||
left: key_state,
|
||||
right: key_state,
|
||||
middle: key_state,
|
||||
ext1: key_state,
|
||||
ext2: key_state,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_TEXT_BACKING_SIZE :: 64
|
||||
|
||||
text_state :: struct {
|
||||
lastUpdate: u64,
|
||||
backing: [INPUT_TEXT_BACKING_SIZE]utf32,
|
||||
codePoints: str32,
|
||||
}
|
||||
|
||||
clipboard_state :: struct {
|
||||
lastUpdate: u64,
|
||||
pastedText: str8,
|
||||
}
|
||||
|
||||
input_state :: struct {
|
||||
frameCounter: u64,
|
||||
keyboard: keyboard_state,
|
||||
mouse: mouse_state,
|
||||
text: text_state,
|
||||
clipboard: clipboard_state,
|
||||
}
|
||||
159
core/sys/orca/io.odin
Normal file
159
core/sys/orca/io.odin
Normal file
@@ -0,0 +1,159 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
|
||||
file :: distinct u64 // handle
|
||||
|
||||
file_access :: enum u16 {
|
||||
NONE = 0,
|
||||
READ = 1 << 1,
|
||||
WRITE = 1 << 2,
|
||||
}
|
||||
|
||||
file_open_flags :: enum u16 {
|
||||
NONE = 0,
|
||||
APPEND = 1 << 1,
|
||||
TRUNCATE = 1 << 2,
|
||||
CREATE = 1 << 3,
|
||||
|
||||
SYMLINK = 1 << 4,
|
||||
NO_FOLLOW = 1 << 5,
|
||||
RESTRICT = 1 << 6,
|
||||
}
|
||||
|
||||
file_whence :: enum c.int {
|
||||
SEEK_SET,
|
||||
SEEK_END,
|
||||
SEEK_CURRENT,
|
||||
}
|
||||
|
||||
io_error :: enum i32 {
|
||||
OK = 0,
|
||||
ERR_UNKNOWN,
|
||||
ERR_OP, // unsupported operation
|
||||
ERR_HANDLE, // invalid handle
|
||||
ERR_PREV, // previously had a fatal error (last error stored on handle)
|
||||
ERR_ARG, // invalid argument or argument combination
|
||||
ERR_PERM, // access denied
|
||||
ERR_SPACE, // no space left
|
||||
ERR_NO_ENTRY, // file or directory does not exist
|
||||
ERR_EXISTS, // file already exists
|
||||
ERR_NOT_DIR, // path element is not a directory
|
||||
ERR_DIR, // attempted to write directory
|
||||
ERR_MAX_FILES, // max open files reached
|
||||
ERR_MAX_LINKS, // too many symbolic links in path
|
||||
ERR_PATH_LENGTH, // path too long
|
||||
ERR_FILE_SIZE, // file too big
|
||||
ERR_OVERFLOW, // offset too big
|
||||
ERR_NOT_READY, // no data ready to be read/written
|
||||
ERR_MEM, // failed to allocate memory
|
||||
ERR_INTERRUPT, // operation interrupted by a signal
|
||||
ERR_PHYSICAL, // physical IO error
|
||||
ERR_NO_DEVICE, // device not found
|
||||
ERR_WALKOUT, // attempted to walk out of root directory
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// File System wrapper API
|
||||
//----------------------------------------------------------------
|
||||
file_type :: enum c.int {
|
||||
UNKNOWN,
|
||||
REGULAR,
|
||||
DIRECTORY,
|
||||
SYMLINK,
|
||||
BLOCK,
|
||||
CHARACTER,
|
||||
FIFO,
|
||||
SOCKET,
|
||||
}
|
||||
|
||||
file_perm :: enum u16 {
|
||||
OTHER_EXEC = 1 << 0,
|
||||
OTHER_WRITE = 1 << 1,
|
||||
OTHER_READ = 1 << 2,
|
||||
|
||||
GROUP_EXEC = 1 << 3,
|
||||
GROUP_WRITE = 1 << 4,
|
||||
GROUP_READ = 1 << 5,
|
||||
|
||||
OWNER_EXEC = 1 << 6,
|
||||
OWNER_WRITE = 1 << 7,
|
||||
OWNER_READ = 1 << 8,
|
||||
|
||||
STICKY_BIT = 1 << 9,
|
||||
SET_GID = 1 << 10,
|
||||
SET_UID = 1 << 11,
|
||||
}
|
||||
|
||||
datestamp :: struct {
|
||||
seconds: i64, // seconds relative to NTP epoch.
|
||||
fraction: u64, // fraction of seconds elapsed since the time specified by seconds.
|
||||
}
|
||||
|
||||
file_status :: struct {
|
||||
uid: u64,
|
||||
type: file_type,
|
||||
perm: file_perm,
|
||||
size: u64,
|
||||
|
||||
creationDate: datestamp,
|
||||
accessDate: datestamp,
|
||||
modificationDate: datestamp,
|
||||
}
|
||||
|
||||
// TODO file dialogs
|
||||
|
||||
// typedef struct oc_file_open_with_dialog_elt
|
||||
// {
|
||||
// oc_list_elt listElt;
|
||||
// oc_file file;
|
||||
// } oc_file_open_with_dialog_elt;
|
||||
|
||||
// typedef struct oc_file_open_with_dialog_result
|
||||
// {
|
||||
// oc_file_dialog_button button;
|
||||
// oc_file file;
|
||||
// oc_list selection;
|
||||
// } oc_file_open_with_dialog_result;
|
||||
|
||||
// file_open_with_dialog_result :: u64 // TODO
|
||||
// file_dialog_desc :: u64 // TODO
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Low-level File IO API
|
||||
//----------------------------------------------------------------
|
||||
// @(default_calling_convention="c", link_prefix="oc_")
|
||||
// foreign {
|
||||
// oc_io_cmp oc_io_wait_single_req(oc_io_req* req);
|
||||
// }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// High-level File IO API
|
||||
//----------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
file_nil :: proc() -> file ---
|
||||
file_is_nil :: proc(handle: file) -> c.bool ---
|
||||
|
||||
file_open :: proc(path: str8, rights: file_access, flags: file_open_flags) -> file ---
|
||||
file_open_at :: proc(dir: file, path: str8, rights: file_access, flags: file_open_flags) -> file ---
|
||||
file_close :: proc(file: file) ---
|
||||
file_last_error :: proc(handle: file) -> io_error ---
|
||||
|
||||
file_pos :: proc(file: file) -> i64 ---
|
||||
file_seek :: proc(file: file, offset: i64, whence: file_whence) -> i64 ---
|
||||
file_write :: proc(file: file, size: u64, buffer: [^]byte) -> u64 ---
|
||||
file_read :: proc(file: file, size: u64, buffer: [^]byte) -> u64 ---
|
||||
|
||||
file_get_status :: proc(file: file) -> file_status ---
|
||||
file_size :: proc(file: file) -> u64 ---
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Asking users for file capabilities
|
||||
//----------------------------------------------------------------
|
||||
// @(default_calling_convention="c", link_prefix="oc_")
|
||||
// foreign {
|
||||
// file_open_with_request :: proc(path: str8, rights: file_access, flags: file_open_flags) -> file ---
|
||||
// file_open_with_dialog :: proc(arena: ^arena, rights: file_access, flags: file_open_flags, desc: ^file_dialog_desc) -> file_open_with_dialog_result ---
|
||||
// }
|
||||
117
core/sys/orca/lists.odin
Normal file
117
core/sys/orca/lists.odin
Normal file
@@ -0,0 +1,117 @@
|
||||
package orca
|
||||
|
||||
// TODO could check if container/intrusive/list/intrusive_list.odin can be used
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Lists
|
||||
//----------------------------------------------------------------
|
||||
list_elt :: struct {
|
||||
prev: ^list_elt,
|
||||
next: ^list_elt,
|
||||
}
|
||||
|
||||
list :: struct {
|
||||
first: ^list_elt,
|
||||
last: ^list_elt,
|
||||
}
|
||||
|
||||
list_init :: proc "c" (list: ^list) {
|
||||
list.first = nil
|
||||
list.last = nil
|
||||
}
|
||||
|
||||
list_insert :: proc "c" (list: ^list, afterElt, elt: ^list_elt) {
|
||||
elt.prev = afterElt
|
||||
elt.next = afterElt.next
|
||||
if afterElt.next != nil {
|
||||
afterElt.next.prev = elt
|
||||
} else {
|
||||
list.last = elt
|
||||
}
|
||||
afterElt.next = elt
|
||||
|
||||
// OC_DEBUG_ASSERT(elt.next != elt, "list_insert(): can't insert an element into itself")
|
||||
}
|
||||
|
||||
list_insert_before :: proc "c" (list: ^list, beforeElt, elt: ^list_elt) {
|
||||
elt.next = beforeElt
|
||||
elt.prev = beforeElt.prev
|
||||
|
||||
if beforeElt.prev != nil {
|
||||
beforeElt.prev.next = elt
|
||||
} else {
|
||||
list.first = elt
|
||||
}
|
||||
beforeElt.prev = elt
|
||||
|
||||
// OC_DEBUG_ASSERT(elt.next != elt, "list_insert_before(): can't insert an element into itself")
|
||||
}
|
||||
|
||||
list_remove :: proc "c" (list: ^list, elt: ^list_elt) {
|
||||
if elt.prev != nil {
|
||||
elt.prev.next = elt.next
|
||||
} else {
|
||||
// OC_DEBUG_ASSERT(list.first == elt)
|
||||
list.first = elt.next
|
||||
}
|
||||
|
||||
if elt.next != nil {
|
||||
elt.next.prev = elt.prev
|
||||
} else {
|
||||
// OC_DEBUG_ASSERT(list.last == elt)
|
||||
list.last = elt.prev
|
||||
}
|
||||
|
||||
elt.prev = nil
|
||||
elt.next = nil
|
||||
}
|
||||
|
||||
list_push :: proc "c" (list: ^list, elt: ^list_elt) {
|
||||
elt.next = list.first
|
||||
elt.prev = nil
|
||||
if list.first != nil {
|
||||
list.first.prev = elt
|
||||
} else {
|
||||
list.last = elt
|
||||
}
|
||||
list.first = elt
|
||||
}
|
||||
|
||||
list_pop :: proc "c" (list: ^list) -> ^list_elt {
|
||||
elt := list.first
|
||||
if elt != list.last {
|
||||
list_remove(list, elt)
|
||||
return elt
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
list_push_back :: proc "c" (list: ^list, elt: ^list_elt) {
|
||||
elt.prev = list.last
|
||||
elt.next = nil
|
||||
|
||||
if list.last != nil {
|
||||
list.last.next = elt
|
||||
} else {
|
||||
list.first = elt
|
||||
}
|
||||
|
||||
list.last = elt
|
||||
}
|
||||
|
||||
list_append :: list_push_back
|
||||
|
||||
list_pop_back :: proc "c" (list: ^list) -> ^list_elt {
|
||||
elt := list.last
|
||||
if elt != nil {
|
||||
list_remove(list, elt)
|
||||
return elt
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
list_empty :: proc "c" (list: ^list) -> bool {
|
||||
return list.first == nil || list.last == nil
|
||||
}
|
||||
32
core/sys/orca/orca.odin
Normal file
32
core/sys/orca/orca.odin
Normal file
@@ -0,0 +1,32 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
|
||||
vec2 :: [2]f32
|
||||
vec3 :: [3]f32
|
||||
vec4 :: [4]f32
|
||||
vec2i :: [2]i32
|
||||
// mat2x3 :: [6]f32
|
||||
mat2x3 :: matrix[2, 3]f32
|
||||
rect :: [4]f32
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// window
|
||||
//------------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
window_set_title :: proc(title: str8) ---
|
||||
window_set_size :: proc(size: vec2) ---
|
||||
request_quit :: proc() ---
|
||||
}
|
||||
|
||||
clock_kind :: enum c.int {
|
||||
MONOTONIC,
|
||||
UPTIME,
|
||||
DATE,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
clock_time :: proc(clock: clock_kind) -> f64 ---
|
||||
}
|
||||
685
core/sys/orca/ui.odin
Normal file
685
core/sys/orca/ui.odin
Normal file
@@ -0,0 +1,685 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
|
||||
ui_key :: struct {
|
||||
hash: u64
|
||||
}
|
||||
|
||||
ui_axis :: enum c.int {
|
||||
X,
|
||||
Y,
|
||||
}
|
||||
|
||||
ui_align :: enum c.int {
|
||||
START,
|
||||
END,
|
||||
CENTER,
|
||||
}
|
||||
|
||||
ui_layout_align :: [2]ui_align
|
||||
|
||||
ui_layout :: struct {
|
||||
axis: ui_axis,
|
||||
spacing: f32,
|
||||
margin: [2]f32,
|
||||
align: ui_layout_align,
|
||||
}
|
||||
|
||||
ui_size_kind :: enum c.int {
|
||||
TEXT,
|
||||
PIXELS,
|
||||
CHILDREN,
|
||||
PARENT,
|
||||
PARENT_MINUS_PIXELS,
|
||||
}
|
||||
|
||||
ui_size :: struct {
|
||||
kind: ui_size_kind,
|
||||
value: f32,
|
||||
relax: f32,
|
||||
minSize: f32,
|
||||
}
|
||||
|
||||
ui_box_size :: [2]ui_size
|
||||
ui_box_floating :: [2]c.bool
|
||||
|
||||
//NOTE: flags for axis-dependent properties (e.g. UI_STYLE_FLOAT_X/Y) need to be consecutive bits
|
||||
// in order to play well with axis agnostic functions
|
||||
ui_style_mask :: enum u64 {
|
||||
NONE = 0,
|
||||
SIZE_WIDTH = 1 << 1,
|
||||
SIZE_HEIGHT = 1 << 2,
|
||||
LAYOUT_AXIS = 1 << 3,
|
||||
LAYOUT_ALIGN_X = 1 << 4,
|
||||
LAYOUT_ALIGN_Y = 1 << 5,
|
||||
LAYOUT_SPACING = 1 << 6,
|
||||
LAYOUT_MARGIN_X = 1 << 7,
|
||||
LAYOUT_MARGIN_Y = 1 << 8,
|
||||
FLOAT_X = 1 << 9,
|
||||
FLOAT_Y = 1 << 10,
|
||||
COLOR = 1 << 11,
|
||||
BG_COLOR = 1 << 12,
|
||||
BORDER_COLOR = 1 << 13,
|
||||
BORDER_SIZE = 1 << 14,
|
||||
ROUNDNESS = 1 << 15,
|
||||
FONT = 1 << 16,
|
||||
FONT_SIZE = 1 << 17,
|
||||
ANIMATION_TIME = 1 << 18,
|
||||
ANIMATION_MASK = 1 << 19,
|
||||
|
||||
//masks
|
||||
SIZE = SIZE_WIDTH | SIZE_HEIGHT,
|
||||
|
||||
LAYOUT_MARGINS = LAYOUT_MARGIN_X | LAYOUT_MARGIN_Y,
|
||||
|
||||
LAYOUT = LAYOUT_AXIS | LAYOUT_ALIGN_X | LAYOUT_ALIGN_Y | LAYOUT_SPACING | LAYOUT_MARGIN_X | LAYOUT_MARGIN_Y,
|
||||
|
||||
FLOAT = FLOAT_X | FLOAT_Y,
|
||||
|
||||
MASK_INHERITED = COLOR | FONT | FONT_SIZE | ANIMATION_TIME | ANIMATION_MASK,
|
||||
}
|
||||
|
||||
ui_style :: struct {
|
||||
size: ui_box_size,
|
||||
layout: ui_layout,
|
||||
floating: ui_box_floating,
|
||||
floatTarget: vec2,
|
||||
_color: color,
|
||||
bgColor: color,
|
||||
borderColor: color,
|
||||
font: font,
|
||||
fontSize: f32,
|
||||
borderSize: f32,
|
||||
roundness: f32,
|
||||
animationTime: f32,
|
||||
animationMask: ui_style_mask,
|
||||
}
|
||||
|
||||
ui_palette :: struct {
|
||||
red0: color,
|
||||
red1: color,
|
||||
red2: color,
|
||||
red3: color,
|
||||
red4: color,
|
||||
red5: color,
|
||||
red6: color,
|
||||
red7: color,
|
||||
red8: color,
|
||||
red9: color,
|
||||
orange0: color,
|
||||
orange1: color,
|
||||
orange2: color,
|
||||
orange3: color,
|
||||
orange4: color,
|
||||
orange5: color,
|
||||
orange6: color,
|
||||
orange7: color,
|
||||
orange8: color,
|
||||
orange9: color,
|
||||
amber0: color,
|
||||
amber1: color,
|
||||
amber2: color,
|
||||
amber3: color,
|
||||
amber4: color,
|
||||
amber5: color,
|
||||
amber6: color,
|
||||
amber7: color,
|
||||
amber8: color,
|
||||
amber9: color,
|
||||
yellow0: color,
|
||||
yellow1: color,
|
||||
yellow2: color,
|
||||
yellow3: color,
|
||||
yellow4: color,
|
||||
yellow5: color,
|
||||
yellow6: color,
|
||||
yellow7: color,
|
||||
yellow8: color,
|
||||
yellow9: color,
|
||||
lime0: color,
|
||||
lime1: color,
|
||||
lime2: color,
|
||||
lime3: color,
|
||||
lime4: color,
|
||||
lime5: color,
|
||||
lime6: color,
|
||||
lime7: color,
|
||||
lime8: color,
|
||||
lime9: color,
|
||||
lightGreen0: color,
|
||||
lightGreen1: color,
|
||||
lightGreen2: color,
|
||||
lightGreen3: color,
|
||||
lightGreen4: color,
|
||||
lightGreen5: color,
|
||||
lightGreen6: color,
|
||||
lightGreen7: color,
|
||||
lightGreen8: color,
|
||||
lightGreen9: color,
|
||||
green0: color,
|
||||
green1: color,
|
||||
green2: color,
|
||||
green3: color,
|
||||
green4: color,
|
||||
green5: color,
|
||||
green6: color,
|
||||
green7: color,
|
||||
green8: color,
|
||||
green9: color,
|
||||
teal0: color,
|
||||
teal1: color,
|
||||
teal2: color,
|
||||
teal3: color,
|
||||
teal4: color,
|
||||
teal5: color,
|
||||
teal6: color,
|
||||
teal7: color,
|
||||
teal8: color,
|
||||
teal9: color,
|
||||
cyan0: color,
|
||||
cyan1: color,
|
||||
cyan2: color,
|
||||
cyan3: color,
|
||||
cyan4: color,
|
||||
cyan5: color,
|
||||
cyan6: color,
|
||||
cyan7: color,
|
||||
cyan8: color,
|
||||
cyan9: color,
|
||||
lightBlue0: color,
|
||||
lightBlue1: color,
|
||||
lightBlue2: color,
|
||||
lightBlue3: color,
|
||||
lightBlue4: color,
|
||||
lightBlue5: color,
|
||||
lightBlue6: color,
|
||||
lightBlue7: color,
|
||||
lightBlue8: color,
|
||||
lightBlue9: color,
|
||||
blue0: color,
|
||||
blue1: color,
|
||||
blue2: color,
|
||||
blue3: color,
|
||||
blue4: color,
|
||||
blue5: color,
|
||||
blue6: color,
|
||||
blue7: color,
|
||||
blue8: color,
|
||||
blue9: color,
|
||||
indigo0: color,
|
||||
indigo1: color,
|
||||
indigo2: color,
|
||||
indigo3: color,
|
||||
indigo4: color,
|
||||
indigo5: color,
|
||||
indigo6: color,
|
||||
indigo7: color,
|
||||
indigo8: color,
|
||||
indigo9: color,
|
||||
violet0: color,
|
||||
violet1: color,
|
||||
violet2: color,
|
||||
violet3: color,
|
||||
violet4: color,
|
||||
violet5: color,
|
||||
violet6: color,
|
||||
violet7: color,
|
||||
violet8: color,
|
||||
violet9: color,
|
||||
purple0: color,
|
||||
purple1: color,
|
||||
purple2: color,
|
||||
purple3: color,
|
||||
purple4: color,
|
||||
purple5: color,
|
||||
purple6: color,
|
||||
purple7: color,
|
||||
purple8: color,
|
||||
purple9: color,
|
||||
pink0: color,
|
||||
pink1: color,
|
||||
pink2: color,
|
||||
pink3: color,
|
||||
pink4: color,
|
||||
pink5: color,
|
||||
pink6: color,
|
||||
pink7: color,
|
||||
pink8: color,
|
||||
pink9: color,
|
||||
grey0: color,
|
||||
grey1: color,
|
||||
grey2: color,
|
||||
grey3: color,
|
||||
grey4: color,
|
||||
grey5: color,
|
||||
grey6: color,
|
||||
grey7: color,
|
||||
grey8: color,
|
||||
grey9: color,
|
||||
black: color,
|
||||
white: color,
|
||||
}
|
||||
|
||||
// TODO exteern
|
||||
// ui_palette: UI_DARK_PALETTE
|
||||
// ui_palette: UI_LIGHT_PALETTE
|
||||
|
||||
ui_theme :: struct {
|
||||
white: color,
|
||||
primary: color,
|
||||
primaryHover: color,
|
||||
primaryActive: color,
|
||||
border: color,
|
||||
fill0: color,
|
||||
fill1: color,
|
||||
fill2: color,
|
||||
bg0: color,
|
||||
bg1: color,
|
||||
bg2: color,
|
||||
bg3: color,
|
||||
bg4: color,
|
||||
text0: color,
|
||||
text1: color,
|
||||
text2: color,
|
||||
text3: color,
|
||||
sliderThumbBorder: color,
|
||||
elevatedBorder: color,
|
||||
|
||||
roundnessSmall: f32,
|
||||
roundnessMedium: f32,
|
||||
roundnessLarge: f32,
|
||||
|
||||
palette: ^ui_palette,
|
||||
}
|
||||
|
||||
@export UI_DARK_THEME: ui_theme
|
||||
@export UI_LIGHT_THEME: ui_theme
|
||||
|
||||
ui_tag :: struct {
|
||||
hash: u64,
|
||||
}
|
||||
|
||||
ui_selector_kind :: enum c.int {
|
||||
ANY,
|
||||
OWNER,
|
||||
TEXT,
|
||||
TAG,
|
||||
STATUS,
|
||||
KEY,
|
||||
}
|
||||
|
||||
ui_status :: enum u8 {
|
||||
NONE = 0,
|
||||
HOVER = 1 << 1,
|
||||
HOT = 1 << 2,
|
||||
ACTIVE = 1 << 3,
|
||||
DRAGGING = 1 << 4,
|
||||
}
|
||||
|
||||
ui_selector_op :: enum c.int {
|
||||
DESCENDANT = 0,
|
||||
AND = 1,
|
||||
}
|
||||
|
||||
ui_selector :: struct {
|
||||
listElt: list_elt,
|
||||
kind: ui_selector_kind,
|
||||
op: ui_selector_op,
|
||||
|
||||
type: struct #raw_union {
|
||||
text: str8,
|
||||
key: ui_key,
|
||||
tag: ui_tag,
|
||||
status: ui_status,
|
||||
}
|
||||
}
|
||||
|
||||
ui_pattern :: struct {
|
||||
l: list,
|
||||
}
|
||||
|
||||
ui_style_rule :: struct {
|
||||
boxElt: list_elt,
|
||||
buildElt: list_elt,
|
||||
tmpElt: list_elt,
|
||||
|
||||
owner: ^ui_box,
|
||||
pattern: ui_pattern,
|
||||
mask: ui_style_mask,
|
||||
style: ^ui_style,
|
||||
}
|
||||
|
||||
ui_sig :: struct {
|
||||
box: ^ui_box,
|
||||
|
||||
mouse: vec2,
|
||||
delta: vec2,
|
||||
wheel: vec2,
|
||||
|
||||
pressed: c.bool,
|
||||
released: c.bool,
|
||||
clicked: c.bool,
|
||||
doubleClicked: c.bool,
|
||||
tripleClicked: c.bool,
|
||||
rightPressed: c.bool,
|
||||
|
||||
dragging: c.bool,
|
||||
hovering: c.bool,
|
||||
|
||||
pasted: c.bool,
|
||||
|
||||
}
|
||||
|
||||
ui_box_draw_proc :: proc "c" (box: ^ui_box, data: rawptr)
|
||||
|
||||
ui_flags :: enum c.int {
|
||||
NONE = 0,
|
||||
CLICKABLE = (1 << 0),
|
||||
SCROLL_WHEEL_X = (1 << 1),
|
||||
SCROLL_WHEEL_Y = (1 << 2),
|
||||
BLOCK_MOUSE = (1 << 3),
|
||||
HOT_ANIMATION = (1 << 4),
|
||||
ACTIVE_ANIMATION = (1 << 5),
|
||||
//WARN: these two following flags need to be kept as consecutive bits to
|
||||
// play well with axis-agnostic functions
|
||||
OVERFLOW_ALLOW_X = (1 << 6),
|
||||
OVERFLOW_ALLOW_Y = (1 << 7),
|
||||
CLIP = (1 << 8),
|
||||
DRAW_BACKGROUND = (1 << 9),
|
||||
DRAW_FOREGROUND = (1 << 10),
|
||||
DRAW_BORDER = (1 << 11),
|
||||
DRAW_TEXT = (1 << 12),
|
||||
DRAW_PROC = (1 << 13),
|
||||
|
||||
OVERLAY = (1 << 16),
|
||||
}
|
||||
|
||||
ui_box :: struct {
|
||||
// hierarchy
|
||||
listElt: list_elt,
|
||||
children: list,
|
||||
parent: ^ui_box,
|
||||
|
||||
overlayElt: list_elt,
|
||||
|
||||
// keying and caching
|
||||
bucketElt: list_elt,
|
||||
key: ui_key,
|
||||
frameCounter: u64,
|
||||
|
||||
// builder-provided info
|
||||
flags: ui_flags,
|
||||
string: str8,
|
||||
tags: list,
|
||||
|
||||
drawProc: ui_box_draw_proc,
|
||||
drawData: rawptr,
|
||||
|
||||
// styling
|
||||
beforeRules: list,
|
||||
afterRules: list,
|
||||
|
||||
//ui_style_tag tag
|
||||
targetStyle: ^ui_style,
|
||||
style: ui_style,
|
||||
z: u32,
|
||||
|
||||
floatPos: vec2,
|
||||
childrenSum: [2]f32,
|
||||
spacing: [2]f32,
|
||||
minSize: [2]f32,
|
||||
rect: rect,
|
||||
|
||||
// signals
|
||||
sig: ^ui_sig,
|
||||
|
||||
// stateful behaviour
|
||||
fresh: c.bool,
|
||||
closed: c.bool,
|
||||
parentClosed: c.bool,
|
||||
dragging: c.bool,
|
||||
hot: c.bool,
|
||||
active: c.bool,
|
||||
scroll: vec2,
|
||||
pressedMouse: vec2,
|
||||
|
||||
// animation data
|
||||
hotTransition: f32,
|
||||
activeTransition: f32,
|
||||
}
|
||||
|
||||
UI_MAX_INPUT_CHAR_PER_FRAME :: 64
|
||||
|
||||
ui_input_text :: struct {
|
||||
count: u8,
|
||||
codePoints: [UI_MAX_INPUT_CHAR_PER_FRAME]utf32,
|
||||
}
|
||||
|
||||
ui_stack_elt :: struct {
|
||||
parent: ^ui_stack_elt,
|
||||
|
||||
_: struct #raw_union {
|
||||
box: ^ui_box,
|
||||
size: ui_size,
|
||||
clip: rect,
|
||||
}
|
||||
}
|
||||
|
||||
ui_tag_elt :: struct {
|
||||
listElt: list_elt,
|
||||
tag: ui_tag,
|
||||
}
|
||||
|
||||
UI_BOX_MAP_BUCKET_COUNT :: 1024
|
||||
|
||||
ui_edit_move :: enum c.int {
|
||||
NONE,
|
||||
CHAR,
|
||||
WORD,
|
||||
LINE,
|
||||
}
|
||||
|
||||
ui_context :: struct {
|
||||
init: c.bool,
|
||||
|
||||
input: input_state,
|
||||
|
||||
frameCounter: u64,
|
||||
frameTime: f64,
|
||||
lastFrameDuration: f64,
|
||||
|
||||
frameArena: arena,
|
||||
boxPool: pool,
|
||||
boxMap: [UI_BOX_MAP_BUCKET_COUNT]list,
|
||||
|
||||
root: ^ui_box,
|
||||
overlay: ^ui_box,
|
||||
overlayList: list,
|
||||
boxStack: ^ui_stack_elt,
|
||||
clipStack: ^ui_stack_elt,
|
||||
|
||||
nextBoxBeforeRules: list,
|
||||
nextBoxAfterRules: list,
|
||||
nextBoxTags: list,
|
||||
|
||||
z: u32,
|
||||
hovered: ^ui_box,
|
||||
|
||||
focus: ^ui_box,
|
||||
editCursor: i32,
|
||||
editMark: i32,
|
||||
editFirstDisplayedChar: i32,
|
||||
editCursorBlinkStart: f64,
|
||||
editSelectionMode: ui_edit_move,
|
||||
editWordSelectionInitialCursor: i32,
|
||||
editWordSelectionInitialMark: i32,
|
||||
|
||||
clipboardRegistered: c.bool,
|
||||
|
||||
theme: ^ui_theme,
|
||||
}
|
||||
|
||||
ui_text_box_result :: struct {
|
||||
changed: c.bool,
|
||||
accepted: c.bool,
|
||||
text: str8,
|
||||
}
|
||||
|
||||
ui_select_popup_info :: struct {
|
||||
changed: bool,
|
||||
selectedIndex: int, // -1 if nothing is selected
|
||||
optionCount: int,
|
||||
options: [^]str8,
|
||||
placeholder: str8,
|
||||
}
|
||||
|
||||
ui_radio_group_info :: struct {
|
||||
changed: bool,
|
||||
selectedIndex: int, // -1 if nothing is selected
|
||||
optionCount: int,
|
||||
options: [^]str8,
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Context and frame lifecycle
|
||||
//----------------------------------------------------------------
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
ui_init :: proc(ctx: ^ui_context) ---
|
||||
ui_get_context :: proc() -> ^ui_context ---
|
||||
ui_set_context :: proc(ctx: ^ui_context) ---
|
||||
|
||||
ui_process_event :: proc(event: ^event) ---
|
||||
ui_begin_frame :: proc(size: vec2, defaultStyle: ^ui_style, mask: ui_style_mask) ---
|
||||
ui_end_frame :: proc() ---
|
||||
ui_draw :: proc() ---
|
||||
}
|
||||
|
||||
@(deferred_none=ui_end_frame)
|
||||
ui_frame :: proc "c" (size: vec2, defaultStyle: ^ui_style, mask: ui_style_mask) {
|
||||
ui_begin_frame(size, defaultStyle, mask)
|
||||
}
|
||||
ui_frame_scoped :: ui_frame
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Common widget helpers
|
||||
//----------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
ui_label :: proc(label: cstring) -> ui_sig ---
|
||||
ui_label_str8 :: proc(label: str8) -> ui_sig ---
|
||||
ui_button :: proc(label: cstring) -> ui_sig ---
|
||||
ui_checkbox :: proc(name: cstring, checked: ^c.bool) -> ui_sig ---
|
||||
ui_slider :: proc(label: cstring, value: ^f32) -> ^ui_box ---
|
||||
ui_scrollbar :: proc(label: cstring, thumbRatio: f32, scrollValue: ^f32) -> ^ui_box ---
|
||||
ui_text_box :: proc(name: cstring, arena: ^arena, text: str8) -> ui_text_box_result ---
|
||||
ui_select_popup :: proc(name: cstring, info: ^ui_select_popup_info) -> ui_select_popup_info ---
|
||||
ui_radio_group :: proc(name: cstring, info: ^ui_radio_group_info) -> ui_radio_group_info ---
|
||||
|
||||
ui_panel_begin :: proc(name: cstring, flags: ui_flags) ---
|
||||
ui_panel_end :: proc() ---
|
||||
|
||||
ui_menu_bar_begin :: proc(label: cstring) ---
|
||||
ui_menu_bar_end :: proc() ---
|
||||
|
||||
ui_menu_begin :: proc(label: cstring) ---
|
||||
ui_menu_end :: proc() ---
|
||||
|
||||
ui_menu_button :: proc(name: cstring) -> ui_sig ---
|
||||
|
||||
ui_tooltip_begin :: proc(name: cstring) -> ui_sig ---
|
||||
ui_tooltip_end :: proc() ---
|
||||
}
|
||||
|
||||
@(deferred_none=ui_panel_end)
|
||||
ui_panel :: proc "c" (name: cstring, flags: ui_flags) {
|
||||
ui_panel_begin(name, flags)
|
||||
}
|
||||
ui_panel_scoped :: ui_panel
|
||||
|
||||
@(deferred_none=ui_menu_bar_end)
|
||||
ui_menu_bar :: proc "c" (label: cstring) {
|
||||
ui_menu_bar_begin(label)
|
||||
}
|
||||
ui_menu_bar_scoped :: ui_menu_bar
|
||||
|
||||
@(deferred_none=ui_menu_end)
|
||||
ui_menu :: proc "c" (label: cstring) {
|
||||
ui_menu_begin(label)
|
||||
}
|
||||
ui_menu_scoped :: ui_menu
|
||||
|
||||
@(deferred_none=ui_tooltip_end)
|
||||
ui_tooltip :: proc "c" (label: cstring) -> ui_sig {
|
||||
return ui_tooltip_begin(label)
|
||||
}
|
||||
ui_tooltip_scoped :: ui_menu
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Styling
|
||||
//-------------------------------------------------------------------------------------
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
ui_style_next :: proc(style: ^ui_style, mask: ui_style_mask) ---
|
||||
|
||||
ui_pattern_push :: proc(arena: ^arena, pattern: ^ui_pattern, selector: ui_selector) ---
|
||||
ui_pattern_all :: proc() -> ui_pattern ---
|
||||
ui_pattern_owner :: proc() -> ui_pattern ---
|
||||
|
||||
ui_style_match_before :: proc(pattern: ui_pattern, style: ^ui_style, mask: ui_style_mask) ---
|
||||
ui_style_match_after :: proc(pattern: ui_pattern, style: ^ui_style, mask: ui_style_mask) ---
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// BOX
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
ui_box_make_str8 :: proc(str: str8, flags: ui_flags) -> ^ui_box ---
|
||||
ui_box_begin_str8 :: proc(str: str8, flags: ui_flags) -> ^ui_box ---
|
||||
ui_box_end :: proc() -> ^ui_box ---
|
||||
}
|
||||
|
||||
@(deferred_none=ui_box_end)
|
||||
ui_container :: proc "c" (str: string, flags: ui_flags) -> ^ui_box {
|
||||
return ui_box_begin_str8(str, flags)
|
||||
}
|
||||
|
||||
@(deferred_none=ui_box_end)
|
||||
ui_container_str8 :: proc "c" (str: str8, flags: ui_flags) -> ^ui_box {
|
||||
return ui_box_begin_str8(str, flags)
|
||||
}
|
||||
|
||||
ui_box_make :: proc "c" (str: string, flags: ui_flags) -> ^ui_box {
|
||||
return ui_box_make_str8(str, flags)
|
||||
}
|
||||
|
||||
ui_box_begin :: proc "c" (str: string, flags: ui_flags) -> ^ui_box {
|
||||
return ui_box_begin_str8(str, flags)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// BOX
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
ui_tag_make_str8 :: proc(str: str8) -> ui_tag ---
|
||||
ui_tag_box_str8 :: proc(box: ^ui_box, str: str8) ---
|
||||
ui_tag_next_str8 :: proc(str: str8) ---
|
||||
}
|
||||
|
||||
ui_tag_make :: proc "c" (s: string) -> ui_tag {
|
||||
return ui_tag_make_str8(s)
|
||||
}
|
||||
|
||||
ui_tag_box :: proc "c" (b: ^ui_box, s: string) {
|
||||
ui_tag_box_str8(b, s)
|
||||
}
|
||||
|
||||
ui_tag_next :: proc "c" (s: string) {
|
||||
ui_tag_next_str8(s)
|
||||
}
|
||||
131
core/sys/orca/utf8.odin
Normal file
131
core/sys/orca/utf8.odin
Normal file
@@ -0,0 +1,131 @@
|
||||
package orca
|
||||
|
||||
unicode_range :: struct {
|
||||
firstCodePoint: utf32,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
UNICODE_BASIC_LATIN:: unicode_range { 0x0000, 127 }
|
||||
UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT:: unicode_range { 0x0080, 127 }
|
||||
UNICODE_LATIN_EXTENDED_A:: unicode_range { 0x0100, 127 }
|
||||
UNICODE_LATIN_EXTENDED_B:: unicode_range { 0x0180, 207 }
|
||||
UNICODE_IPA_EXTENSIONS:: unicode_range { 0x0250, 95 }
|
||||
UNICODE_SPACING_MODIFIER_LETTERS:: unicode_range { 0x02b0, 79 }
|
||||
UNICODE_COMBINING_DIACRITICAL_MARKS:: unicode_range { 0x0300, 111 }
|
||||
UNICODE_GREEK_COPTIC:: unicode_range { 0x0370, 143 }
|
||||
UNICODE_CYRILLIC:: unicode_range { 0x0400, 255 }
|
||||
UNICODE_CYRILLIC_SUPPLEMENT:: unicode_range { 0x0500, 47 }
|
||||
UNICODE_ARMENIAN:: unicode_range { 0x0530, 95 }
|
||||
UNICODE_HEBREW:: unicode_range { 0x0590, 111 }
|
||||
UNICODE_ARABIC:: unicode_range { 0x0600, 255 }
|
||||
UNICODE_SYRIAC:: unicode_range { 0x0700, 79 }
|
||||
UNICODE_THAANA:: unicode_range { 0x0780, 63 }
|
||||
UNICODE_DEVANAGARI:: unicode_range { 0x0900, 127 }
|
||||
UNICODE_BENGALI_ASSAMESE:: unicode_range { 0x0980, 127 }
|
||||
UNICODE_GURMUKHI:: unicode_range { 0x0a00, 127 }
|
||||
UNICODE_GUJARATI:: unicode_range { 0x0a80, 127 }
|
||||
UNICODE_ORIYA:: unicode_range { 0x0b00, 127 }
|
||||
UNICODE_TAMIL:: unicode_range { 0x0b80, 127 }
|
||||
UNICODE_TELUGU:: unicode_range { 0x0c00, 127 }
|
||||
UNICODE_KANNADA:: unicode_range { 0x0c80, 127 }
|
||||
UNICODE_MALAYALAM:: unicode_range { 0x0d00, 255 }
|
||||
UNICODE_SINHALA:: unicode_range { 0x0d80, 127 }
|
||||
UNICODE_THAI:: unicode_range { 0x0e00, 127 }
|
||||
UNICODE_LAO:: unicode_range { 0x0e80, 127 }
|
||||
UNICODE_TIBETAN:: unicode_range { 0x0f00, 255 }
|
||||
UNICODE_MYANMAR:: unicode_range { 0x1000, 159 }
|
||||
UNICODE_GEORGIAN:: unicode_range { 0x10a0, 95 }
|
||||
UNICODE_HANGUL_JAMO:: unicode_range { 0x1100, 255 }
|
||||
UNICODE_ETHIOPIC:: unicode_range { 0x1200, 383 }
|
||||
UNICODE_CHEROKEE:: unicode_range { 0x13a0, 95 }
|
||||
UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS:: unicode_range { 0x1400, 639 }
|
||||
UNICODE_OGHAM:: unicode_range { 0x1680, 31 }
|
||||
UNICODE_RUNIC:: unicode_range { 0x16a0, 95 }
|
||||
UNICODE_TAGALOG:: unicode_range { 0x1700, 31 }
|
||||
UNICODE_HANUNOO:: unicode_range { 0x1720, 31 }
|
||||
UNICODE_BUHID:: unicode_range { 0x1740, 31 }
|
||||
UNICODE_TAGBANWA:: unicode_range { 0x1760, 31 }
|
||||
UNICODE_KHMER:: unicode_range { 0x1780, 127 }
|
||||
UNICODE_MONGOLIAN:: unicode_range { 0x1800, 175 }
|
||||
UNICODE_LIMBU:: unicode_range { 0x1900, 79 }
|
||||
UNICODE_TAI_LE:: unicode_range { 0x1950, 47 }
|
||||
UNICODE_KHMER_SYMBOLS:: unicode_range { 0x19e0, 31 }
|
||||
UNICODE_PHONETIC_EXTENSIONS:: unicode_range { 0x1d00, 127 }
|
||||
UNICODE_LATIN_EXTENDED_ADDITIONAL:: unicode_range { 0x1e00, 255 }
|
||||
UNICODE_GREEK_EXTENDED:: unicode_range { 0x1f00, 255 }
|
||||
UNICODE_GENERAL_PUNCTUATION:: unicode_range { 0x2000, 111 }
|
||||
UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS:: unicode_range { 0x2070, 47 }
|
||||
UNICODE_CURRENCY_SYMBOLS:: unicode_range { 0x20a0, 47 }
|
||||
UNICODE_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS:: unicode_range { 0x20d0, 47 }
|
||||
UNICODE_LETTERLIKE_SYMBOLS:: unicode_range { 0x2100, 79 }
|
||||
UNICODE_NUMBER_FORMS:: unicode_range { 0x2150, 63 }
|
||||
UNICODE_ARROWS:: unicode_range { 0x2190, 111 }
|
||||
UNICODE_MATHEMATICAL_OPERATORS:: unicode_range { 0x2200, 255 }
|
||||
UNICODE_MISCELLANEOUS_TECHNICAL:: unicode_range { 0x2300, 255 }
|
||||
UNICODE_CONTROL_PICTURES:: unicode_range { 0x2400, 63 }
|
||||
UNICODE_OPTICAL_CHARACTER_RECOGNITION:: unicode_range { 0x2440, 31 }
|
||||
UNICODE_ENCLOSED_ALPHANUMERICS:: unicode_range { 0x2460, 159 }
|
||||
UNICODE_BOX_DRAWING:: unicode_range { 0x2500, 127 }
|
||||
UNICODE_BLOCK_ELEMENTS:: unicode_range { 0x2580, 31 }
|
||||
UNICODE_GEOMETRIC_SHAPES:: unicode_range { 0x25a0, 95 }
|
||||
UNICODE_MISCELLANEOUS_SYMBOLS:: unicode_range { 0x2600, 255 }
|
||||
UNICODE_DINGBATS:: unicode_range { 0x2700, 191 }
|
||||
UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A:: unicode_range { 0x27c0, 47 }
|
||||
UNICODE_SUPPLEMENTAL_ARROWS_A:: unicode_range { 0x27f0, 15 }
|
||||
UNICODE_BRAILLE_PATTERNS:: unicode_range { 0x2800, 255 }
|
||||
UNICODE_SUPPLEMENTAL_ARROWS_B:: unicode_range { 0x2900, 127 }
|
||||
UNICODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B:: unicode_range { 0x2980, 127 }
|
||||
UNICODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS:: unicode_range { 0x2a00, 255 }
|
||||
UNICODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS:: unicode_range { 0x2b00, 255 }
|
||||
UNICODE_CJK_RADICALS_SUPPLEMENT:: unicode_range { 0x2e80, 127 }
|
||||
UNICODE_KANGXI_RADICALS:: unicode_range { 0x2f00, 223 }
|
||||
UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS:: unicode_range { 0x2ff0, 15 }
|
||||
UNICODE_CJK_SYMBOLS_AND_PUNCTUATION:: unicode_range { 0x3000, 63 }
|
||||
UNICODE_HIRAGANA:: unicode_range { 0x3040, 95 }
|
||||
UNICODE_KATAKANA:: unicode_range { 0x30a0, 95 }
|
||||
UNICODE_BOPOMOFO:: unicode_range { 0x3100, 47 }
|
||||
UNICODE_HANGUL_COMPATIBILITY_JAMO:: unicode_range { 0x3130, 95 }
|
||||
UNICODE_KANBUN_KUNTEN:: unicode_range { 0x3190, 15 }
|
||||
UNICODE_BOPOMOFO_EXTENDED:: unicode_range { 0x31a0, 31 }
|
||||
UNICODE_KATAKANA_PHONETIC_EXTENSIONS:: unicode_range { 0x31f0, 15 }
|
||||
UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS:: unicode_range { 0x3200, 255 }
|
||||
UNICODE_CJK_COMPATIBILITY:: unicode_range { 0x3300, 255 }
|
||||
UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A:: unicode_range { 0x3400, 6591 }
|
||||
UNICODE_YIJING_HEXAGRAM_SYMBOLS:: unicode_range { 0x4dc0, 63 }
|
||||
UNICODE_CJK_UNIFIED_IDEOGRAPHS:: unicode_range { 0x4e00, 20911 }
|
||||
UNICODE_YI_SYLLABLES:: unicode_range { 0xa000, 1167 }
|
||||
UNICODE_YI_RADICALS:: unicode_range { 0xa490, 63 }
|
||||
UNICODE_HANGUL_SYLLABLES:: unicode_range { 0xac00, 11183 }
|
||||
UNICODE_HIGH_SURROGATE_AREA:: unicode_range { 0xd800, 1023 }
|
||||
UNICODE_LOW_SURROGATE_AREA:: unicode_range { 0xdc00, 1023 }
|
||||
UNICODE_PRIVATE_USE_AREA:: unicode_range { 0xe000, 6399 }
|
||||
UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS:: unicode_range { 0xf900, 511 }
|
||||
UNICODE_ALPHABETIC_PRESENTATION_FORMS:: unicode_range { 0xfb00, 79 }
|
||||
UNICODE_ARABIC_PRESENTATION_FORMS_A:: unicode_range { 0xfb50, 687 }
|
||||
UNICODE_VARIATION_SELECTORS:: unicode_range { 0xfe00, 15 }
|
||||
UNICODE_COMBINING_HALF_MARKS:: unicode_range { 0xfe20, 15 }
|
||||
UNICODE_CJK_COMPATIBILITY_FORMS:: unicode_range { 0xfe30, 31 }
|
||||
UNICODE_SMALL_FORM_VARIANTS:: unicode_range { 0xfe50, 31 }
|
||||
UNICODE_ARABIC_PRESENTATION_FORMS_B:: unicode_range { 0xfe70, 143 }
|
||||
UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS:: unicode_range { 0xff00, 239 }
|
||||
UNICODE_SPECIALS:: unicode_range { 0xfff0, 15 }
|
||||
UNICODE_LINEAR_B_SYLLABARY:: unicode_range { 0x10000, 127 }
|
||||
UNICODE_LINEAR_B_IDEOGRAMS:: unicode_range { 0x10080, 127 }
|
||||
UNICODE_AEGEAN_NUMBERS:: unicode_range { 0x10100, 63 }
|
||||
UNICODE_OLD_ITALIC:: unicode_range { 0x10300, 47 }
|
||||
UNICODE_GOTHIC:: unicode_range { 0x10330, 31 }
|
||||
UNICODE_UGARITIC:: unicode_range { 0x10380, 31 }
|
||||
UNICODE_DESERET:: unicode_range { 0x10400, 79 }
|
||||
UNICODE_SHAVIAN:: unicode_range { 0x10450, 47 }
|
||||
UNICODE_OSMANYA:: unicode_range { 0x10480, 47 }
|
||||
UNICODE_CYPRIOT_SYLLABARY:: unicode_range { 0x10800, 63 }
|
||||
UNICODE_BYZANTINE_MUSICAL_SYMBOLS:: unicode_range { 0x1d000, 255 }
|
||||
UNICODE_MUSICAL_SYMBOLS:: unicode_range { 0x1d100, 255 }
|
||||
UNICODE_TAI_XUAN_JING_SYMBOLS:: unicode_range { 0x1d300, 95 }
|
||||
UNICODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS:: unicode_range { 0x1d400, 1023 }
|
||||
UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B:: unicode_range { 0x20000, 42719 }
|
||||
UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT:: unicode_range { 0x2f800, 543 }
|
||||
UNICODE_TAGS:: unicode_range { 0xe0000, 127 }
|
||||
UNICODE_VARIATION_SELECTORS_SUPPLEMENT:: unicode_range { 0xe0100, 239 }
|
||||
UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A:: unicode_range { 0xf0000, 65533 }
|
||||
UNICODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B :: unicode_range { 0x100000, 65533 }
|
||||
266
core/sys/orca/util.odin
Normal file
266
core/sys/orca/util.odin
Normal file
@@ -0,0 +1,266 @@
|
||||
package orca
|
||||
|
||||
import "core:c"
|
||||
import "core:fmt"
|
||||
import "core:runtime"
|
||||
import "core:intrinsics"
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Arenas
|
||||
//----------------------------------------------------------------
|
||||
|
||||
mem_reserve_proc :: proc "c" (ctx: ^base_allocator, size: u64)
|
||||
mem_modify_proc :: proc "c" (ctx: ^base_allocator, ptr: rawptr, size: u64)
|
||||
|
||||
base_allocator :: struct {
|
||||
reserve: mem_reserve_proc,
|
||||
commit: mem_modify_proc,
|
||||
decommit: mem_modify_proc,
|
||||
release: mem_modify_proc,
|
||||
}
|
||||
|
||||
arena_chunk :: struct {
|
||||
listElt: list_elt,
|
||||
ptr: ^c.char,
|
||||
offset: u64,
|
||||
committed: u64,
|
||||
cap: u64,
|
||||
}
|
||||
|
||||
arena :: struct {
|
||||
base: ^base_allocator,
|
||||
chunks: list,
|
||||
currentChunk: ^arena_chunk,
|
||||
}
|
||||
|
||||
arena_scope :: struct {
|
||||
arena: ^arena,
|
||||
chunk: ^arena_chunk,
|
||||
offset: u64,
|
||||
}
|
||||
|
||||
arena_options :: struct {
|
||||
base: ^base_allocator,
|
||||
reserve: u64,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
arena_init :: proc(arena: ^arena) ---
|
||||
arena_init_with_options :: proc(arena: ^arena, options: ^arena_options) ---
|
||||
arena_cleanup :: proc(arena: ^arena) ---
|
||||
|
||||
arena_push :: proc(arena: ^arena, size: u64) -> rawptr ---
|
||||
arena_clear :: proc(arena: ^arena) ---
|
||||
|
||||
arena_scope_begin :: proc(arena: ^arena) -> arena_scope ---
|
||||
arena_scope_end :: proc(scope: arena_scope) ---
|
||||
|
||||
scratch_begin :: proc() -> arena_scope ---
|
||||
scratch_begin_next :: proc(used: ^arena) -> arena_scope ---
|
||||
}
|
||||
|
||||
arena_push_type :: proc "c" (arena: ^arena, $T: typeid) -> ^T {
|
||||
return cast(^T) arena_push(arena, size_of(T))
|
||||
}
|
||||
|
||||
arena_push_array :: proc "c" (arena: ^arena, $T: typeid, count: int) -> []T {
|
||||
return ([^]T)(arena_push(arena, size_of(T)))[:count]
|
||||
}
|
||||
|
||||
scratch_end :: arena_scope_end
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Pool
|
||||
//----------------------------------------------------------------
|
||||
|
||||
pool :: struct {
|
||||
arena: arena,
|
||||
freeList: list,
|
||||
blockSize: u64,
|
||||
}
|
||||
|
||||
pool_options :: struct {
|
||||
base: ^base_allocator,
|
||||
reserve: u64,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
pool_init :: proc(pool: ^pool, blockSize: u64) ---
|
||||
pool_init_with_options :: proc(pool: ^pool, blockSize: u64, options: ^pool_options) ---
|
||||
pool_cleanup :: proc(pool: ^pool) ---
|
||||
|
||||
pool_alloc :: proc(pool: ^pool) -> rawptr ---
|
||||
pool_recycle :: proc(pool: ^pool, ptr: rawptr) ---
|
||||
pool_clear :: proc(pool: ^pool) ---
|
||||
}
|
||||
|
||||
pool_alloc_type :: proc "c" (arena: ^arena, $T: typeid) -> ^T {
|
||||
return cast(^T) pool_alloc(arena)
|
||||
}
|
||||
|
||||
// TODO support list macros?
|
||||
// #define list_entry :: proc(ptr, type, member)
|
||||
// #define list_next_entry :: proc(list, elt, type, member)
|
||||
// #define list_prev_entry :: proc(list, elt, type, member)
|
||||
// #define list_first_entry :: proc(list, type, member)
|
||||
// #define list_last_entry :: proc(list, type, member)
|
||||
// #define list_pop_entry :: proc(list, type, member)
|
||||
|
||||
// @(default_calling_convention="c", link_prefix="oc_")
|
||||
// foreign {
|
||||
// list_init :: proc(list: ^list) ---
|
||||
// list_empty :: proc(list: ^list) -> c.bool ---
|
||||
|
||||
// list_begin :: proc(list: ^list) -> ^list_elt ---
|
||||
// list_end :: proc(list: ^list) -> ^list_elt ---
|
||||
// list_last :: proc(list: ^list) -> ^list_elt ---
|
||||
|
||||
// list_insert :: proc(list: ^list, afterElt: ^list_elt, elt: ^list_elt) ---
|
||||
// list_insert_before :: proc(list: ^list, beforeElt: ^list_elt, elt: ^list_elt) ---
|
||||
// list_remove :: proc(list: ^list, elt: ^list_elt) ---
|
||||
// list_push :: proc(list: ^list, elt: ^list_elt) ---
|
||||
// list_pop :: proc(list: ^list) -> ^list_elt ---
|
||||
// list_push_back :: proc(list: ^list, elt: ^list_elt) ---
|
||||
// list_pop_back :: proc(list: ^list) -> ^list_elt ---
|
||||
// }
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
// for iterators
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
List_Iterator :: struct($T: typeid) {
|
||||
iterate: ^list,
|
||||
curr: ^list_elt,
|
||||
index: int,
|
||||
offset: uintptr,
|
||||
}
|
||||
|
||||
// NOTE(Skytrias): intrusive list iterator
|
||||
list_iter_init :: proc "c" (iterate: ^list, $T: typeid, $field_name: string) -> (res: List_Iterator(T))
|
||||
where intrinsics.type_has_field(T, field_name),
|
||||
intrinsics.type_field_type(T, field_name) == list_elt {
|
||||
res.iterate = iterate
|
||||
res.curr = list_begin(iterate)
|
||||
res.offset = offset_of_by_string(T, field_name)
|
||||
return
|
||||
}
|
||||
|
||||
list_iterate :: proc "c" (iter: ^List_Iterator($T)) -> (ptr: ^T, ok: bool) {
|
||||
node := iter.curr
|
||||
if node == nil {
|
||||
return nil, false
|
||||
}
|
||||
iter.index += 1
|
||||
iter.curr = node.next
|
||||
return (^T)(uintptr(node) - iter.offset), true
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Strings / string lists / path strings
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// TODO use odin cstring when ^c.char is used?
|
||||
|
||||
str8 :: string
|
||||
str32 :: []rune
|
||||
|
||||
str8_list :: struct {
|
||||
list: list,
|
||||
eltCount: u64,
|
||||
len: u64,
|
||||
}
|
||||
|
||||
str8_elt :: struct {
|
||||
str: str8,
|
||||
listElt: list_elt,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
str8_push_buffer :: proc(arena: ^arena, len: u64, buffer: ^c.char) -> str8 ---
|
||||
str8_push_cstring :: proc(arena: ^arena, str: ^c.char) -> str8 ---
|
||||
str8_push_copy :: proc(arena: ^arena, s: str8) -> str8 ---
|
||||
str8_push_slice :: proc(arena: ^arena, s: str8, start: u64, end: u64) -> str8 ---
|
||||
|
||||
// TODO get rid of these or wrap them
|
||||
str8_pushfv :: proc(arena: ^arena, format: cstring, args: c.va_list) -> str8 ---
|
||||
str8_pushf :: proc(arena: ^arena, format: cstring, #c_vararg args: ..any) -> str8 ---
|
||||
|
||||
str8_to_cstring :: proc(arena: ^arena, string: str8) -> ^c.char ---
|
||||
|
||||
str8_list_push :: proc(arena: ^arena, list: ^str8_list, str: str8) ---
|
||||
str8_list_pushf :: proc(arena: ^arena, list: ^str8_list, format: cstring, #c_vararg args: ..any) ---
|
||||
|
||||
str8_list_collate :: proc(arena: ^arena, list: str8_list, prefix: str8, separator: str8, postfix: str8) -> str8 ---
|
||||
str8_list_join :: proc(arena: ^arena, list: str8_list) -> str8 ---
|
||||
str8_split :: proc(arena: ^arena, str: str8, separators: str8_list) -> str8_list ---
|
||||
|
||||
path_slice_directory :: proc(path: str8) -> str8 ---
|
||||
path_slice_filename :: proc(path: str8) -> str8 ---
|
||||
path_split :: proc(arena: ^arena, path: str8) -> str8_list ---
|
||||
path_join :: proc(arena: ^arena, elements: str8_list) -> str8 ---
|
||||
path_append :: proc(arena: ^arena, parent: str8, relPath: str8) -> str8 ---
|
||||
path_is_absolute :: proc(path: str8) -> bool ---
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Logging
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// TODO proper odin formatted strings
|
||||
|
||||
log_level :: enum c.int {
|
||||
ERROR,
|
||||
WARNING,
|
||||
INFO,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="oc_")
|
||||
foreign {
|
||||
log_ext :: proc(
|
||||
level: log_level,
|
||||
function: cstring,
|
||||
file: cstring,
|
||||
line: c.int,
|
||||
fmt: cstring,
|
||||
#c_vararg args: ..any,
|
||||
) ---
|
||||
}
|
||||
|
||||
log_proc: [1028]u8
|
||||
log_file: [1028]u8
|
||||
|
||||
log_temp :: proc "c" (loc: runtime.Source_Code_Location) -> (function, file: cstring) {
|
||||
copy(log_proc[:], loc.procedure)
|
||||
log_proc[len(loc.procedure)] = 0
|
||||
function = cstring(&log_proc[0])
|
||||
|
||||
copy(log_file[:], loc.file_path)
|
||||
log_file[len(loc.file_path)] = 0
|
||||
file = cstring(&log_file[0])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
log_info :: proc "c" (format: cstring, args: ..any, loc := #caller_location) {
|
||||
function, file := log_temp(loc)
|
||||
// final := fmt.ctprintf(format, ..args)
|
||||
// log_ext(.INFO, function, file, loc.line, final, {})
|
||||
log_ext(.INFO, function, file, loc.line, format, {})
|
||||
}
|
||||
|
||||
log_warning :: proc "c" (format: cstring, args: ..any, loc := #caller_location) {
|
||||
function, file := log_temp(loc)
|
||||
// final := fmt.ctprintf(format, ..args)
|
||||
// log_ext(.WARNING, function, file, loc.line, final, {})
|
||||
log_ext(.WARNING, function, file, loc.line, format, {})
|
||||
}
|
||||
|
||||
log_error :: proc "c" (format: cstring, args: ..any, loc := #caller_location) {
|
||||
function, file := log_temp(loc)
|
||||
// final := fmt.ctprintf(format, ..args)
|
||||
// log_ext(.ERROR, function, file, loc.line, final, {})
|
||||
log_ext(.ERROR, function, file, loc.line, format, {})
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
//+build wasm32
|
||||
package sys_wasi
|
||||
|
||||
foreign import wasi "wasi_snapshot_preview1"
|
||||
when ODIN_OS == .Orca {
|
||||
foreign import wasi "wasi"
|
||||
} else {
|
||||
foreign import wasi "wasi_snapshot_preview1"
|
||||
}
|
||||
|
||||
DIRCOOKIE_START :: u64(0)
|
||||
size_t :: uint
|
||||
|
||||
26
core/time/time_orca.odin
Normal file
26
core/time/time_orca.odin
Normal file
@@ -0,0 +1,26 @@
|
||||
//+private
|
||||
//+build orca
|
||||
package time
|
||||
|
||||
import wasi "core:sys/wasm/wasi"
|
||||
|
||||
_IS_SUPPORTED :: false
|
||||
|
||||
_now :: proc "contextless" () -> Time {
|
||||
return {}
|
||||
}
|
||||
|
||||
_sleep :: proc "contextless" (d: Duration) {
|
||||
}
|
||||
|
||||
_tick_now :: proc "contextless" () -> Tick {
|
||||
// mul_div_u64 :: proc "contextless" (val, num, den: i64) -> i64 {
|
||||
// q := val / den
|
||||
// r := val % den
|
||||
// return q * num + r * num / den
|
||||
// }
|
||||
return {}
|
||||
}
|
||||
|
||||
_yield :: proc "contextless" () {
|
||||
}
|
||||
@@ -22,6 +22,7 @@ enum TargetOsKind : u16 {
|
||||
|
||||
TargetOs_wasi,
|
||||
TargetOs_js,
|
||||
TargetOs_orca,
|
||||
|
||||
TargetOs_freestanding,
|
||||
|
||||
@@ -83,6 +84,7 @@ gb_global String target_os_names[TargetOs_COUNT] = {
|
||||
|
||||
str_lit("wasi"),
|
||||
str_lit("js"),
|
||||
str_lit("orca"),
|
||||
|
||||
str_lit("freestanding"),
|
||||
};
|
||||
@@ -583,6 +585,14 @@ gb_global TargetMetrics target_wasi_wasm32 = {
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_orca_wasm32 = {
|
||||
TargetOs_orca,
|
||||
TargetArch_wasm32,
|
||||
4, 4, 8, 16,
|
||||
str_lit("wasm32-wasi-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
|
||||
gb_global TargetMetrics target_freestanding_wasm64p32 = {
|
||||
TargetOs_freestanding,
|
||||
@@ -655,6 +665,7 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
|
||||
{ str_lit("wasi_wasm32"), &target_wasi_wasm32 },
|
||||
{ str_lit("js_wasm32"), &target_js_wasm32 },
|
||||
{ str_lit("orca_wasm32"), &target_orca_wasm32 },
|
||||
|
||||
{ str_lit("freestanding_wasm64p32"), &target_freestanding_wasm64p32 },
|
||||
{ str_lit("js_wasm64p32"), &target_js_wasm64p32 },
|
||||
@@ -1513,9 +1524,12 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
// if (bc->metrics.arch == TargetArch_wasm64) {
|
||||
// link_flags = gb_string_appendc(link_flags, "-mwasm64 ");
|
||||
// }
|
||||
if (bc->no_entry_point) {
|
||||
if (bc->no_entry_point || bc->metrics.os == TargetOs_orca) {
|
||||
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
||||
}
|
||||
|
||||
// in case orca target was
|
||||
bc->no_entry_point = true;
|
||||
}
|
||||
|
||||
bc->link_flags = make_string_c(link_flags);
|
||||
|
||||
|
||||
@@ -1015,6 +1015,7 @@ gb_internal void init_universal(void) {
|
||||
{"WASI", TargetOs_wasi},
|
||||
{"JS", TargetOs_js},
|
||||
{"Freestanding", TargetOs_freestanding},
|
||||
{"Orca", TargetOs_orca},
|
||||
};
|
||||
|
||||
auto fields = add_global_enum_type(str_lit("Odin_OS_Type"), values, gb_count_of(values));
|
||||
|
||||
@@ -69,15 +69,20 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
if (is_arch_wasm()) {
|
||||
timings_start_section(timings, str_lit("wasm-ld"));
|
||||
|
||||
String extra_orca_flags = {};
|
||||
if (build_context.metrics.os == TargetOs_orca) {
|
||||
extra_orca_flags = str_lit(" -L . -lorca --export-dynamic");
|
||||
}
|
||||
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s",
|
||||
"\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s %.*s",
|
||||
LIT(build_context.ODIN_ROOT),
|
||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), LIT(extra_orca_flags));
|
||||
#else
|
||||
result = system_exec_command_line_app("wasm-ld",
|
||||
"wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s",
|
||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags));
|
||||
"wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s %.*s",
|
||||
LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), LIT(extra_orca_flags));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user