From: Brendan Hansen Date: Mon, 21 Sep 2020 01:13:33 +0000 (-0500) Subject: loading font data, woop! X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=cd88ea48c607c0d7df66ad2824e4efa54cf55bae;p=onyx-game.git loading font data, woop! --- diff --git a/build.sh b/build.sh index d66a9bb..37baa37 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,3 @@ #!/bin/sh -onyx doc src/main.onyx -onyx src/main.onyx \ No newline at end of file +onyx src/main.onyx && onyx doc src/main.onyx diff --git a/res/Inconsolata-Regular.ttf b/res/Inconsolata-Regular.ttf new file mode 100644 index 0000000..e329bbc Binary files /dev/null and b/res/Inconsolata-Regular.ttf differ diff --git a/src/font.onyx b/src/font.onyx new file mode 100644 index 0000000..4617dac --- /dev/null +++ b/src/font.onyx @@ -0,0 +1,372 @@ +package ttf_font + +use package core +use package vecmath + +// Very proud of how small this function can be using slices +// However, it should be turned into a non-recursive solution +// since this runs in factorial time. +bezier_curve :: proc (t: f32, ps: [] V2f) -> V2f { + if ps.count == 1 do return ps[0]; + + ret := V2f.{ 0.0f, 0.0f }; + ret = v2_add(ret, v2_mul(bezier_curve(t, ps.data[0 .. ps.count - 1]), 1.0f - t)); + ret = v2_add(ret, v2_mul(bezier_curve(t, ps.data[1 .. ps.count]), t)); + return ret; +} + +BinaryReader :: struct { + data : [] u8; + pos : u32; +} + +binary_reader_create :: proc (data: [] u8, initial_pos := 0) -> BinaryReader { + return BinaryReader.{ data = data, pos = initial_pos }; +} + +#private_file seek :: proc (use br: ^BinaryReader, new_pos: u32) -> u32 { + old_pos :: pos; + pos = new_pos; + return old_pos; +} + +#private_file tell :: proc (use br: ^BinaryReader) -> u32 do return pos; + +#private_file read_u8 :: proc (use br: ^BinaryReader) -> u8 { + ret := data[pos]; + pos += 1; + return ret; +} + +#private_file read_u16 :: proc (use br: ^BinaryReader) -> u16 do return ~~(read_u8(br) << ~~8 | read_u8(br)); + +#private_file read_u32 :: proc (use br: ^BinaryReader) -> u32 { + // Encoding is big endian + ret := 0; + ret |= ~~read_u8(br) << 24; + ret |= ~~read_u8(br) << 16; + ret |= ~~read_u8(br) << 8; + ret |= ~~read_u8(br); + return ret; +} + +#private_file read_i16 :: proc (use br: ^BinaryReader) -> i16 { + ret := read_u16(br); + if ret & ~~0x8000 != ~~0 do ret -= ~~(1 << 16); + return ret; +} + +#private_file read_i32 :: proc (use br: ^BinaryReader) -> i32 { + return ~~read_u32(br); +} + +#private_file read_fword :: proc (use br: ^BinaryReader) -> i16 do return read_i16(br); + +#private_file read_2dot14 :: proc (use br: ^BinaryReader) -> f32 { + val := cast(i32) read_i16(br); + return ~~val / cast(f32) (1 << 14); +} + +#private_file read_fixed :: proc (use br: ^BinaryReader) -> f32 { + val := read_i32(br); + return ~~val / cast(f32) (1 << 16); +} + +#private_file read_string :: proc (use br: ^BinaryReader, len: i32) -> string { + ret := data.data[pos .. pos + len]; + pos += len; + return ret; +} + +// NOT IMPLEMENTED +#private_file read_date :: proc (use br: ^BinaryReader) -> u64 { + pos += 8; + return ~~0; +} + + + + + +TrueTypeFont :: struct { + reader: BinaryReader; + + // NOTE: I don't know how useful these are, but they're at + // the beginning of the ttf file. + scalar_type : u32; + search_range : u16; + entry_selector : u16; + range_shift : u16; + + table_map : I32Map(TTTableInfo); + + version : u32; + font_revision : u32; + checksum_adjustment : u32; + magic_number : u32; + flags : u16; + units_per_em : u16; + // created : u64; + // modified : u64; + x_min : i16; + x_max : i16; + y_min : i16; + y_max : i16; + mac_style : u16; + lowest_rec_ppem : u16; + font_direction_hint : i16; + index_to_loc_format : TTIndexToLocFormat; + glyph_data_format : i16; +} + +TTTableInfo :: struct { + checksum : u32 = 0; + offset : u32 = 0; + length : u32 = 0; +} + +TTIndexToLocFormat :: enum (i16) { + Short :: 0x00; + Long :: 0x01; +} + +TTGlyph :: struct { + contour_count : i16; + x_min : i16; + x_max : i16; + y_min : i16; + y_max : i16; + + points : [..] TTGlyphPoint; + contour_ends : [..] u16; +} + +TTGlyphPoint :: struct { + on_curve : bool; + x : i16 = ~~0; + y : i16 = ~~0; +} + +ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont { + ttf : TrueTypeFont; + ttf.reader = binary_reader_create(ttf_data); + i32map_init(^ttf.table_map); + + return ttf; +} + +ttf_read_offset_table :: proc (use ttf: ^TrueTypeFont) { + scalar_type = read_u32(^reader); + num_tables := read_u16(^reader); + search_range = read_u16(^reader); + entry_selector = read_u16(^reader); + range_shift = read_u16(^reader); + + for i: 0 .. ~~num_tables { + tag := read_string(^reader, 4); + tag_int := string_to_beu32(tag); + println(tag); + + table_info : TTTableInfo; + table_info.checksum = read_u32(^reader); + table_info.offset = read_u32(^reader); + table_info.length = read_u32(^reader); + + i32map_put(^table_map, tag_int, table_info); + + if !string_equal(tag, "head") { + // TODO: Calculate checksum to ensure everything looks right + csum := ttf_calc_table_checksum(^reader, table_info.offset, table_info.length); + if table_info.checksum != csum { + print("WARNING: Checksum for table '"); + print(tag); + print("' did not match."); + } + } + } +} + +ttf_read_head_table :: proc (use ttf: ^TrueTypeFont) { + empty_table_hack := TTTableInfo.{}; + head_table_info := i32map_get(^table_map, string_to_beu32("head"), empty_table_hack); + seek(^reader, head_table_info.offset); + + version = read_u32(^reader); + font_revision = read_u32(^reader); + checksum_adjustment = read_u32(^reader); + magic_number = read_u32(^reader); // NOTE: Should be 0x5f0f3cf5 + flags = read_u16(^reader); + units_per_em = read_u16(^reader); + read_date(^reader); // created + read_date(^reader); // modified + x_min = read_fword(^reader); + y_min = read_fword(^reader); + x_max = read_fword(^reader); + y_max = read_fword(^reader); + mac_style = read_u16(^reader); + lowest_rec_ppem = read_u16(^reader); + font_direction_hint = read_i16(^reader); + index_to_loc_format = cast(TTIndexToLocFormat) read_i16(^reader); + glyph_data_format = read_i16(^reader); +} + +ttf_lookup_glyph_offset :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> u32 { + empty_table_hack := TTTableInfo.{}; + loca_table_info := i32map_get(^table_map, string_to_beu32("loca"), empty_table_hack); + glyf_table_info := i32map_get(^table_map, string_to_beu32("glyf"), empty_table_hack); + + old: u32; + defer seek(^reader, old); + + switch index_to_loc_format { + case TTIndexToLocFormat.Long { + old = seek(^reader, loca_table_info.offset + glyph_index * 4); + return read_u32(^reader) + glyf_table_info.offset; + } + + case #default { + old = seek(^reader, loca_table_info.offset + glyph_index * 2); + return 2 * ~~read_u16(^reader) + glyf_table_info.offset; + } + } + + return -1; +} + +// Result is expected to be freed +ttf_read_glyph :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> ^TTGlyph { + offset := ttf_lookup_glyph_offset(ttf, glyph_index); + + empty_table_hack := TTTableInfo.{}; + glyf_table_info := i32map_get(^table_map, string_to_beu32("glyf"), empty_table_hack); + + if offset >= glyf_table_info.offset + glyf_table_info.length do return null; + + seek(^reader, offset); + + glyph := cast(^TTGlyph) calloc(sizeof TTGlyph); + glyph.contour_count = read_i16(^reader); + glyph.x_min = read_fword(^reader); + glyph.y_min = read_fword(^reader); + glyph.x_max = read_fword(^reader); + glyph.y_max = read_fword(^reader); + + if glyph.contour_count < ~~0 { cfree(glyph); return null; } + if glyph.contour_count == ~~ -1 { + // Compound glyph + return null; + } else { + // Simple glyph + ttf_read_simple_glyph(ttf, glyph); + } + + return glyph; +} + +#private_file +TTGlyphFlags :: enum #flags { + On_Curve :: 0x01; + X_Is_Byte :: 0x2; + Y_Is_Byte :: 0x4; + Repeat :: 0x8; + X_Delta :: 0x10; + Y_Delta :: 0x20; +} + +#private_file +ttf_read_simple_glyph :: proc (use ttf: ^TrueTypeFont, glyph: ^TTGlyph) { + array_init(^glyph.contour_ends, ~~glyph.contour_count); + array_init(^glyph.points); + + for i: 0 .. ~~glyph.contour_count { + array_push(^glyph.contour_ends, read_u16(^reader)); + } + + seek(^reader, ~~read_u16(^reader) + tell(^reader)); + + if glyph.contour_count == ~~0 do return; + + num_points := array_fold(^glyph.contour_ends, cast(u16) 0, max_poly) + ~~1; + + flags : [..] TTGlyphFlags; + array_init(^flags); + defer array_free(^flags); + + for i: 0 .. ~~num_points { + flag := cast(TTGlyphFlags) read_u8(^reader); + array_push(^flags, flag); + array_push(^glyph.points, TTGlyphPoint.{ on_curve = (flag & TTGlyphFlags.On_Curve) != ~~0 }); + + if (flag & TTGlyphFlags.Repeat) != ~~0 { + rep_count := read_u8(^reader); + i += ~~rep_count; + for i: 0 .. ~~rep_count { + array_push(^flags, flag); + array_push(^glyph.points, TTGlyphPoint.{ on_curve = (flag & TTGlyphFlags.On_Curve) != ~~0 }); + } + } + } + + value := cast(i16) 0; + for i: 0 .. ~~num_points { + flag := flags[i]; + + if (flag & TTGlyphFlags.X_Is_Byte) != ~~0 { + if (flag & TTGlyphFlags.X_Delta) != ~~0 { + value += ~~read_u8(^reader); + } else { + value -= ~~read_u8(^reader); + } + } elseif (flag & TTGlyphFlags.X_Delta) == ~~0 { + value += read_i16(^reader); + } + + glyph.points[i].x = value; + } + + value = cast(i16) 0; + for i: 0 .. ~~num_points { + flag := flags[i]; + + if (flag & TTGlyphFlags.Y_Is_Byte) != ~~0 { + if (flag & TTGlyphFlags.Y_Delta) != ~~0 { + value += ~~read_u8(^reader); + } else { + value -= ~~read_u8(^reader); + } + } elseif (flag & TTGlyphFlags.Y_Delta) == ~~0 { + value += read_i16(^reader); + } + + glyph.points[i].y = value; + } +} + + +ttf_glyph_count :: proc (use ttf: ^TrueTypeFont) -> u32 { + empty_table_hack := TTTableInfo.{}; + maxp_table_info := i32map_get(^table_map, string_to_beu32("maxp"), empty_table_hack); + old := seek(^reader, maxp_table_info.offset + 4); + defer seek(^reader, old); + + return ~~read_u16(^reader); +} + +#private_file +ttf_calc_table_checksum :: proc (reader: ^BinaryReader, offset: u32, length: u32) -> u32 { + old := seek(reader, offset); + defer seek(reader, old); + + sum := 0; + nlongs := (length + 3) >> 2; + for i: 0 .. nlongs do sum += read_u32(reader); + return sum; +} + +#private_file +string_to_beu32 :: proc (s: string) -> u32 { + return (~~s[0] << 24) + | (~~s[1] << 16) + | (~~s[2] << 8) + | (~~s[3]); +} diff --git a/src/gfx/quad_renderer.onyx b/src/gfx/quad_renderer.onyx index 9191818..64a1c87 100644 --- a/src/gfx/quad_renderer.onyx +++ b/src/gfx/quad_renderer.onyx @@ -28,13 +28,13 @@ QuadRenderer :: struct { Color4f32 :: struct { r: f32; g: f32; b: f32; a: f32; } Quad :: struct { - pos : Vec2; - size : Vec2; + pos : Vec2 = Vec2.{ 0f, 0f }; + size : Vec2 = Vec2.{ 0f, 0f }; - tex_pos : Vec2; - tex_size : Vec2; + tex_pos : Vec2 = Vec2.{ 0f, 0f }; + tex_size : Vec2 = Vec2.{ 0f, 0f }; - color : Color4f32; + color : Color4f32 = Color4f32.{ 0f, 0f, 0f, 0f }; } quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) { @@ -61,12 +61,7 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) { array_init(^quad_data, initial_quads); - default_quad : Quad; - default_quad.pos = Vec2.{ 0.0f, 0.0f }; - default_quad.size = Vec2.{ 0.0f, 0.0f }; - default_quad.tex_pos = Vec2.{ 0.0f, 0.0f }; - default_quad.tex_size = Vec2.{ 0.0f, 0.0f }; - default_quad.color = Color4f32.{ 0.0f, 0.0f, 0.0f, 0.0f }; + default_quad := Quad.{}; for i: 0 .. initial_quads { array_push(^quad_data, default_quad); } diff --git a/src/main.onyx b/src/main.onyx index 099623c..974ea10 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -9,21 +9,76 @@ package main #include_file "gfx/texture" #include_file "events" #include_file "input" +#include_file "font" +#include_file "vecmath" use package core use package gfx use package gl as gl use package event as event use package input as input { Key } +use package vecmath +use package ttf_font + +NUM_QUADS :: 1 << 10 + + + +RenderContext :: struct { + quad_renderer: ^QuadRenderer; + + curr_quad_idx: i32 = 0; + max_quad_idx: i32 = 0; + + // @CLEANUP Allow for the syntax: + // color := Color4f32.{ ... } + // OR + // color: Color4f32 = .{ ... } + color: Color4f32 = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f }; +} + +render_context_init :: proc (use rc: ^RenderContext, qr: ^QuadRenderer = null) { + aqr := qr; + + if aqr == null { + aqr = calloc(sizeof QuadRenderer); + quad_renderer_init(aqr, NUM_QUADS); + } + + *rc = RenderContext.{ + quad_renderer = aqr, + max_quad_idx = qr.quad_data.count, + }; +} + +draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) { + if curr_quad_idx >= max_quad_idx do return; + + quad_update_at_index(quad_renderer, curr_quad_idx, Quad.{ + pos = Vec2.{ x, y }, + size = Vec2.{ w, h }, + color = color, + }); + + curr_quad_idx += 1; +} + +render_context_flush :: proc (use rc: ^RenderContext) { + quad_rebuffer_data(quad_renderer); + quad_renderer_draw(quad_renderer); + + curr_quad_idx = 0; +} + -NUM_QUADS :: 1 << 7 // @Cleanup window_width := 0 window_height := 0 -quad_renderer : QuadRenderer +renderer : RenderContext input_state : input.InputState +ttf : TrueTypeFont Player :: struct { use pos : Vec2; } player : Player @@ -47,7 +102,7 @@ poll_events :: proc () { gl.canvasSize(window_width, window_height); gl.viewport(0, 0, window_width, window_height); - quad_renderer_update_view(^quad_renderer); + quad_renderer_update_view(renderer.quad_renderer); } } } @@ -63,34 +118,46 @@ update :: proc () { if input.key_down(^input_state, Key.ArrowDown) do player.y += player_speed; if input.key_down(^input_state, Key.ArrowLeft) do player.x -= player_speed; if input.key_down(^input_state, Key.ArrowRight) do player.x += player_speed; +} - quad_update_at_index(^quad_renderer, NUM_QUADS - 1, Quad.{ - pos = Vec2.{ ~~input_state.mouse.x, ~~input_state.mouse.y }, - size = Vec2.{ 32.0f, 32.0f }, +draw :: proc () { + defer render_context_flush(^renderer); - tex_pos = Vec2.{ 0.25f, 0.25f }, - tex_size = Vec2.{ 0.25f, 0.25f }, + gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f); + gl.clear(gl.COLOR_BUFFER_BIT); - color = Color4f32.{ 1.0f, 0.0f, 0.0f, 0.5f }, - }); + renderer.color = Color4f32.{ 1f, 0f, 0f, 1f }; - quad_update_at_index(^quad_renderer, 0, Quad.{ - pos = player.pos, - size = Vec2.{ 100.0f, 100.0f }, - tex_pos = Vec2.{ 0.0f, 0.0f }, - tex_size = Vec2.{ 1.0f, 1.0f }, + // points : [6] V2f; + // points[0] = V2f.{ 500.0f, 700.0f }; + // points[1] = V2f.{ 600.0f, 200.0f }; + // points[2] = V2f.{ 700.0f, 400.0f }; + // points[3] = V2f.{ 1700.0f, 800.0f }; + // points[4] = V2f.{ 1800.0f, 400.0f }; + // points[5] = V2f.{ 1000.0f, 200.0f }; - color = Color4f32.{ 0.0f, 0.0f, 1.0f, 1.0f }, - }); -} + // for i: 0 .. 200 { + // pos := bezier_curve(~~i / 200.0f, points[0 .. 6]); + // draw_rect(^renderer, pos.x, pos.y, 16f, 16f); + // } -draw :: proc () { - gl.clearColor(0.1f, 0.1f, 0.1f, 1.0f); - gl.clear(gl.COLOR_BUFFER_BIT); + glyph : ^TTGlyph = null; + idx := 230; + while glyph == null { + glyph = ttf_read_glyph(^ttf, idx); + idx += 1; + } + defer cfree(glyph); + + rx := 100.0f / ~~ cast(i32) (glyph.x_max - glyph.x_min); + ry := 100.0f / ~~ cast(i32) (glyph.y_min - glyph.y_max); + for p: glyph.points { + draw_rect(^renderer, ~~ cast(i32) p.x * rx + 100f, ~~ cast(i32) p.y * ry + 100f, 10f, 10f); + } - quad_rebuffer_data(^quad_renderer); - quad_renderer_draw(^quad_renderer); + draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f); + draw_rect(^renderer, player.pos.x, player.pos.y, 100f, 100f); } // This procedure is called asynchronously from JS every frame. @@ -113,15 +180,13 @@ main :: proc (args: [] cstring) { gl.enable(gl.BLEND); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - quad_renderer_init(^quad_renderer, NUM_QUADS); + render_context_init(^renderer, null); // CLEANUP: Maybe there should be a way to cast between slices? // Automatically multiply / divide the count by the ratio of the type sizes? // This could be very buggy - image_data : [] Color3; raw_image_data := #file_contents "res/smile.data"; - image_data.data = cast(^Color3) raw_image_data.data; - image_data.count = raw_image_data.count / 3; + image_data := (cast(^Color3) raw_image_data.data)[0 .. raw_image_data.count / 3]; smile := texture_create(image_data, 32, 32); texture_prepare(^smile); @@ -130,6 +195,27 @@ main :: proc (args: [] cstring) { event.init(); input.init(^input_state); + ttf_data := #file_contents "res/Inconsolata-Regular.ttf"; + ttf = ttf_create(ttf_data); + ttf_read_offset_table(^ttf); + ttf_read_head_table(^ttf); + + // for i: 0 .. ttf_glyph_count(^ttf) { + // glyph := ttf_read_glyph(^ttf, i); + // if glyph == null do continue; + // defer cfree(glyph); + + // // println(glyph.points.count); + // // for p: glyph.points { + // // print(p.on_curve); + // // print(" "); + // // print(cast(i32) p.x); + // // print(", "); + // // print(cast(i32) p.y); + // // print("\n"); + // // } + // } + game_launch(); } diff --git a/src/vecmath.onyx b/src/vecmath.onyx new file mode 100644 index 0000000..0d638e0 --- /dev/null +++ b/src/vecmath.onyx @@ -0,0 +1,28 @@ +package vecmath + +// BUG: Default values do not work on polymorphic structs. +V2 :: struct ($T) { x: T; y: T; } + +V2f :: #type V2(f32); +V2i :: #type V2(i32); + +v2_add :: proc (a: V2($T), b: V2(T)) -> V2(T) { + ret : V2(T); + ret.x = a.x + b.x; + ret.y = a.y + b.y; + return ret; +} + +v2_sub :: proc (a: V2($T), b: V2(T)) -> V2(T) { + ret : V2(T); + ret.x = a.x - b.x; + ret.y = a.y - b.y; + return ret; +} + +v2_mul :: proc (a: V2($T), scalar: T) -> V2(T) { + ret : V2(T); + ret.x = a.x * scalar; + ret.y = a.y * scalar; + return ret; +} diff --git a/tags b/tags index c4c1d1f..dc7befa 100644 --- a/tags +++ b/tags @@ -42,6 +42,7 @@ BROWSER_DEFAULT_WEBGL /usr/share/onyx/core/js/webgl.onyx /^BROWSER_DEFAULT_WEBGL BUFFER_SIZE /usr/share/onyx/core/js/webgl.onyx /^BUFFER_SIZE :: 0x8764$/ BUFFER_USAGE /usr/share/onyx/core/js/webgl.onyx /^BUFFER_USAGE :: 0x8765$/ BYTE /usr/share/onyx/core/js/webgl.onyx /^BYTE :: 0x1400$/ +BinaryReader src/font.onyx /^BinaryReader :: struct {$/ Buffer /usr/share/onyx/core/builtin.onyx /^Buffer :: #type []void;$/ CCW /usr/share/onyx/core/js/webgl.onyx /^CCW :: 0x0901$/ CLAMP_TO_EDGE /usr/share/onyx/core/js/webgl.onyx /^CLAMP_TO_EDGE :: 0x812F$/ @@ -308,7 +309,7 @@ NICEST /usr/share/onyx/core/js/webgl.onyx /^NICEST :: 0x NONE /usr/share/onyx/core/js/webgl.onyx /^NONE :: 0$/ NOTEQUAL /usr/share/onyx/core/js/webgl.onyx /^NOTEQUAL :: 0x0205$/ NO_ERROR /usr/share/onyx/core/js/webgl.onyx /^NO_ERROR :: 0$/ -NUM_QUADS src/main.onyx /^NUM_QUADS :: 1 << 7$/ +NUM_QUADS src/main.onyx /^NUM_QUADS :: 1 << 10$/ OBJECT_TYPE /usr/share/onyx/core/js/webgl.onyx /^OBJECT_TYPE :: 0x9112$/ ONE /usr/share/onyx/core/js/webgl.onyx /^ONE :: 1$/ ONE_MINUS_CONSTANT_ALPHA /usr/share/onyx/core/js/webgl.onyx /^ONE_MINUS_CONSTANT_ALPHA :: 0x8004$/ @@ -413,6 +414,7 @@ RGBA8_SNORM /usr/share/onyx/core/js/webgl.onyx /^RGBA8_SNORM RGBA_INTEGER /usr/share/onyx/core/js/webgl.onyx /^RGBA_INTEGER :: 0x8D99$/ RGB_INTEGER /usr/share/onyx/core/js/webgl.onyx /^RGB_INTEGER :: 0x8D98$/ RG_INTEGER /usr/share/onyx/core/js/webgl.onyx /^RG_INTEGER :: 0x8228$/ +RenderContext src/main.onyx /^RenderContext :: struct {$/ ResizeEvent src/events.onyx /^ResizeEvent :: struct {$/ SAMPLER_2D /usr/share/onyx/core/js/webgl.onyx /^SAMPLER_2D :: 0x8B5E$/ SAMPLER_2D_ARRAY /usr/share/onyx/core/js/webgl.onyx /^SAMPLER_2D_ARRAY :: 0x8DC1$/ @@ -556,7 +558,12 @@ TRANSFORM_FEEDBACK_VARYINGS /usr/share/onyx/core/js/webgl.onyx /^TRANSFORM_FEEDB TRIANGLES /usr/share/onyx/core/js/webgl.onyx /^TRIANGLES :: 0x0004$/ TRIANGLE_FAN /usr/share/onyx/core/js/webgl.onyx /^TRIANGLE_FAN :: 0x0006$/ TRIANGLE_STRIP /usr/share/onyx/core/js/webgl.onyx /^TRIANGLE_STRIP :: 0x0005$/ +TTGlyph src/font.onyx /^TTGlyph :: struct {$/ +TTGlyphPoint src/font.onyx /^TTGlyphPoint :: struct {$/ +TTIndexToLocFormat src/font.onyx /^TTIndexToLocFormat :: enum (i16) {$/ +TTTableInfo src/font.onyx /^TTTableInfo :: struct {$/ Texture src/gfx/texture.onyx /^Texture :: struct {$/ +TrueTypeFont src/font.onyx /^TrueTypeFont :: struct {$/ UNIFORM_ARRAY_STRIDE /usr/share/onyx/core/js/webgl.onyx /^UNIFORM_ARRAY_STRIDE :: 0x8A3C$/ UNIFORM_BLOCK_ACTIVE_UNIFORMS /usr/share/onyx/core/js/webgl.onyx /^UNIFORM_BLOCK_ACTIVE_UNIFORMS :: 0x8A42$/ UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES /usr/share/onyx/core/js/webgl.onyx /^UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES :: 0x8A43$/ @@ -603,6 +610,9 @@ UNSIGNED_SHORT /usr/share/onyx/core/js/webgl.onyx /^UNSIGNED_SHORT UNSIGNED_SHORT_4_4_4_4 /usr/share/onyx/core/js/webgl.onyx /^UNSIGNED_SHORT_4_4_4_4 :: 0x8033$/ UNSIGNED_SHORT_5_5_5_1 /usr/share/onyx/core/js/webgl.onyx /^UNSIGNED_SHORT_5_5_5_1 :: 0x8034$/ UNSIGNED_SHORT_5_6_5 /usr/share/onyx/core/js/webgl.onyx /^UNSIGNED_SHORT_5_6_5 :: 0x8363$/ +V2 src/vecmath.onyx /^V2 :: struct ($T) { x: T; y: T; }$/ +V2f src/vecmath.onyx /^V2f :: #type V2(f32);$/ +V2i src/vecmath.onyx /^V2i :: #type V2(i32);$/ VALIDATE_STATUS /usr/share/onyx/core/js/webgl.onyx /^VALIDATE_STATUS :: 0x8B83$/ VENDOR /usr/share/onyx/core/js/webgl.onyx /^VENDOR :: 0x1F00$/ VERSION /usr/share/onyx/core/js/webgl.onyx /^VERSION :: 0x1F02$/ @@ -646,6 +656,8 @@ array_remove /usr/share/onyx/core/array.onyx /^array_remove :: proc (arr: ^[..] array_sort /usr/share/onyx/core/array.onyx /^array_sort :: proc (arr: ^[..] $T, cmp: proc (T, T) -> i32) {$/ array_to_slice /usr/share/onyx/core/array.onyx /^array_to_slice :: proc (arr: ^[..] $T) -> [] T {$/ attachShader /usr/share/onyx/core/js/webgl.onyx /^attachShader :: proc (program: GLProgram, shader: GLShader) -> GLProgram #foreign "gl" "attachShader" ---$/ +bezier_curve src/font.onyx /^bezier_curve :: proc (t: f32, ps: [] V2f) -> V2f {$/ +binary_reader_create src/font.onyx /^binary_reader_create :: proc (data: [] u8, initial_pos := 0) -> BinaryReader {$/ bindAttribLocation /usr/share/onyx/core/js/webgl.onyx /^bindAttribLocation :: proc (program: GLProgram, index: GLuint, name: string) #foreign "gl" "bindAttribLocation" ---$/ bindBuffer /usr/share/onyx/core/js/webgl.onyx /^bindBuffer :: proc (target: GLenum, buffer: GLBuffer) #foreign "gl" "bindBuffer" ---$/ bindFramebuffer /usr/share/onyx/core/js/webgl.onyx /^bindFramebuffer :: proc (target: GLenum, framebuffer: GLFramebuffer) #foreign "gl" "bindFramebuffer" ---$/ @@ -719,6 +731,7 @@ drawArrays /usr/share/onyx/core/js/webgl.onyx /^drawArrays : drawArraysInstanced /usr/share/onyx/core/js/webgl.onyx /^drawArraysInstanced :: proc (mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei) #foreign "gl" "drawArraysInstanced" ---$/ drawElements /usr/share/onyx/core/js/webgl.onyx /^drawElements :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint) #foreign "gl" "drawElements" ---$/ drawElementsInstanced /usr/share/onyx/core/js/webgl.onyx /^drawElementsInstanced :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint, instanceCount: GLsizei) #foreign "gl" "drawElementsInstanced" ---$/ +draw_rect src/main.onyx /^draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) {$/ enable /usr/share/onyx/core/js/webgl.onyx /^enable :: proc (cap: GLenum) #foreign "gl" "enable" ---$/ enableVertexAttribArray /usr/share/onyx/core/js/webgl.onyx /^enableVertexAttribArray :: proc (index: GLuint) #foreign "gl" "enableVertexAttribArray" ---$/ finish /usr/share/onyx/core/js/webgl.onyx /^finish :: proc () #foreign "gl" "finish" ---$/ @@ -775,12 +788,14 @@ link_program src/utils/gl.onyx /^link_program :: proc (vertex_shader: gl.GLShade main src/main.onyx /^main :: proc (args: [] cstring) {$/ max_f32 /usr/share/onyx/core/intrinsics.onyx /^max_f32 :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/ max_f64 /usr/share/onyx/core/intrinsics.onyx /^max_f64 :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/ +max_poly /usr/share/onyx/core/math.onyx /^max_poly :: proc (a: $T, b: T) -> T {$/ memory_copy /usr/share/onyx/core/memory.onyx /^memory_copy :: proc (dst_: rawptr, src_: rawptr, len: u32) {$/ memory_grow /usr/share/onyx/core/intrinsics.onyx /^memory_grow :: proc (val: i32) -> i32 #intrinsic ---$/ memory_init /usr/share/onyx/core/alloc.onyx /^memory_init :: proc () {$/ memory_size /usr/share/onyx/core/intrinsics.onyx /^memory_size :: proc () -> i32 #intrinsic ---$/ min_f32 /usr/share/onyx/core/intrinsics.onyx /^min_f32 :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/ min_f64 /usr/share/onyx/core/intrinsics.onyx /^min_f64 :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/ +min_poly /usr/share/onyx/core/math.onyx /^min_poly :: proc (a: $T, b: T) -> T {$/ nearest_f32 /usr/share/onyx/core/intrinsics.onyx /^nearest_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ nearest_f64 /usr/share/onyx/core/intrinsics.onyx /^nearest_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ new_frame_callback src/main.onyx /^new_frame_callback :: proc () #export {$/ @@ -819,7 +834,6 @@ ptrmap_has /usr/share/onyx/core/ptrmap.onyx /^ptrmap_has :: proc (use pmap: ^Ptr ptrmap_init /usr/share/onyx/core/ptrmap.onyx /^ptrmap_init :: proc (use pmap: ^PtrMap, hash_count: i32 = 16) {$/ ptrmap_put /usr/share/onyx/core/ptrmap.onyx /^ptrmap_put :: proc (use pmap: ^PtrMap, key: rawptr, value: rawptr) {$/ quad_rebuffer_data src/gfx/quad_renderer.onyx /^quad_rebuffer_data :: proc (use qr: ^QuadRenderer) {$/ -quad_renderer src/main.onyx /^quad_renderer : QuadRenderer$/ quad_renderer_draw src/gfx/quad_renderer.onyx /^quad_renderer_draw :: proc (use qr: ^QuadRenderer) {$/ quad_renderer_init src/gfx/quad_renderer.onyx /^quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {$/ quad_renderer_update_view src/gfx/quad_renderer.onyx /^quad_renderer_update_view :: proc (use qr: ^QuadRenderer) {$/ @@ -831,7 +845,10 @@ random_seed /usr/share/onyx/core/random.onyx /^random_seed :: proc (s: u32) do s range /usr/share/onyx/core/builtin.onyx /^range :: struct {$/ readBuffer /usr/share/onyx/core/js/webgl.onyx /^readBuffer :: proc (src: GLenum) #foreign "gl" "readBuffer" ---$/ readPixels /usr/share/onyx/core/js/webgl.onyx /^readPixels :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "readPixels" ---$/ +render_context_flush src/main.onyx /^render_context_flush :: proc (use rc: ^RenderContext) {$/ +render_context_init src/main.onyx /^render_context_init :: proc (use rc: ^RenderContext, qr: ^QuadRenderer = null) {$/ renderbufferStorageMultisample /usr/share/onyx/core/js/webgl.onyx /^renderbufferStorageMultisample :: proc (target: GLenum, samples: GLsizei, internalforamt: GLenum, width: GLsizei, height: GLsizei) #foreign "gl" "renderbufferStorageMultisample" ---$/ +renderer src/main.onyx /^renderer : RenderContext$/ resize /usr/share/onyx/core/builtin.onyx /^resize :: proc (use a: Allocator, ptr: rawptr, size: u32) -> rawptr {$/ rotl_i32 /usr/share/onyx/core/intrinsics.onyx /^rotl_i32 :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/ rotl_i64 /usr/share/onyx/core/intrinsics.onyx /^rotl_i64 :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/ @@ -872,6 +889,7 @@ string_builder_make /usr/share/onyx/core/string.onyx /^string_builder_make :: pr string_builder_to_string /usr/share/onyx/core/string.onyx /^string_builder_to_string :: proc (use sb: ^StringBuilder) -> string {$/ string_concat /usr/share/onyx/core/string.onyx /^string_concat :: proc (s1: string, s2: string) -> string {$/ string_contains /usr/share/onyx/core/string.onyx /^string_contains :: proc (str: string, c: u8) -> bool {$/ +string_equal /usr/share/onyx/core/string.onyx /^string_equal :: proc (str1: string, str2: string) -> bool {$/ string_free /usr/share/onyx/core/string.onyx /^string_free :: proc (s: string) do cfree(s.data);$/ string_length /usr/share/onyx/core/string.onyx /^string_length :: proc {$/ string_make /usr/share/onyx/core/string.onyx /^string_make :: proc (s: cstring) -> string {$/ @@ -892,6 +910,13 @@ texture_prepare src/gfx/texture.onyx /^texture_prepare :: proc (use tex: ^Textur texture_use src/gfx/texture.onyx /^texture_use :: proc (use tex: ^Texture) {$/ trunc_f32 /usr/share/onyx/core/intrinsics.onyx /^trunc_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ trunc_f64 /usr/share/onyx/core/intrinsics.onyx /^trunc_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ +ttf src/main.onyx /^ttf : TrueTypeFont$/ +ttf_create src/font.onyx /^ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont {$/ +ttf_glyph_count src/font.onyx /^ttf_glyph_count :: proc (use ttf: ^TrueTypeFont) -> u32 {$/ +ttf_lookup_glyph_offset src/font.onyx /^ttf_lookup_glyph_offset :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> u32 {$/ +ttf_read_glyph src/font.onyx /^ttf_read_glyph :: proc (use ttf: ^TrueTypeFont, glyph_index: i32) -> ^TTGlyph {$/ +ttf_read_head_table src/font.onyx /^ttf_read_head_table :: proc (use ttf: ^TrueTypeFont) {$/ +ttf_read_offset_table src/font.onyx /^ttf_read_offset_table :: proc (use ttf: ^TrueTypeFont) {$/ uniform1f /usr/share/onyx/core/js/webgl.onyx /^uniform1f :: proc (loc: GLUniformLocation, x: GLfloat) #foreign "gl" "uniform1f" ---$/ uniform1i /usr/share/onyx/core/js/webgl.onyx /^uniform1i :: proc (loc: GLUniformLocation, x: GLint) #foreign "gl" "uniform1i" ---$/ uniform2f /usr/share/onyx/core/js/webgl.onyx /^uniform2f :: proc (loc: GLUniformLocation, x: GLfloat, y: GLfloat) #foreign "gl" "uniform2f" ---$/ @@ -905,6 +930,9 @@ uniformMatrix3 /usr/share/onyx/core/js/webgl.onyx /^uniformMatrix3 uniformMatrix4 /usr/share/onyx/core/js/webgl.onyx /^uniformMatrix4 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat4) #foreign "gl" "uniformMatrix4" ---$/ update src/main.onyx /^update :: proc () {$/ useProgram /usr/share/onyx/core/js/webgl.onyx /^useProgram :: proc (program: GLProgram) #foreign "gl" "useProgram" ---$/ +v2_add src/vecmath.onyx /^v2_add :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/ +v2_mul src/vecmath.onyx /^v2_mul :: proc (a: V2($T), scalar: T) -> V2(T) {$/ +v2_sub src/vecmath.onyx /^v2_sub :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/ validateProgram /usr/share/onyx/core/js/webgl.onyx /^validateProgram :: proc (program: GLProgram) #foreign "gl" "validateProgram" ---$/ vertexAttrib1f /usr/share/onyx/core/js/webgl.onyx /^vertexAttrib1f :: proc (idx: GLuint, x: GLfloat) #foreign "gl" "vertexAttrib1f" ---$/ vertexAttrib2f /usr/share/onyx/core/js/webgl.onyx /^vertexAttrib2f :: proc (idx: GLuint, x: GLfloat, y: GLfloat) #foreign "gl" "vertexAttrib2f" ---$/